Added widget project nature and WRT validators
authortasneems@symbian.org
Wed, 27 Jan 2010 15:05:37 -0800
changeset 50 0560e98b9bf6
parent 43 464130c45935
child 51 a0e2f1f4e212
Added widget project nature and WRT validators
org.symbian.tools.wrttools.product/META-INF/MANIFEST.MF
org.symbian.tools.wrttools/.classpath
org.symbian.tools.wrttools/META-INF/MANIFEST.MF
org.symbian.tools.wrttools/build.properties
org.symbian.tools.wrttools/icons/Thumbs.db
org.symbian.tools.wrttools/icons/validate_widget.gif
org.symbian.tools.wrttools/lib/jtidy-8.0-20060801.131059-3.jar
org.symbian.tools.wrttools/plugin.xml
org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/Activator.java
org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/WidgetProjectNature.java
org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/core/exception/BaseException.java
org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/core/exception/CallStackParser.java
org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/core/exception/ReportException.java
org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/core/exception/ValidationException.java
org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/core/marker/MarkerUtil.java
org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/core/marker/WRTMarker.java
org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/core/packager/PackagerMessages.java
org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/core/packager/WRTPackagerConstants.java
org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/core/parser/XMLParser.java
org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/core/parser/XMLPlistParser.java
org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/core/parser/XmlElement.java
org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/core/report/IMessageListener.java
org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/core/report/Message.java
org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/core/report/MessageHandler.java
org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/core/status/IWRTConstants.java
org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/core/status/IWRTStatusListener.java
org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/core/status/Messages.java
org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/core/status/WRTStatus.java
org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/core/status/WRTStatusHandler.java
org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/core/validator/HtmlValidator.java
org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/core/validator/IValidator.java
org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/core/validator/MandatoryFilesValidator.java
org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/core/validator/Messages.java
org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/core/validator/PlistValidator.java
org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/core/validator/ValidateAction.java
org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/core/validator/ValidatorPropMessages.java
org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/core/validator/WidgetProjectValidator.java
org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/core/validator/WidgetValidator.java
org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/core/widgetmodel/WidgetModel.java
org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/core/widgetmodel/plist-1.0.dtd
org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/previewer/preview/PreviewSupport.java
org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/sdt/utils/Check.java
org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/sdt/utils/DefaultMessageListener.java
org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/sdt/utils/FileUtils.java
org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/sdt/utils/IDisposable.java
org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/sdt/utils/IMessage.java
org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/sdt/utils/IMessageListener.java
org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/sdt/utils/ITimedTask.java
org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/sdt/utils/ListenerList.java
org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/sdt/utils/Logging.java
org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/sdt/utils/Message.java
org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/sdt/utils/MessageLocation.java
org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/sdt/utils/MessageReporting.java
org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/sdt/utils/TrackedResource.java
org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/sdt/utils/UtilsPlugin.java
org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/sdt/utils/VariableSubstitutionEngine.java
org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/sdt/utils/noexport/Messages.java
org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/sdt/utils/noexport/messages.properties
org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/util/FileUtil.java
org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/util/Messages.java
org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/util/Util.java
org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/util/WRTEntityResolver.java
org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/util/messages.properties
--- a/org.symbian.tools.wrttools.product/META-INF/MANIFEST.MF	Mon Jan 25 16:30:51 2010 -0500
+++ b/org.symbian.tools.wrttools.product/META-INF/MANIFEST.MF	Wed Jan 27 15:05:37 2010 -0800
@@ -8,12 +8,12 @@
 Require-Bundle: org.eclipse.ui,
  org.eclipse.core.runtime,
  org.eclipse.wst.jsdt.ui;bundle-version="1.0.200",
- org.eclipse.search;bundle-version="3.5.1",
- org.eclipse.debug.ui;bundle-version="3.5.1",
+ org.eclipse.search;bundle-version="3.5.0",
+ org.eclipse.debug.ui;bundle-version="3.5.0",
  org.eclipse.ui.console;bundle-version="3.4.0",
  org.symbian.tools.wrttools;bundle-version="1.0.0",
- org.eclipse.wst.css.ui;bundle-version="1.0.401",
- org.eclipse.wst.html.ui;bundle-version="1.0.401",
- org.eclipse.wst.xml.ui;bundle-version="1.1.1"
+ org.eclipse.wst.css.ui;bundle-version="1.0.400",
+ org.eclipse.wst.html.ui;bundle-version="1.0.400",
+ org.eclipse.wst.xml.ui;bundle-version="1.1.0"
 Bundle-RequiredExecutionEnvironment: JavaSE-1.6
 Bundle-ActivationPolicy: lazy
--- a/org.symbian.tools.wrttools/.classpath	Mon Jan 25 16:30:51 2010 -0500
+++ b/org.symbian.tools.wrttools/.classpath	Wed Jan 27 15:05:37 2010 -0800
@@ -1,5 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <classpath>
+	<classpathentry exported="true" kind="lib" path="lib/jtidy-8.0-20060801.131059-3.jar"/>
 	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
 	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
 	<classpathentry kind="src" path="src"/>
--- a/org.symbian.tools.wrttools/META-INF/MANIFEST.MF	Mon Jan 25 16:30:51 2010 -0500
+++ b/org.symbian.tools.wrttools/META-INF/MANIFEST.MF	Wed Jan 27 15:05:37 2010 -0800
@@ -43,5 +43,6 @@
  org.eclipse.ui.internal.ide.dialogs,
  org.eclipse.ui.wizards.newresource
 Bundle-ClassPath: lib/tagsoup-1.2.jar,
- .
+ .,
+ lib/jtidy-8.0-20060801.131059-3.jar
 Export-Package: org.symbian.tools.wrttools.wizards
--- a/org.symbian.tools.wrttools/build.properties	Mon Jan 25 16:30:51 2010 -0500
+++ b/org.symbian.tools.wrttools/build.properties	Wed Jan 27 15:05:37 2010 -0800
@@ -8,4 +8,5 @@
                projecttemplates/,\
                lib/,\
                licenses/,\
-               icons/
+               icons/,\
+               lib/jtidy-8.0-20060801.131059-3.jar
Binary file org.symbian.tools.wrttools/icons/Thumbs.db has changed
Binary file org.symbian.tools.wrttools/icons/validate_widget.gif has changed
Binary file org.symbian.tools.wrttools/lib/jtidy-8.0-20060801.131059-3.jar has changed
--- a/org.symbian.tools.wrttools/plugin.xml	Mon Jan 25 16:30:51 2010 -0500
+++ b/org.symbian.tools.wrttools/plugin.xml	Wed Jan 27 15:05:37 2010 -0800
@@ -2,6 +2,7 @@
 <?eclipse version="3.4"?>
 <plugin>
 
+<!-- Generic Project Builder and Project Natures  -->		
 	<extension id="PropertiesFileAuditor" name="Properties File Auditor Project Builder"
 		point="org.eclipse.core.resources.builders">
 		<builder hasNature="true">
@@ -20,6 +21,75 @@
 		<builder id="org.symbian.tools.wrttools.PropertiesFileAuditor">
 		</builder>
 	</extension>
+ 	
+<!-- Widget Project Nature -->	
+ <extension
+       id="WidgetProjectNature"
+       point="org.eclipse.core.resources.natures">
+    <runtime>
+       <run class="org.symbian.tools.wrttools.WidgetProjectNature"/>
+    </runtime>
+ </extension> 
+ 
+<!-- Widget Project Nature Images -->
+        <extension
+              point="org.eclipse.ui.ide.projectNatureImages">
+           <image
+                 icon="icons/main16.gif"
+                 id="org.symbian.tools.wrttools.natureImage"
+                 natureId="org.symbian.tools.wrttools.WidgetProjectNature">
+           </image>
+        </extension>
+        
+<!-- WRT Validators -->		
+	<extension
+			point="org.eclipse.wst.validation.validatorV2"
+			id="org.symbian.tools.wrttools.core.validator"
+			name="%VALIDATOR.Name">
+		<validator class="org.symbian.tools.wrttools.core.validator.ValidateAction">
+         	<include>
+         	     <rules>
+		               <fileext ext="xml"/>
+		               <fileext ext="html"/>
+		               <fileext ext="js"/>
+		               <fileext ext="css"/>
+		               <fileext ext="plist"/>
+		         </rules>
+            </include>
+		</validator>
+    </extension> 
+    
+<!-- Validation markers -->
+   
+        <extension
+           id="org.symbian.tools.wrttools.core.validator.marker"
+           name="Validator Marker"
+           point="org.eclipse.core.resources.markers">
+                 <super type="org.eclipse.core.resources.problemmarker"/>
+                 <persistent value ="true"/>
+        </extension>
+
+        <extension	
+          point="org.eclipse.ui.popupMenus">
+	      <objectContribution
+			 adaptable="true"
+			 id="com.nokia.wrt.core.validator"
+             objectClass="org.eclipse.core.resources.IResource">
+           <filter
+         	name="projectNature"
+         	value="org.symbian.tools.wrttools.WidgetProjectNature"/>
+           <action
+                 class="com.nokia.wrt.core.validator.ValidateAction"
+                 enablesFor="+"
+                 icon="icons/validate_widget.gif"
+                 id="com.nokia.wrt.core.validator.ValidateAction"
+                 label="Validate Widget"
+                 menubarPath="com.nokia.wrt.contextMenuGroupMarker">
+			</action>
+		   </objectContribution> 
+        </extension>  
+
+<!-- WRT Project Templates - CSS Validator -->
 	<extension-point id="projectTemplates" name="WRT application project templates" schema="schema/projectTemplates.exsd"/>
 	<extension id="org.symbian.tools.wrttools.core.cssvalidator"
 		name="CSS Validator" point="org.eclipse.wst.validation.validatorV2">
@@ -36,6 +106,8 @@
 			</include>
 		</validator>
 	</extension>
+	 
+<!-- WRT WidgetWizard and AptanaProjectImportWizard -->
 	<extension point="org.eclipse.ui.newWizards">
 		<category id="org.symbian.tools.wrttools.core.category" name="Web Runtime(WRT)">
 		</category>
@@ -58,6 +130,8 @@
 			project="true">
 		</wizard>
 	</extension>
+	
+<!-- WRT Project Templates -->
 	<extension point="org.symbian.tools.wrttools.projectTemplates">
 		<projectTemplate
 		name="Basic Widget Project"
@@ -72,6 +146,8 @@
          </description>
 		</projectTemplate>
 	</extension>
+	
+<!-- Import Wizard -->
 	<extension point="org.eclipse.ui.importWizards">
 		<category id="org.symbian.tools.wrttools.import" name="Web Runtime(WRT)">
 		</category>
@@ -81,6 +157,8 @@
 			name="Aptana IDE WRT Project">
 		</wizard>
 	</extension>
+	
+<!-- Problem Markers -->
 	<extension id="org.symbian.tools.wrt.xmlProblem" name="XML Problem"
 		point="org.eclipse.core.resources.markers">
 		<super type="org.eclipse.core.resources.problemmarker">
@@ -95,12 +173,16 @@
 		<persistent value="true">
 		</persistent>
 	</extension>
+	
+<!-- WRT Content Descriptor (.plist) file -->
 	<extension point="org.eclipse.core.contenttype.contentTypes">
 		<content-type base-type="org.eclipse.core.runtime.xml"
 			file-extensions="plist" id="org.symbian.tools.wrttools.contenttype.plist"
 			name="WebRuntime Descriptor File" priority="normal">
 		</content-type>
 	</extension>
+	
+<!-- Perspective Extensions -->
 	<extension point="org.eclipse.ui.perspectiveExtensions">
 		<perspectiveExtension targetID="org.eclipse.wst.jsdt.ui.JavaPerspective">
 			<newWizardShortcut id="org.symbian.tools.wrttools.core.wrtwidgetwizard">
@@ -111,6 +193,8 @@
 			</newWizardShortcut>
 		</perspectiveExtension>
 	</extension>
+	
+<!-- Navigator Extensions -->
 	<extension point="org.eclipse.ui.views">
 		<view allowMultiple="false" category="org.symbian.tools.wrttools.views"
 			class="org.eclipse.ui.navigator.CommonNavigator" icon="icons/main16.gif"
@@ -179,7 +263,7 @@
                       type="org.eclipse.core.resources.IProject">
                    <test
                          property="org.eclipse.core.resources.projectNature"
-                         value="org.eclipse.wst.jsdt.core.jsNature">
+                         value="org.symbian.tools.wrttools.WidgetProjectNature">
                    </test>
                 </adapt>
              </and>
@@ -242,7 +326,7 @@
                    </instanceof>
                    <test
                          property="org.eclipse.core.resources.projectNature"
-                         value="org.eclipse.wst.jsdt.core.jsNature">
+                         value="org.symbian.tools.wrttools.WidgetProjectNature">
                    </test>
                 </and>
                 <instanceof
@@ -275,7 +359,7 @@
                    </instanceof>
                    <test
                          property="org.eclipse.core.resources.projectNature"
-                         value="org.eclipse.wst.jsdt.core.jsNature">
+                         value="org.symbian.tools.wrttools.WidgetProjectNature">
                    </test>
                 </and>
                 <instanceof
--- a/org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/Activator.java	Mon Jan 25 16:30:51 2010 -0500
+++ b/org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/Activator.java	Wed Jan 27 15:05:37 2010 -0800
@@ -22,6 +22,7 @@
 import org.eclipse.core.runtime.Status;
 import org.eclipse.ui.plugin.AbstractUIPlugin;
 import org.osgi.framework.BundleContext;
+import org.symbian.tools.wrttools.sdt.utils.Logging;
 
 /**
  * The activator class controls the plug-in life cycle
@@ -74,5 +75,10 @@
 	public static void log(String message, Exception e) {
 		getDefault().getLog().log(new Status(IStatus.ERROR, PLUGIN_ID, message, e));
 	}
+	
+	public static void log(int severity, String message, Throwable x) {
+		IStatus status = new Status(severity, PLUGIN_ID, 0, message, x);
+		Logging.log(getDefault(), status);
+	}
 
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/WidgetProjectNature.java	Wed Jan 27 15:05:37 2010 -0800
@@ -0,0 +1,76 @@
+/**
+ * Copyright (c) 2009 Symbian Foundation and/or its subsidiary(-ies).
+ * All rights reserved.
+ * This component and the accompanying materials are made available
+ * under the terms of the License "Eclipse Public License v1.0"
+ * which accompanies this distribution, and is available
+ * at the URL "http://www.eclipse.org/legal/epl-v10.html".
+ *
+ * Initial Contributors:
+ * Symbian Foundation - initial contribution.
+ * Contributors:
+ * Description:
+ * Overview:
+ * Details:
+ * Platforms/Drives/Compatibility:
+ * Assumptions/Requirement/Pre-requisites:
+ * Failures and causes:
+ */
+
+package org.symbian.tools.wrttools;
+
+import org.eclipse.core.resources.ICommand;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IProjectDescription;
+import org.eclipse.core.resources.IProjectNature;
+import org.eclipse.core.runtime.CoreException;
+
+import org.symbian.tools.wrttools.core.validator.WidgetProjectValidator;
+
+public class WidgetProjectNature implements IProjectNature {
+	
+	private IProject project;
+
+	public void configure() throws CoreException {
+		IProjectDescription desc = project.getDescription();
+		ICommand[] commands = desc.getBuildSpec();
+
+		for (int i = 0; i < commands.length; ++i) {
+			if (commands[i].getBuilderName().equals(WidgetProjectValidator.BUILDER_ID)) {
+				return;
+			}
+		}
+
+		ICommand[] newCommands = new ICommand[commands.length + 1];
+		System.arraycopy(commands, 0, newCommands, 0, commands.length);
+		ICommand command = desc.newCommand();
+		command.setBuilderName(WidgetProjectValidator.BUILDER_ID);
+		newCommands[newCommands.length - 1] = command;
+		desc.setBuildSpec(newCommands);
+		project.setDescription(desc, null);
+	}
+
+	public void deconfigure() throws CoreException {
+		IProjectDescription description = getProject().getDescription();
+		ICommand[] commands = description.getBuildSpec();
+		for (int i = 0; i < commands.length; ++i) {
+			if (commands[i].getBuilderName().equals(WidgetProjectValidator.BUILDER_ID)) {
+				ICommand[] newCommands = new ICommand[commands.length - 1];
+				System.arraycopy(commands, 0, newCommands, 0, i);
+				System.arraycopy(commands, i + 1, newCommands, i,
+						commands.length - i - 1);
+				description.setBuildSpec(newCommands);
+				return;
+			}
+		}
+	}
+
+	public IProject getProject() {
+		return project;
+	}
+
+	public void setProject(IProject project) {
+		this.project = project;
+	}
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/core/exception/BaseException.java	Wed Jan 27 15:05:37 2010 -0800
@@ -0,0 +1,180 @@
+/**
+ * Copyright (c) 2009 Symbian Foundation and/or its subsidiary(-ies).
+ * All rights reserved.
+ * This component and the accompanying materials are made available
+ * under the terms of the License "Eclipse Public License v1.0"
+ * which accompanies this distribution, and is available
+ * at the URL "http://www.eclipse.org/legal/epl-v10.html".
+ *
+ * Initial Contributors:
+ * Symbian Foundation - initial contribution.
+ * Contributors:
+ * Description:
+ * Overview:
+ * Details:
+ * Platforms/Drives/Compatibility:
+ * Assumptions/Requirement/Pre-requisites:
+ * Failures and causes:
+ */
+
+
+package org.symbian.tools.wrttools.core.exception;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+
+public class BaseException extends Exception {
+
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 2256229917601216943L;
+	
+	private Throwable m_nestedException;
+    private String m_exceptionId;
+
+    /**
+     * Private initialization method.
+     */
+    private void init()
+    {
+        this.m_exceptionId = this.getExceptionId();
+    }
+
+    /**
+     * Default constructor.
+     */
+    public BaseException()
+    {
+        this.init();
+    }
+
+    /**
+     * Contructor that takes a message and a <code>Throwable</code> for nesting.
+     * @param pMessage <code>String</code> message for the exception.
+     * @param pNestedException <code>Throwable</code> object to nest.
+     */
+    public BaseException( String pMessage, Throwable pNestedException )
+    {
+        super( pMessage );
+
+        this.init();
+
+        this.m_nestedException = pNestedException;
+    }
+
+    /**
+     * Contructor that takes a <code>Throwable</code> for nesting.
+     * @param pNestedException <code>Throwable</code> object to nest.
+     */
+    public BaseException( Throwable pNestedException )
+    {
+        this.init();
+
+        this.m_nestedException = pNestedException;
+    }
+
+    /**
+     * Contructor that takes a message.
+     * @param pMessage <code>String</code> message for the exception.
+     */
+    public BaseException( String pMessage )
+    {
+        super( pMessage );
+
+        this.init();
+    }
+
+    /**
+     * Method to extract the class name, method name & line number from the
+     * call stack.
+     * @return The exception Id.
+     */
+    private String getExceptionId()
+    {
+        return CallStackParser.parse( this.getExpStackTrace() );
+    }
+
+    /**
+     * Internal helper method to serialize the stack to a
+     * <code>String</code>.
+     * @return <code>String</code> holding the serialized stack.
+     */
+    private String getExpStackTrace()
+    {
+        ByteArrayOutputStream stream = new ByteArrayOutputStream();
+        PrintStream ps = new PrintStream( stream );
+        super.printStackTrace( ps );
+        return stream.toString();
+    }
+
+    /**
+     * Serializes the exception to a <code>String</code>.
+     * @return String
+     */
+    public String toString()
+    {
+        StringBuffer retval = new StringBuffer( this.getClass().getName() );
+
+        if( this.m_exceptionId != null ) {
+            retval.append( "\r\nId: " );
+            retval.append( this.m_exceptionId );
+            retval.append( "\r\n" );
+        }
+
+        retval.append( "Message: " );
+        retval.append( super.getMessage() );
+
+        if( this.m_nestedException != null ) {
+            retval.append( "\r\nNested Exception: " );
+            retval.append( this.m_nestedException.toString() );
+        }
+
+        return retval.toString();
+    }
+
+    /**
+     * Prints this <code>BaseException</code> and its backtrace and any nested
+     * <code>Thowable</code>to the standard error stream.
+     */
+    public void printStackTrace()
+    {
+        super.printStackTrace();
+
+        if( this.m_nestedException != null ) {
+//            System.err.println( "Nested Exception--------------------------------" );
+            this.m_nestedException.printStackTrace();
+        }
+    }
+
+    /**
+     * Prints this <code>BaseException</code> and its backtrace and any nested
+     * <code>Thowable</code> to the specified <code>PrintStream</code>.
+     * @param pStream <code>PrintStream</code> to write to.
+     */
+    public void printStackTrace( PrintStream pStream )
+    {
+        super.printStackTrace( pStream );
+
+        if( this.m_nestedException != null ) {
+            pStream.println( "Nested Exception--------------------------------" );
+            this.m_nestedException.printStackTrace( pStream );
+        }
+    }
+
+    /**
+     * Prints this <code>BaseException</code> and its backtrace and any nested
+     * <code>Thowable</code> to the specified <code>PrintWriter</code>.
+     * @param pWriter <code>PrintWriter</code> to write to.
+     */
+    public void printStackTrace( PrintWriter pWriter )
+    {
+        super.printStackTrace( pWriter );
+
+        if( this.m_nestedException != null ) {
+            pWriter.println( "Nested Exception--------------------------------" );
+            this.m_nestedException.printStackTrace( pWriter );
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/core/exception/CallStackParser.java	Wed Jan 27 15:05:37 2010 -0800
@@ -0,0 +1,79 @@
+/**
+ * Copyright (c) 2009 Symbian Foundation and/or its subsidiary(-ies).
+ * All rights reserved.
+ * This component and the accompanying materials are made available
+ * under the terms of the License "Eclipse Public License v1.0"
+ * which accompanies this distribution, and is available
+ * at the URL "http://www.eclipse.org/legal/epl-v10.html".
+ *
+ * Initial Contributors:
+ * Symbian Foundation - initial contribution.
+ * Contributors:
+ * Description:
+ * Overview:
+ * Details:
+ * Platforms/Drives/Compatibility:
+ * Assumptions/Requirement/Pre-requisites:
+ * Failures and causes:
+ */
+
+package org.symbian.tools.wrttools.core.exception;
+
+import java.util.StringTokenizer;
+
+public class CallStackParser {
+    /**
+     * Method to extract the class name, method name & line number from
+     * the call stack.
+     * @param pCallStack The call strack string
+     * @return The exception Id.
+     */
+    protected static String parse( String pCallStack )
+    {
+        try {
+            if( pCallStack == null )
+                return "CallStackParser: Unknown Call Stack";
+
+            String lineNumber = "";
+            String text       = pCallStack;
+
+            StringTokenizer st = new StringTokenizer( text, "\r\n" );
+            // we want the second line for the classname and calling method
+            // so throw away the first element
+            st.nextElement();
+            // and save the second
+            text = ( String )st.nextElement();
+
+            // find the line number
+            int ix = text.lastIndexOf( ":" );
+            if( ix != -1 ) {
+                lineNumber = text.substring( ix + 1, text.length() - 1 );
+            }
+
+            // strip everything after the first found '('
+            ix = text.indexOf( "(" );
+            if( ix != -1 ) {
+                text = text.substring( 0, ix );
+            }
+
+            // strip everything before the class name
+            ix = text.indexOf( " " );
+            if( ix != -1 ) {
+                text = text.substring( ix + 1 );
+            }
+
+            // if we have a line number, append it
+            if( lineNumber.length() > 0 ) {
+                StringBuffer output = new StringBuffer( text );
+                output.append( ":" );
+                output.append( lineNumber );
+                return output.toString();
+            }
+
+            return text;
+        }
+        catch( Exception e ) {
+            return "<Unknown Exception Id>";
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/core/exception/ReportException.java	Wed Jan 27 15:05:37 2010 -0800
@@ -0,0 +1,52 @@
+/**
+ * Copyright (c) 2009 Symbian Foundation and/or its subsidiary(-ies).
+ * All rights reserved.
+ * This component and the accompanying materials are made available
+ * under the terms of the License "Eclipse Public License v1.0"
+ * which accompanies this distribution, and is available
+ * at the URL "http://www.eclipse.org/legal/epl-v10.html".
+ *
+ * Initial Contributors:
+ * Symbian Foundation - initial contribution.
+ * Contributors:
+ * Description:
+ * Overview:
+ * Details:
+ * Platforms/Drives/Compatibility:
+ * Assumptions/Requirement/Pre-requisites:
+ * Failures and causes:
+ */
+
+package org.symbian.tools.wrttools.core.exception;
+
+public class ReportException extends BaseException {
+	/**
+	 *  @author Sailaja Duvvuri
+	 */
+	private static final long serialVersionUID = -1598160901494205202L;
+
+	/**
+	 * Contructor that takes a <code>Throwable</code> for nesting.
+	 * @param pNestedException <code>Throwable</code> object to nest.
+	 */
+	public ReportException(Throwable pNestedException) {
+		super(pNestedException);
+	}
+
+	/**
+	 *
+	 * @param pMessage
+	 * @param pNestedException
+	 */
+	public ReportException(String pMessage, Throwable pNestedException) {
+		super(pMessage, pNestedException);
+	}
+
+	/**
+	 *
+	 * @param pMessage
+	 */
+	public ReportException(String pMessage) {
+		super(pMessage);
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/core/exception/ValidationException.java	Wed Jan 27 15:05:37 2010 -0800
@@ -0,0 +1,52 @@
+/**
+ * Copyright (c) 2009 Symbian Foundation and/or its subsidiary(-ies).
+ * All rights reserved.
+ * This component and the accompanying materials are made available
+ * under the terms of the License "Eclipse Public License v1.0"
+ * which accompanies this distribution, and is available
+ * at the URL "http://www.eclipse.org/legal/epl-v10.html".
+ *
+ * Initial Contributors:
+ * Symbian Foundation - initial contribution.
+ * Contributors:
+ * Description:
+ * Overview:
+ * Details:
+ * Platforms/Drives/Compatibility:
+ * Assumptions/Requirement/Pre-requisites:
+ * Failures and causes:
+ */
+
+package org.symbian.tools.wrttools.core.exception;
+
+public class ValidationException extends BaseException {
+	/**
+	 *  @author Sailaja Duvvuri
+	 */
+	private static final long serialVersionUID = -1598160901494205202L;
+
+	/**
+	 * Contructor that takes a <code>Throwable</code> for nesting.
+	 * @param pNestedException <code>Throwable</code> object to nest.
+	 */
+	public ValidationException(Throwable pNestedException) {
+		super(pNestedException);
+	}
+
+	/**
+	 *
+	 * @param pMessage
+	 * @param pNestedException
+	 */
+	public ValidationException(String pMessage, Throwable pNestedException) {
+		super(pMessage, pNestedException);
+	}
+
+	/**
+	 *
+	 * @param pMessage
+	 */
+	public ValidationException(String pMessage) {
+		super(pMessage);
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/core/marker/MarkerUtil.java	Wed Jan 27 15:05:37 2010 -0800
@@ -0,0 +1,168 @@
+/**
+ * Copyright (c) 2009 Symbian Foundation and/or its subsidiary(-ies).
+ * All rights reserved.
+ * This component and the accompanying materials are made available
+ * under the terms of the License "Eclipse Public License v1.0"
+ * which accompanies this distribution, and is available
+ * at the URL "http://www.eclipse.org/legal/epl-v10.html".
+ *
+ * Initial Contributors:
+ * Symbian Foundation - initial contribution.
+ * Contributors:
+ * Description:
+ * Overview:
+ * Details:
+ * Platforms/Drives/Compatibility:
+ * Assumptions/Requirement/Pre-requisites:
+ * Failures and causes:
+ */
+package org.symbian.tools.wrttools.core.marker;
+
+import java.util.List;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Path;
+
+import org.symbian.tools.wrttools.Activator;
+import org.symbian.tools.wrttools.core.report.Message;
+import org.symbian.tools.wrttools.core.status.IWRTConstants;
+
+/**
+ * A class to handle CodeScanner commandline tool execution, error processing
+ * and generating CodeScanner specific markers.
+ * 
+ */
+public class MarkerUtil   {
+
+	public MarkerUtil() {
+	}
+
+	/**
+	 * Map an IMarkerGenerator severity to an IMarker severity
+	 * @param severity - an IMarkerGenerator severity
+	 * @return an IMarker severity
+	 */
+	protected static int mapWRTMarkerSeverity(String severity) {
+		if (IWRTConstants.INFO.equals(severity))
+			return IMarker.SEVERITY_INFO;
+		if (IWRTConstants.WARN.equals(severity))
+			return IMarker.SEVERITY_WARNING;
+		if (IWRTConstants.ERROR.equals(severity))
+			return IMarker.SEVERITY_ERROR;
+		if (IWRTConstants.FATAL.equals(severity))
+			return IMarker.SEVERITY_ERROR;
+		return IMarker.PRIORITY_LOW;
+	}
+	
+
+	public static void addMarker(Message msg, IProject project) {
+		try {
+			if (project != null) {
+
+				IResource markerResource = project;
+				IMarker marker = null;
+				if (markerResource != null) {
+					// IMarker[] cur =
+					
+					// markerResource.findMarkers(CSMarker.CS_PROBLEM_MARKER,
+					// false, IResource.DEPTH_ONE);
+					IMarker[] markerList = null;
+					int depth = IResource.DEPTH_INFINITE;
+//					IPath filePath = new Path(msg.getTargetObject());
+//					IFile fileProblem = project.getFile(filePath);
+					if(msg.getTargetObject()!=null)
+					{
+						IPath filePath = new Path(msg.getTargetObject());
+						IFile fileProblem = project.getFile(filePath);
+					
+					///----------------if error is associated with file create marker with file or else part
+					if (fileProblem.exists()) {
+						markerList = fileProblem.findMarkers(null, true, depth);
+						marker = fileProblem.createMarker(IMarker.PROBLEM);
+					} else {
+						// if error is not associated with any file create marker with the project.
+						markerList = project.findMarkers(null, true, depth);
+						marker = project.createMarker(IMarker.PROBLEM);
+					}
+					
+				}else{
+					// if error is not associated with any file create marker with the project.
+					markerList = project.findMarkers(null, true, depth);
+					marker = project.createMarker(IMarker.PROBLEM);
+					
+				}	
+					// try to find matching markers and don't put in duplicates
+					
+					if ((markerList != null) && (markerList.length > 0)) {
+						for (int i = 0; i < markerList.length; i++) {
+							int line = markerList[i].getAttribute(IMarker.LINE_NUMBER,-1);
+							// int sev = ((Integer)
+							// cur[i].getAttribute(IMarker.SEVERITY)).intValue();
+							int sev = new Integer(markerList[i].getAttribute(IMarker.SEVERITY).toString());
+							String mesg = (String) markerList[i].getAttribute(IMarker.MESSAGE);
+							String message = msg.getMessage();
+							//If the marker is previously created then return.
+							if (line == msg.getLineNumber()	&& sev == mapWRTMarkerSeverity(msg.getSeverity())&& mesg.equals(message)) {
+								return;
+							}
+						}
+					}
+				} 
+
+//				if (markerResource != null) {
+					// create the marker and set its attributes
+					// IMarker marker =
+					// project.createMarker(WRTMarker.WRT_PROBLEM_MARKER);
+
+					if (marker != null) {
+						String message = msg.getMessage();
+						marker.setAttribute(IMarker.MESSAGE, message);
+						marker.setAttribute(IMarker.SEVERITY, mapWRTMarkerSeverity(msg.getSeverity()));
+						marker.setAttribute(IMarker.LINE_NUMBER, msg.getLineNumber());
+					} 
+//				}
+
+			}
+		} 
+		catch (CoreException e) {
+			Activator.log(IStatus.ERROR,	"Add Marker Exception ", e);
+		}
+	}
+	
+
+	public  static void deleteMarker(IProject project) {
+		try {
+			if (project != null) {
+					project.deleteMarkers(IMarker.PROBLEM, true, IResource.DEPTH_INFINITE);
+			}
+			
+		}
+		catch (CoreException e) {
+			Activator.log(IStatus.ERROR,	"Delete Marker Exception ", e);
+		}
+	}
+	
+	
+	/**
+	 * 
+	 * @param iMarkerList
+	 */
+	
+	public   void deleteMarker(List<IMarker> iMarkerList) {
+		try {			
+			for (IMarker mark : iMarkerList) {
+			mark.delete();
+			}			
+		}
+		catch (CoreException e) {
+			Activator.log(IStatus.ERROR,	"Delete All Markers Exception ", e);
+		}
+	}
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/core/marker/WRTMarker.java	Wed Jan 27 15:05:37 2010 -0800
@@ -0,0 +1,88 @@
+/**
+ * Copyright (c) 2009 Symbian Foundation and/or its subsidiary(-ies).
+ * All rights reserved.
+ * This component and the accompanying materials are made available
+ * under the terms of the License "Eclipse Public License v1.0"
+ * which accompanies this distribution, and is available
+ * at the URL "http://www.eclipse.org/legal/epl-v10.html".
+ *
+ * Initial Contributors:
+ * Symbian Foundation - initial contribution.
+ * Contributors:
+ * Description:
+ * Overview:
+ * Details:
+ * Platforms/Drives/Compatibility:
+ * Assumptions/Requirement/Pre-requisites:
+ * Failures and causes:
+ */
+
+package org.symbian.tools.wrttools.core.marker;
+
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+
+import org.symbian.tools.wrttools.Activator;
+
+
+/**
+ * A class to handle markers.
+ */
+public class WRTMarker {
+
+	/**
+	 * WRTValidator problem marker type. This can be used to recognize those markers
+	 * in the workspace that flag problems detected by the CodeScanner plugin.
+	 */
+	public static final String WRT_PROBLEM_MARKER = Activator.PLUGIN_ID + ".com.nokia.wrt.core.validator.marker"; //$NON-NLS-1$
+	
+//	public static final String WRT_PROBLEM_MARKER = Activator.PLUGIN_ID + ".WRTMarker"; //$NON-NLS-1$
+	
+	/**
+	 * WRTValidator extension to the marker problem markers which may hold a hint on
+	 * the variable name that caused the error. Used by the ui to highlight the variable
+	 * itself if it can be found.
+	 */
+	public static final String WRT_MARKER_VARIABLE = "problem.variable"; //$NON-NLS-1$
+	
+	public static final String WRT_MARKER_FILE_NAME = "problem.file.name"; //$NON-NLS-1$
+	
+	public static final String WRT_MARKER_FILE_FULL_PATH = "problem.file.full.path"; //$NON-NLS-1$
+	
+	/**
+	 * WRTValidator extension to the marker problem markers which may hold 
+	 * the path to the workspace external location of the file containing the problem 
+	 */
+	public static final String WRT_MARKER_EXTERNAL_LOCATION = "problem.externalLocation"; //$NON-NLS-1$
+
+	/**
+	 * WRTValidator extension to the marker problem markers which may hold 
+	 * the name of the WRTValidator rule applicable to the problem 
+	 */
+	public static final String WRT_MARKER_RULE_NAME = "problem.ruleName"; //$NON-NLS-1$
+
+	/**
+	 * Remove all validate markers from a project.
+	 * @param currProject - Project containing WRTValidator markers.
+	 */
+	 public static void removeAllMarkers(IProject currProject) {
+		try {
+			IWorkspace workspace = currProject.getWorkspace();
+
+			// remove all WRTValidator markers
+			IMarker[] markers = currProject.findMarkers(WRTMarker.WRT_PROBLEM_MARKER, true, IResource.DEPTH_INFINITE);
+			if ((markers != null) && (markers.length > 0)) {
+				workspace.deleteMarkers(markers);
+			}		
+		} catch (CoreException e){
+			Activator.log(IStatus.ERROR,	"Marker Exception ", e);
+        }
+	 }
+
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/core/packager/PackagerMessages.java	Wed Jan 27 15:05:37 2010 -0800
@@ -0,0 +1,40 @@
+/**
+ * Copyright (c) 2009 Symbian Foundation and/or its subsidiary(-ies).
+ * All rights reserved.
+ * This component and the accompanying materials are made available
+ * under the terms of the License "Eclipse Public License v1.0"
+ * which accompanies this distribution, and is available
+ * at the URL "http://www.eclipse.org/legal/epl-v10.html".
+ *
+ * Initial Contributors:
+ * Symbian Foundation - initial contribution.
+ * Contributors:
+ * Description:
+ * Overview:
+ * Details:
+ * Platforms/Drives/Compatibility:
+ * Assumptions/Requirement/Pre-requisites:
+ * Failures and causes:
+ */
+package org.symbian.tools.wrttools.core.packager;
+
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+public class PackagerMessages {
+	private static final String BUNDLE_NAME = "com.nokia.wrt.core.packager.packageMessages"; //$NON-NLS-1$
+
+	private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle
+			.getBundle(BUNDLE_NAME);
+
+	private PackagerMessages() {
+	}
+
+	public static String getString(String key) {
+		try {
+			return RESOURCE_BUNDLE.getString(key);
+		} catch (MissingResourceException e) {
+			return '!' + key + '!';
+		}
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/core/packager/WRTPackagerConstants.java	Wed Jan 27 15:05:37 2010 -0800
@@ -0,0 +1,66 @@
+/**
+ * Copyright (c) 2009 Symbian Foundation and/or its subsidiary(-ies).
+ * All rights reserved.
+ * This component and the accompanying materials are made available
+ * under the terms of the License "Eclipse Public License v1.0"
+ * which accompanies this distribution, and is available
+ * at the URL "http://www.eclipse.org/legal/epl-v10.html".
+ *
+ * Initial Contributors:
+ * Symbian Foundation - initial contribution.
+ * Contributors:
+ * Description:
+ * Overview:
+ * Details:
+ * Platforms/Drives/Compatibility:
+ * Assumptions/Requirement/Pre-requisites:
+ * Failures and causes:
+ */
+
+package org.symbian.tools.wrttools.core.packager;
+
+import org.eclipse.core.runtime.QualifiedName;
+
+public class WRTPackagerConstants {
+	
+	public static QualifiedName EXCLUDE_PROPERTY = new QualifiedName("com.nokia.wrt.packager", "exclude");
+	
+
+	public static String STA_PKG_PASSED = PackagerMessages.getString("WRTPackagerConstants.success"); //$NON-NLS-1$
+	public static String STA_PKG_FAILED = PackagerMessages.getString("WRTPackagerConstants.failed"); //$NON-NLS-1$
+
+	public static String ERR_PKG_MAN_PLIST_FILE_MISSING = PackagerMessages.getString("WRTPackagerConstants.package.missing.mandatory.files.plist"); //$NON-NLS-1$
+	public static String ERR_PKG_MAN_HTML_FILE_MISSING = PackagerMessages.getString("WRTPackagerConstants.package.missing.mandatory.files.html"); //$NON-NLS-1$
+
+	
+	
+	public static String STA_PKG_PROGRESS = PackagerMessages.getString("WRTPackagerConstants.inProgress"); //$NON-NLS-1$
+	public static String STA_PKG_START = PackagerMessages.getString("WRTPackagerConstants.started"); //$NON-NLS-1$
+	
+	public static String LOG_NULL_INPUT= PackagerMessages.getString("WRTPackagerConstants.nullpera"); //$NON-NLS-1$
+	public static String ERR_NULL= PackagerMessages.getString("WRTPackagerConstants.nullInput"); //$NON-NLS-1$
+	public static String LOG_DIR_CREATE_FAIL= PackagerMessages.getString("WRTPackagerConstants.directoryCreateErr"); //$NON-NLS-1$
+	public static String ERR_DIR_CREATE_FAIL= PackagerMessages.getString("WRTPackagerConstants.checkPermission"); //$NON-NLS-1$
+	public static String LOG_UNSUPPORTED_INPUT= PackagerMessages.getString("WRTPackagerConstants.unSupportedInput"); //$NON-NLS-1$
+	public static String ERR_UNSUPPORTED_INPUT= PackagerMessages.getString("WRTPackagerConstants.InputNotSupported"); //$NON-NLS-1$
+	public static String LOG_RENAME_FAIL= PackagerMessages.getString("WRTPackagerConstants.renameFailed"); //$NON-NLS-1$
+	public static String ERR_RENAME_FAIL= PackagerMessages.getString("WRTPackagerConstants.failureGenerate"); //$NON-NLS-1$
+	public static String LOG_SOURCE_NOT_FOUND= PackagerMessages.getString("WRTPackagerConstants.srcNotFound"); //$NON-NLS-1$
+	public static String ERR_SOURCE_NOT_FOUND= PackagerMessages.getString("WRTPackagerConstants.inputSourceNotFound"); //$NON-NLS-1$
+	public static String LOG_UNREADABLE= PackagerMessages.getString("WRTPackagerConstants.srcNotReadable"); //$NON-NLS-1$
+	public static String ERR_UNREADABLE= PackagerMessages.getString("WRTPackagerConstants.unReadable"); //$NON-NLS-1$
+	public static String LOG_FILE_COPY_FAIL= PackagerMessages.getString("WRTPackagerConstants.canNotcopy"); //$NON-NLS-1$
+	public static String ERR_FILE_COPY_FAIL= PackagerMessages.getString("WRTPackagerConstants.copyErr"); //$NON-NLS-1$
+	public static String LOG_DEST_NOT_FOUND= PackagerMessages.getString("WRTPackagerConstants.NoDestination"); //$NON-NLS-1$
+	public static String ERR_DEST_NOT_FOUND= PackagerMessages.getString("WRTPackagerConstants.noLocateDest"); //$NON-NLS-1$
+	public static String LOG_NOT_WRITABLE= PackagerMessages.getString("WRTPackagerConstants.destNotWritable"); //$NON-NLS-1$
+	public static String ERR_NOT_WRITABLE= PackagerMessages.getString("WRTPackagerConstants.destNotwritableErr"); //$NON-NLS-1$
+	public static String LOG_READ_WRITE_FAIL= PackagerMessages.getString("WRTPackagerConstants.readWriteFail"); //$NON-NLS-1$
+	public static String ERR_READ_WRITE_FAIL= PackagerMessages.getString("WRTPackagerConstants.readWritePermission"); //$NON-NLS-1$
+	public static String LOG_FILE_CLOSE_FAIL= PackagerMessages.getString("WRTPackagerConstants.closeFile"); //$NON-NLS-1$
+	public static String ERR_FILE_CLOSE_FAIL= PackagerMessages.getString("WRTPackagerConstants.closeFileerr"); //$NON-NLS-1$
+	public static String LOG_ZIP_FAILED= PackagerMessages.getString("WRTPackagerConstants.ZipFailed"); //$NON-NLS-1$
+	public static String ERR_ZIP_FAILED= PackagerMessages.getString("WRTPackagerConstants.packFailed"); //$NON-NLS-1$
+	public static String LOG_EMPTY_SRC= PackagerMessages.getString("WRTPackagerConstants.emptyInputFolder"); //$NON-NLS-1$
+	public static String ERR_EMPTY_SRC= PackagerMessages.getString("WRTPackagerConstants.emptyFolderErr"); //$NON-NLS-1$
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/core/parser/XMLParser.java	Wed Jan 27 15:05:37 2010 -0800
@@ -0,0 +1,1186 @@
+/**
+ * Copyright (c) 2009 Symbian Foundation and/or its subsidiary(-ies).
+ * All rights reserved.
+ * This component and the accompanying materials are made available
+ * under the terms of the License "Eclipse Public License v1.0"
+ * which accompanies this distribution, and is available
+ * at the URL "http://www.eclipse.org/legal/epl-v10.html".
+ *
+ * Initial Contributors:
+ * Symbian Foundation - initial contribution.
+ * Contributors:
+ * Description:
+ * Overview:
+ * Details:
+ * Platforms/Drives/Compatibility:
+ * Assumptions/Requirement/Pre-requisites:
+ * Failures and causes:
+ */
+
+package org.symbian.tools.wrttools.core.parser;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Stack;
+import java.util.logging.Logger;
+
+import org.symbian.tools.wrttools.core.parser.XmlElement.Attribute;
+import org.symbian.tools.wrttools.core.report.IMessageListener;
+import org.symbian.tools.wrttools.core.report.Message;
+import org.symbian.tools.wrttools.core.status.IWRTConstants;
+import org.symbian.tools.wrttools.core.validator.ValidatorPropMessages;
+
+public class XMLParser {
+	private Logger log = Logger.getLogger(getClass().getName());
+	protected static Stack<XmlElement> xmlStackElements = new Stack<XmlElement>();
+
+	protected int lineNumber = 1;
+
+	protected final int typeElmBegin = 3;
+	protected final int typeElmValue = 7;
+	protected final int typeElmEnd = 8;
+	protected final int typeEmptyElm = 9;
+	protected final int typeErrorElement = 10;
+
+	protected final char beginElement = '<';
+	protected final char endElement = '>';
+	protected final String endEmptyElement = "/>";
+	protected final String beginEndElement = "</";
+	protected final String beginCommentElement = "<!--";
+	protected final String endCommentElement = "-->";
+	protected final String javaScriptCommentElement = "//";
+
+	// <!--View Selector Tab-->
+
+	protected int beginElementCount;
+	protected int endElementCount;
+	protected int endEmptyElementCount;
+	protected int beginEndElementCount;
+
+	protected int beginCommentElementCount;
+	protected int endCommentElementCount;
+	protected int javaScriptCommentElementCount;
+
+	protected int posBeginElement = 0;
+	protected int posEndElement = 0;
+	protected int posEndEmptyElement = 0;
+	protected int posBeginEndElement = 0;
+
+	protected int posBeginCommentElement = 0;
+	protected int posEndCommentElement = 0;
+	protected int posJavaScriptCommentElement = 0;
+
+	boolean docTypeSet = false;
+	boolean xmlDeclarationSet = false;
+	boolean rootElmStartSet = false;
+	protected BufferedReader inputStream = null;
+	protected String line;
+	protected HashMap countMap;
+	protected boolean error;
+	protected int elmType = 0;
+	protected int lastElmType = 0;
+	protected XmlElement rootXml;
+	protected String targetFileName;
+	protected boolean enableValidation = false;
+	protected boolean endDoc = false;
+
+	public XmlElement parseXML(File fileName) throws IOException {
+		log.finest("parseXML  >>--->>");
+		lineNumber = 0;
+		targetFileName = fileName.getName();
+		showData("Starting parse#########------- fileName :  " + fileName);
+		try {
+			// rootXml=null;
+			inputStream = new BufferedReader(new FileReader(fileName));
+			line = "";
+			
+			while ((line = readNextLine()) != null) {
+				showData("lineNumber  "+lineNumber+"  line :  " + line);
+				countMap = new HashMap();
+				line = line.trim();
+				parseLine();
+
+			}
+			showData("all lins read " );
+			
+		}catch(Exception ex) {
+			ex.printStackTrace();
+		}
+		finally {
+			if (inputStream != null) {
+				inputStream.close();
+			}
+		}
+
+		String msgkey = null;
+		msgkey = "xml.element.not.closed";
+		if (!xmlStackElements.isEmpty()) {
+			// showData("-stack is not empty ");
+			while (!xmlStackElements.isEmpty()) {
+
+				String elmName = xmlStackElements.lastElement().getName().trim();
+				Message msg = new Message();
+				msg = new Message();
+				msg.setMessageSource(IWRTConstants.VALIDATOR);
+				msg.setLineNumber(xmlStackElements.lastElement().getLineNo());
+				msg.setTargetObject(targetFileName);
+				msg.setMessageKey(msgkey);
+				msg.setMessage(ValidatorPropMessages.getString(msgkey) + "   "+ elmName);
+				msg.setSeverity(IWRTConstants.ERROR);
+				msg.setRecommendAction(ValidatorPropMessages.getString("todo."+ msgkey));
+				xmlStackElements.lastElement().addError(msg);
+				xmlStackElements.pop();
+
+			}
+		}
+
+		log.finest("parseXML <<---<<");
+		return rootXml;
+	}
+
+	protected void parseLine() throws IOException {
+		log.finest("parseLine >>--->>");
+//		 showData("parseLine>---->>:"+line+":");
+		int x = 0;
+		while (line != null && line.trim().length() > 0 && !endDoc) {
+			//line = line.trim();
+			getcount(line);
+			String block = getNextElement();
+			if (block != null)
+				processBlock(block);
+		}// end while.
+
+		log.finest("parseLine <<---<<");
+	}
+
+	protected void processBlock(String block) {
+		log.finest("processBlock >>-->>");
+
+		getcount(block);
+
+		// showData("-------------------------------------------------------------------");
+		// showData( "type "+elmType+" processBlock----------block process :"+block);
+		// showData(" beginElementCount----------block process :"+beginElementCount);
+		// showData(" endElementCount----------block process :"+endElementCount);
+		// showData(" beginEndElementCount----------block process :"+beginEndElementCount);
+		// showData(" posBeginEndElement----------block process :"+posBeginEndElement);
+		// showData(error +" posBeginElement----------block process :"+posBeginElement);
+		//		
+
+		if (error) {
+
+			String newBlock;
+			if (beginElementCount == 2 && endElementCount == 1) {
+				newBlock = block.substring(posBeginElement, block.indexOf('<',	posBeginElement + 1));
+				line = block.substring(block.indexOf('<', posBeginElement + 1) + 1)	+ line;
+				getcount(newBlock);
+			} else if (beginElementCount == 1 && endElementCount == 2) {
+				newBlock = block.substring(0, posEndElement);
+				line = block.substring(posEndElement + 1) + line;
+				getcount(newBlock);
+			} else if (beginElementCount == 1 && beginEndElementCount == 0&& endElementCount == 0) {
+				elmType = typeElmBegin;
+			} else if (beginElementCount == 1 && beginEndElementCount == 1&& endElementCount == 0) {
+				elmType = typeElmEnd;
+			}
+
+		}
+		if (beginElementCount == 1 && endElementCount == 1) {
+			error = false;
+		}
+		if ((block.startsWith("<?") || block.contains("?xml") || block	.contains("?>"))&& !xmlDeclarationSet) {
+			startDocument(block);
+			return;
+		}
+		if (block.startsWith("<!DOCTYPE")|| (block.contains("!DOCTYPE") && !docTypeSet)) {
+			processDocType(block);
+			return;
+		}
+		if (elmType == typeElmValue) {
+			processElementValue(block);
+			lastElmType = elmType;
+		}
+		if (elmType == typeEmptyElm) {
+			processEmptyElement(block);
+			lastElmType = elmType;
+			return;//					
+		}
+		if (elmType == typeElmBegin) {
+			processStartElement(block);
+			lastElmType = elmType;
+			return;
+		}
+		if (elmType == this.typeElmEnd) {
+			processCloseElement(block);
+			lastElmType = elmType;
+			return;
+		}
+
+	}
+
+	// ---------------Start Parsing
+	// Methods---------------------------------------//
+
+	public void startDocument(String xmlDeclaration) {
+		log.finest("startDocument>>-->>");
+		// showData("startDocument>>-->> :"+xmlDeclaration);
+		rootXml = new XmlElement();
+		rootXml.setXmlDeclaration(xmlDeclaration);
+		xmlDeclarationSet = true;
+		if (error) {
+			String msgkey = null;
+			if (beginElementCount == 1 && endElementCount == 0) {
+				msgkey = "xml.declaration.error.missing.close";
+			}
+			if (beginElementCount == 0 && endElementCount == 1) {
+				msgkey = "xml.declaration.error.missing.open";
+			}
+			if (beginElementCount == 0 && endElementCount == 0) {
+				msgkey = "xml.declaration.error.missing.open.and.close";
+			}
+
+			Message msg = new Message();
+			msg.setMessageSource(IWRTConstants.VALIDATOR);
+			msg.setLineNumber(lineNumber);
+			msg.setMessageKey(msgkey);
+			msg.setMessage(ValidatorPropMessages.getString(msgkey)); //$NON-NLS-1$
+			msg.setSeverity(IWRTConstants.ERROR);
+			msg.setRecommendAction(ValidatorPropMessages.getString("todo."+ msgkey));
+			rootXml.addError(msg);
+
+		}
+
+		log.finest("startDocument <<--<< ");
+
+	}
+
+	public void processDocType(String docType) {
+		log.finest("processDocType >>--->>    : " + docType);
+		// showData("processDocType >>--->> : " +docType);
+		if (rootXml == null) {
+			xmlStackElements = new Stack();
+			rootXml = new XmlElement();
+		}
+		rootXml.setDocType(docType);
+		this.docTypeSet = true;
+
+		if (error) {
+			String msgkey = null;
+			if (beginElementCount == 1 && endElementCount == 0) {
+				msgkey = "xml.doctype.error.missing.close";
+			}
+			if (beginElementCount == 0 && endElementCount == 1) {
+				msgkey = "xml.doctype.error.missing.open";
+			}
+			if (beginElementCount == 0 && endElementCount == 0) {
+				msgkey = "xml.doctype.error.missing.open.and.close";
+			}
+
+			Message msg = new Message();
+			msg.setMessageSource(IWRTConstants.VALIDATOR);
+			msg.setLineNumber(lineNumber);
+			msg.setMessageKey(msgkey);
+			msg.setTargetObject(targetFileName);
+			msg.setMessage(ValidatorPropMessages.getString(msgkey));
+			msg.setSeverity(IWRTConstants.ERROR);
+			msg.setRecommendAction(ValidatorPropMessages.getString("todo."+ msgkey));
+			rootXml.addError(msg);
+
+		}
+
+		log.finest("processDocType<<---<<   : ");
+
+	}
+
+	public void processStartElement(String startElem) {
+		log.finest("processStartElement >>--->>    : " + startElem);
+		// showData("processStartElement >>--->> : "+startElem);
+
+		String elmName = null;
+		Message msg = null;
+
+		if (error) {
+			String msgkey = null;
+			if (beginElementCount == 1 && endElementCount == 0) {
+				msgkey = "xml.element.error.missing.close";
+			}
+			if (beginElementCount == 0 && endElementCount == 1) {
+				msgkey = "xml.element.error.missing.open";
+			}
+			if (beginElementCount == 0 && endElementCount == 0) {
+				msgkey = "xml.element.error.missing.open.and.close";
+			}
+
+			msg = new Message();
+			msg.setMessageSource(IWRTConstants.VALIDATOR);
+			msg.setLineNumber(lineNumber);
+			msg.setTargetObject(targetFileName);
+			msg.setMessageKey(msgkey);
+			msg.setMessage(ValidatorPropMessages.getString(msgkey) + elmName);
+			msg.setSeverity(IWRTConstants.ERROR);
+			msg.setRecommendAction(ValidatorPropMessages.getString("todo."
+					+ msgkey));
+
+		}
+		elmName = getElementName(startElem);
+		if (rootXml == null) {
+			rootXml = new XmlElement();
+			xmlStackElements = new Stack();
+
+		}
+		if (rootElmStartSet) {
+
+			XmlElement xmlNode = new XmlElement();
+			xmlNode.setName(elmName);
+			xmlNode.setLineNo(lineNumber);
+			if (!xmlStackElements.isEmpty()) {
+				xmlStackElements.lastElement().addChild(xmlNode);
+				xmlStackElements.push(xmlNode);
+				parseAttributes(xmlNode, startElem, elmName);
+				if (error) {
+					xmlNode.addError(msg);
+
+				}
+			}
+
+		} else {
+			rootElmStartSet = true;
+			rootXml.setName(elmName);
+			rootXml.setLineNo(lineNumber);
+			xmlStackElements.push(rootXml);
+			parseAttributes(rootXml, startElem, elmName);
+			if (error) {
+				rootXml.addError(msg);
+
+			}
+		}
+		log.finest("processStartElement <<--<<    : ");
+	}
+
+	public void processCloseElement(String closeElem) {
+		log.finest("processCloseElement >>--->>   : " + closeElem);
+//		 showData("processCloseElement >>--->> "+closeElem);
+		String elmName = null;
+		Message msg = null;
+		if (error) {
+			getcount(closeElem);
+			String msgkey = null;
+			if (beginElementCount == 1 && endElementCount == 0) {
+				msgkey = "xml.element.end.error.missing.close";
+			}
+			if (beginElementCount == 0 && endElementCount == 1) {
+				msgkey = "xml.element.end.error.missing.open";
+			}
+			if (beginElementCount == 0 && endElementCount == 0) {
+				msgkey = "xml.element.end.error.missing.open.and.close";
+			}
+
+			msg = new Message();
+			msg.setMessageSource(IWRTConstants.VALIDATOR);
+			msg.setLineNumber(lineNumber);
+			msg.setTargetObject(targetFileName);
+			msg.setMessageKey(msgkey);
+			msg.setMessage(ValidatorPropMessages.getString(msgkey) + elmName);
+			msg.setSeverity(IWRTConstants.ERROR);
+			msg.setRecommendAction(ValidatorPropMessages.getString("todo."+ msgkey));
+
+		}
+		elmName = getElementName(closeElem);
+
+		if (rootXml == null) {
+			rootXml = new XmlElement();
+			xmlStackElements = new Stack();
+			// error
+		}
+
+		if (!xmlStackElements.isEmpty()) {
+			if (xmlStackElements.lastElement().getName().trim()	.equalsIgnoreCase(elmName)) {
+				if (error) {
+					xmlStackElements.lastElement().addError(msg);
+				}
+				xmlStackElements.pop();
+			} else {
+				// identify error .
+				// a close element name which not matches with the last element
+				// in the stack.
+				String msgkey = null;
+				msgkey = "xml.element.not.closed";
+				msg = new Message();
+				msg.setMessageSource(IWRTConstants.VALIDATOR);
+				msg.setLineNumber(xmlStackElements.lastElement().getLineNo());
+				msg.setTargetObject(targetFileName);
+				msg.setMessageKey(msgkey);
+				msg.setMessage(ValidatorPropMessages.getString(msgkey) + "   "+ xmlStackElements.lastElement().getName());
+				msg.setSeverity(IWRTConstants.ERROR);
+				msg.setRecommendAction(ValidatorPropMessages.getString("todo."+ msgkey));
+				xmlStackElements.lastElement().addError(msg);
+				xmlStackElements.pop();
+
+			}
+		}
+		log.finest("processCloseElement <<--<<   : ");
+	}
+
+	public void processEmptyElement(String emptyElem) {
+		log.finest("processEmptyElement >>--->>    : " + emptyElem);
+		// showData("processEmptyElement >>--->> : "+emptyElem);
+		Message msg = null;
+		String elmName = null;
+		if (error) {
+			String msgkey = null;
+
+			if (beginElementCount == 1 && endElementCount == 0) {
+				msgkey = "xml.element.error.missing.close";
+			}
+			if (beginElementCount == 0 && endElementCount == 1) {
+				msgkey = "xml.element.error.missing.open";
+			}
+			if (beginElementCount == 0 && endElementCount == 0) {
+				msgkey = "xml.element.error.missing.open.and.close";
+			}
+
+			msg = new Message();
+			msg.setMessageSource(IWRTConstants.VALIDATOR);
+			msg.setLineNumber(lineNumber);
+			msg.setTargetObject(targetFileName);
+			msg.setMessageKey(msgkey);
+			msg.setMessage(ValidatorPropMessages.getString(msgkey) + elmName);
+			msg.setSeverity(IWRTConstants.ERROR);
+			msg.setRecommendAction(ValidatorPropMessages.getString("todo."+ msgkey));
+
+		}
+		elmName = getElementName(emptyElem);
+
+		if (rootXml == null) {
+			// this is an error first element must not be empty
+			rootXml = new XmlElement();
+			xmlStackElements = new Stack();
+			xmlStackElements.add(rootXml);
+		}
+		XmlElement emptyNode = new XmlElement();
+		emptyNode.setName(elmName);
+		emptyNode.setLineNo(lineNumber);
+		parseAttributes(emptyNode, emptyElem, elmName);
+		if (error) {
+			emptyNode.addError(msg);
+		}
+		xmlStackElements.lastElement().addChild(emptyNode);
+		log.finest("processEmptyElement <<--<<    : ");
+	}
+
+	public void processElementValue(String value) {
+		// showData("processElementValue >>---<< : "+value);
+		log.finest("processElementValue >>---<<   : " + value);
+		boolean validchar = validateChar(value);
+		if ((rootXml == null || xmlStackElements == null)
+				&& (xmlStackElements.size() < 1)) {
+
+			if (!validchar) {
+				String msgkey = "char.present.before.start.line";
+				Message msg = new Message();
+				msg.setMessageSource(IWRTConstants.VALIDATOR);
+				msg.setLineNumber(lineNumber);
+				msg.setMessageKey(msgkey);
+				msg.setMessage(value + ValidatorPropMessages.getString(msgkey));
+				msg.setSeverity(IWRTConstants.ERROR);
+				msg.setRecommendAction(ValidatorPropMessages.getString("todo."+ msgkey));
+				// this is an error first element must not be empty
+				rootXml = new XmlElement();
+				xmlStackElements = new Stack();
+				rootXml.addError(msg);
+
+			}
+			return;
+
+		}
+		if (!(xmlStackElements.lastElement().getName().equalsIgnoreCase("style") && value.length() > 100)) {
+			xmlStackElements.lastElement().setValue(value);
+		} else {
+			xmlStackElements.lastElement().setValue(parseStyleBody(value));
+
+		}
+
+	}
+
+	// ===========================================================
+	// Helpers Methods
+	// ===========================================================
+
+	protected String getNextElement() throws IOException {
+//		showData("getNextElement>>---->>");
+		String element = "";
+		String processLine = line;
+		boolean processLineActive = false;
+
+		// showData("-------------------------------------------------");
+		// showData("beginElementCount :"+beginElementCount);
+		// showData("endElementCount :"+endElementCount);
+		// showData("beginEndElementCount :"+beginEndElementCount);
+		//		 
+		//
+		// showData("beginCommentElementCount :"+beginCommentElementCount);
+		// showData("endCommentElementCount :"+endCommentElementCount);
+		//		 
+		// showData("posBeginElement :"+posBeginElement);
+		// showData("posEndElement :"+posEndElement);
+		//		
+
+		if (beginCommentElementCount > 0 && endCommentElementCount > 0) {
+
+			if (rootXml != null && xmlStackElements != null
+					&& !xmlStackElements.isEmpty()) {
+				if (xmlStackElements.lastElement().getName().trim()	.equalsIgnoreCase("script")
+						|| xmlStackElements.lastElement().getName().trim().equalsIgnoreCase("Style")
+
+				) {
+
+					if (line.trim().startsWith(beginCommentElement)) {
+						String afterEndComment = line.substring(posEndCommentElement + 3);
+						String beforeEndComment = line.substring(posBeginCommentElement + 4,posEndCommentElement);
+						line = beforeEndComment + afterEndComment;
+
+					} else {
+						line = line.replaceFirst(beginCommentElement, " ");
+						line = line.replaceFirst(endCommentElement, " ");
+					}
+					getcount(line);
+				}
+
+			}
+
+			if (line.trim().startsWith(beginCommentElement)) {
+				line = line.substring(posEndCommentElement + 3);
+				return null;
+			} else {
+				String beforeComment = line.substring(0, posBeginCommentElement);
+				line = beforeComment + line.substring(posEndCommentElement + 3);
+			}
+
+		}
+		if (beginCommentElementCount == 1 && endCommentElementCount == 0) {
+			// line = line + " " + inputStream.readLine();
+			// lineNumber++;
+			readNextLine();
+			return null;
+		}
+
+		if (beginElementCount == 0 && endElementCount == 0) {
+			// line = line + " " + inputStream.readLine();
+			// lineNumber++;
+			readNextLine();
+			return null;
+		}
+		if (beginElementCount == 2 && endElementCount == 2
+				&& beginEndElementCount == 1) {
+			element = line.substring(0, posEndElement + 1);
+			line = line.substring(posEndElement + 1);
+			elmType = typeElmBegin;
+			return element;
+		}
+
+		if (beginElementCount == 2 && beginEndElementCount == 1) {
+			element = line.substring(0, posBeginEndElement);
+			line = line.substring(posBeginEndElement);
+			error = true;
+			elmType = typeErrorElement;
+			return element;
+		}
+		if (beginElementCount == 1 && endElementCount == 2) {
+			element = line.substring(0, posEndElement + 1);
+			line = line.substring(posEndElement + 1);
+			error = true;
+			elmType = typeErrorElement;
+			return element;
+		}
+
+		if (beginElementCount > 0 && endElementCount == 0) {
+			// line = line + " " + inputStream.readLine();
+			// lineNumber++;
+			readNextLine();
+			return null;
+		}
+
+		if (beginElementCount == 0 && endElementCount > 0) {
+			element = line.substring(0, posEndElement + 1);
+			line = line.substring(posEndElement + 1);
+			error = true;
+			elmType = typeErrorElement;
+			return element;
+		}
+
+		if (beginElementCount > 0 && endElementCount > 0) {
+			if (posBeginElement < posEndElement) {
+				if (beginElementCount > 1 && endElementCount > 1&& trimElementSpace(line).startsWith("<")) {
+					element = line.substring(posBeginElement, posEndElement + 1);
+					line = line.substring(posEndElement + 1);
+					getcount(element);
+					processLine = element;
+					processLineActive = true;
+				}
+				if (beginElementCount == 1 && endElementCount == 1&& trimElementSpace(processLine).startsWith("<")) {
+					if (beginEndElementCount == 1) {
+						elmType = typeElmEnd;
+					} else if (endEmptyElementCount == 1) {
+						elmType = typeEmptyElm;
+					} else {
+						elmType = typeElmBegin;
+					}
+					if (processLineActive)
+						return element;
+					element = line.substring(posBeginElement, posEndElement + 1);
+					line = line.substring(posEndElement + 1);
+					error = false;
+					return element;
+				} else if (beginElementCount == 2 && endElementCount == 1
+						&& trimElementSpace(processLine).startsWith("<")) {
+					// clear case of error begin element is not close properly
+					error = true;
+					if (element.lastIndexOf('<') < posEndElement) {
+
+						if (processLineActive) {
+							element = element.substring(0, element.lastIndexOf('<'));
+							line = processLine.substring((processLine.lastIndexOf('<')))+ line;
+						} else {
+							getcount(line);
+							element = line.substring(posBeginElement, line.lastIndexOf('<'));
+							line = line.substring(line.lastIndexOf('<'));
+
+						}
+					}
+					getcount(element);
+					if (beginElementCount == 1 && endElementCount == 1)
+						error = false;
+					if (beginEndElementCount == 1)
+						elmType = typeElmEnd;
+					if (endEmptyElementCount == 1)
+						elmType = typeEmptyElm;
+					if (lastElmType == typeElmEnd && beginElementCount == 1)
+						elmType = typeElmBegin;
+					if (lastElmType == typeElmEnd && endElementCount == 1&& endEmptyElementCount == 0)
+						elmType = typeElmBegin;
+					return element;
+				} else if (!(trimElementSpace(processLine).startsWith("<"))) {
+					if (!xmlDeclarationSet)
+						error = true;
+					if (!this.xmlDeclarationSet)
+						error = true;
+
+					element = line.substring(0, posBeginElement);
+					line = line.substring(posBeginElement);
+					elmType = typeElmValue;
+				}
+
+			} else {
+
+				if (beginElementCount == 1 && endElementCount == 2
+						&& !trimElementSpace(processLine).startsWith("<")
+						&& lastElmType == typeElmEnd) {
+
+					element = line.substring(0, posEndElement + 1);
+					line = line.substring(posEndElement + 1);
+					elmType = typeElmBegin;
+					error = true;
+				} else {
+					element = line.substring(0, posEndElement - 1);
+					line = line.substring(posEndElement);
+					error = true;
+					elmType = typeErrorElement;
+				}
+			}
+		}
+		if (line.trim().length() == 0)
+			line = null;
+//		showData("getNextElement  <<---<<");
+		return element;
+
+	}
+
+	protected void getcount(String inputLine) {
+		char[] array = inputLine.toLowerCase().toCharArray();
+		beginElementCount = 0;
+		endElementCount = 0;
+		endEmptyElementCount = 0;
+		beginEndElementCount = 0;
+
+		posBeginElement = 0;
+		posEndElement = 0;
+		posEndEmptyElement = 0;
+		posBeginEndElement = 0;
+
+		beginCommentElementCount = 0;
+		endCommentElementCount = 0;
+		posBeginCommentElement = 0;
+		posEndCommentElement = 0;
+
+		posJavaScriptCommentElement = 0;
+		javaScriptCommentElementCount = 0;
+
+		countMap.clear();
+		countMap = null;
+		countMap = new HashMap();
+		int count = 0;
+		char previous = ' ';
+		String comment = "";
+
+		for (int i = 0; i < array.length; i++) {
+			char charToCount = array[i];
+			count = 1;
+			if (charToCount == '>' && previous == '/') {
+				if (countMap.containsKey(endEmptyElement)) {
+					count = (Integer) countMap.get(endEmptyElement);
+					count++;
+				}
+				countMap.put(endEmptyElement, count);
+			}
+			count = 1;
+
+			if (charToCount == '/' && previous == '<') {
+				if (countMap.containsKey(beginEndElement)) {
+					count = (Integer) countMap.get(beginEndElement);
+					count++;
+				}
+				countMap.put(beginEndElement, count);
+			}
+			count = 1;
+
+			if (charToCount == '/' && previous == '/') {
+				if (countMap.containsKey(javaScriptCommentElement)) {
+					count = (Integer) countMap.get(javaScriptCommentElement);
+					count++;
+				}
+				countMap.put(javaScriptCommentElement, count);
+			}
+			count = 1;
+			if (charToCount == '-' && previous == '-') {
+
+				if (i > 2 && array[i - 2] == '!' && array[i - 3] == '<') {
+					if (countMap.containsKey(beginCommentElement)) {
+						count = (Integer) countMap.get(beginCommentElement);
+						count++;
+					}
+					countMap.put(beginCommentElement, count);
+				}
+
+			}
+			count = 1;
+			if (charToCount == '>' && previous == '-') {
+
+				if (array[i - 2] == '-') {
+					if (countMap.containsKey(endCommentElement)) {
+						count = (Integer) countMap.get(endCommentElement);
+						count++;
+					}
+					countMap.put(endCommentElement, count);
+				}
+			}
+
+			count = 1;
+			if (countMap.containsKey(charToCount)) {
+				count = (Integer) countMap.get(charToCount);
+				count++;
+			}
+			if (charToCount != ' ') {
+				previous = charToCount;
+			}
+			countMap.put(charToCount, count);
+		}
+
+		if (countMap.containsKey(beginElement)) {
+			beginElementCount = (Integer) countMap.get(beginElement);
+			posBeginElement = inputLine.indexOf(beginElement);
+		}
+		if (countMap.containsKey(endElement)) {
+			endElementCount = (Integer) countMap.get(endElement);
+			posEndElement = inputLine.indexOf(endElement);
+		}
+		if (countMap.containsKey(endEmptyElement)) {
+			endEmptyElementCount = (Integer) countMap.get(endEmptyElement);
+			posEndEmptyElement = inputLine.indexOf(endEmptyElement);
+		}
+		if (countMap.containsKey(beginEndElement)) {
+			beginEndElementCount = (Integer) countMap.get(beginEndElement);
+			posBeginEndElement = inputLine.indexOf(beginEndElement);
+
+		}
+		if (countMap.containsKey(this.beginCommentElement)) {
+			beginCommentElementCount = (Integer) countMap
+					.get(beginCommentElement);
+			posBeginCommentElement = inputLine.indexOf(beginCommentElement);
+
+		}
+		if (countMap.containsKey(this.endCommentElement)) {
+			endCommentElementCount = (Integer) countMap.get(endCommentElement);
+			posEndCommentElement = inputLine.indexOf(endCommentElement);
+
+		}
+		// showData("endEmptyElementCount :"+endEmptyElementCount);
+		// showData("posEndEmptyElement :"+posEndEmptyElement);
+		//
+		// showData("beginElementCount :"+beginElementCount);
+		// showData("posBeginElement :"+posBeginElement);
+		// showData("beginEndElementCount :"+beginEndElementCount);
+		// showData("posBeginEndElement :"+posBeginEndElement);
+		// showData("endElementCount :"+endElementCount);
+		// showData("posEndElement :"+posEndElement);
+
+	}
+
+	protected String getElementName(String element) {
+		String elmName = null;
+		int start = 0;
+		int end = 0;
+		int spaceIndex = element.indexOf(' ');
+		if (beginEndElementCount == 1) {
+			start = posBeginEndElement + 2;
+		} else if (beginElementCount == 1) {
+			start = posBeginElement + 1;
+		} else if (beginElementCount == 0) {
+			if (element.trim().startsWith("/"))
+				start = element.indexOf("/") + 1;
+		}
+
+		if (this.endEmptyElementCount == 1) {
+			end = posEndEmptyElement;
+			if (spaceIndex < posEndEmptyElement && spaceIndex > start) {
+				end = element.indexOf(' ');
+			}
+
+		} else if (endElementCount == 1) {
+
+			end = posEndElement;
+			if (spaceIndex < posEndElement && spaceIndex > start) {
+				end = spaceIndex;
+			}
+		} else if (endElementCount == 0) {
+			if (spaceIndex < element.length() && spaceIndex > start) {
+				end = spaceIndex;
+			}
+			if (element.trim().endsWith("/")) {
+				if (spaceIndex < element.indexOf("/") && spaceIndex > start) {
+					end = spaceIndex;
+				} else {
+					end = element.indexOf("/");
+				}
+			}
+			if (beginEndElementCount == 1 && spaceIndex < posBeginEndElement) {
+				end = element.length();
+
+			}
+
+		}
+		if (end <= start)
+			end = element.length();
+		elmName = element.substring(start, end);
+		return elmName;
+	}
+
+	protected void parseAttributes(XmlElement elm, String elementLine,
+			String name) {
+		// log.finest("parseAttributes >>--->> ");
+		// showData(" parseAttributes ------->>:" + elementLine+": name :" +
+		// name);
+
+		log.finest("parseAttributes >>--->>  name   : " + name);
+		log.finest("parseAttributes >>--->>  startElement  : " + elementLine);
+
+		elementLine = trimElementAttrSpace(elementLine);
+		int nameEndIndex = elementLine.indexOf(name) + name.length();
+		int spaceIndex = 0;
+		int equalIndex = 0;
+		int quotesIndex = 0;
+		int endIndex = 0;
+		elementLine = (elementLine.substring(nameEndIndex)).trim();
+
+		char before = ' ';
+		char x = ' ';
+		StringBuffer otherString = new StringBuffer();
+		String key;
+		String value;
+
+		Attribute attr = null;
+		while (elementLine != null && elementLine.trim().length() > 0) {
+			spaceIndex = elementLine.indexOf(' ');
+			equalIndex = elementLine.indexOf('=');
+			if (elementLine.contains("=")) {
+				key = elementLine.substring(0, equalIndex);
+				key.replaceAll("=", "");
+				log.finest("Key   : " + key);
+				// showData("Key :"+key);
+				elementLine = elementLine.substring(equalIndex + 1).trim();
+				if (elementLine.contains("\"")) {
+					if (elementLine.indexOf('"') == 0) {
+						elementLine = elementLine.substring(1);
+					}
+
+				}
+				spaceIndex = elementLine.indexOf(' ');
+				quotesIndex = elementLine.indexOf('"');
+				if (quotesIndex < 0)
+					quotesIndex = elementLine.indexOf('\'');
+				equalIndex = elementLine.indexOf('=');
+				endIndex = elementLine.indexOf('>');
+				if (spaceIndex > quotesIndex) {
+
+					value = elementLine.substring(0, spaceIndex - 1);
+					elementLine = elementLine.substring(spaceIndex).trim();
+				} else if (spaceIndex < quotesIndex && equalIndex < quotesIndex
+						&& spaceIndex > 0) {
+
+					value = elementLine.substring(0, spaceIndex);
+					elementLine = elementLine.substring(spaceIndex).trim();
+				} else if (spaceIndex < quotesIndex && spaceIndex > 0) {
+
+					value = elementLine.substring(0, quotesIndex);
+					elementLine = elementLine.substring(quotesIndex).trim();
+				} else if (spaceIndex < quotesIndex && spaceIndex == -1) {
+
+					value = elementLine.substring(0, quotesIndex);
+					elementLine = elementLine.substring(quotesIndex + 1).trim();
+				} else {
+
+					value = elementLine.substring(0, endIndex);
+					elementLine = "";
+				}
+				log.finest("Value  : " + value);
+				// showData(key+"= '"+value+"'");
+				attr = elm.new Attribute();
+				attr.setKey(key);
+				value = value.replaceAll("\"", "");
+				value = value.replaceAll("'", "");
+				value = value.trim();
+
+				attr.setValue(value);
+				elm.addAttribute(attr);
+				//				
+			} else {
+				elementLine = "";
+			}
+
+		}
+		log.finest("parseAttributes <<--<<");
+
+	}
+
+	// --------------End Parsing
+	// Methods-------------------------------------------------------------------
+	public String trimElementSpace(String element) {
+		log.finest("trimElementSpace>>--->>");
+		StringBuffer otherString = new StringBuffer();
+		for (int i = 0; i < element.length(); i++) {
+			char x = element.charAt(i);
+			int ascii = (x > 127) ? '?' : (char) (x & 0x7F);
+
+			if (x != ' ' && ascii != 9) {
+				otherString.append(x);
+			}
+		}
+		log.finest("trimElementSpace<<---<<");
+		return otherString.toString();
+	}
+
+	public String trimElementAttrSpace(String element) {
+		log.finest("trimElementAttrSpace>>--->>");
+		StringBuffer otherString = new StringBuffer();
+		char before = ' ';
+		char x = ' ';
+		for (int i = 0; i < element.length(); i++) {
+			if (i != 0) {
+				before = x;
+			}
+
+			x = element.charAt(i);
+			int ascii = (x > 127) ? '?' : (char) (x & 0x7F);
+
+			if (x != ' ' && ascii != 9) {
+				if ((before == ' ' && x != '=') || (before == ' ' && x != '"')) {
+					otherString.append(' ');
+				}
+				otherString.append(x);
+
+			}
+		}
+		log.finest("trimElementAttrSpace<<---<<");
+		return otherString.toString();
+	}
+
+	public String readNextLine() throws IOException {
+
+		String nextLine = inputStream.readLine();
+		lineNumber++;
+		if (nextLine == null) {
+			endDoc = true;
+			return null;
+		}
+		String testLine = nextLine;
+		testLine = testLine.trim();
+		if (rootXml != null && xmlStackElements != null	&& !xmlStackElements.isEmpty()) {
+			
+			if (xmlStackElements.lastElement().getName().trim()	.equalsIgnoreCase("script")
+					&& testLine.startsWith(this.javaScriptCommentElement)) {
+			
+				if (!(beginCommentElementCount == 1	&& endCommentElementCount == 0 && testLine
+						.contains(endCommentElement))) {
+					nextLine = "";
+					readNextLine();
+				}
+			}
+		}
+
+		line = line + " " + nextLine;
+		line = line.trim();
+
+		return line;
+	}
+
+	protected static void showData(String s) {
+//		if (s != null && s.trim().length() > 0)
+//			System.out.println(s);
+	}
+
+	protected void getNameAndValue(XmlElement rootXml) {
+		// showData("getName "+rootXml.getName());
+		// showData("value "+rootXml.getValue());
+
+		for (XmlElement elm : rootXml.getChildList()) {
+			getNameAndValue(elm);
+		}
+		if (rootXml.getAttrList() != null)
+			for (Attribute attr : rootXml.getAttrList()) {
+				showData("Attr     " + attr.getKey() + "='" + attr.getValue()
+						+ "'");
+			}
+	}
+
+	protected boolean validateChar(String block) {
+		char x = ' ';
+		int ascii = 0;
+		boolean invalid = false;
+		String invalidChar = "";
+		for (int i = 0; i < block.length(); i++) {
+			x = block.charAt(i);
+			ascii = (x > 127) ? new Integer(x) : (char) (x & 0x7F);
+			if (x > 127) {
+				invalidChar = invalidChar + x;
+				invalid = true;
+			}
+			// showData(" ascii for " + x + " is : " + ascii);
+		}
+
+		// showData("invalidChar :" + invalidChar);
+
+		if (invalid && enableValidation) {
+			String msgkey = "unrecognized.char.present.at.line.no";
+			Message msg = new Message();
+			msg.setMessageSource(IWRTConstants.VALIDATOR);
+			msg.setLineNumber(lineNumber);
+			msg.setTargetObject(targetFileName);
+			msg.setMessageKey(msgkey);
+			msg.setMessage("  '" + invalidChar + "'   "
+					+ ValidatorPropMessages.getString(msgkey));
+			msg.setSeverity(IWRTConstants.WARN);
+			msg.setRecommendAction(ValidatorPropMessages.getString("todo."
+					+ msgkey));
+
+		}
+
+		return invalid;
+	}
+
+	protected String parseStyleBody(String styleBody) {
+		String returnBlock = IWRTConstants.IMAGE_REF;
+		// System.out.println("value------- importString "+importString+":");
+		while (styleBody != null && styleBody.trim().length() > 0) {
+			// showData("importString -- : "+importString);
+			String block = null;
+			if (styleBody.contains("background-image:")) {
+				// showData("styleBody.indexOf(background-image:) -- :
+				// "+styleBody.indexOf("background-image:"));
+				// showData("styleBody.indexOf(';') -- :
+				// "+styleBody.indexOf(';'));
+				if (styleBody.indexOf("background-image:") > styleBody
+						.indexOf(';')) {
+					styleBody = styleBody.substring(styleBody
+							.indexOf("background-image:"));
+				}
+
+				block = styleBody.substring(styleBody
+						.indexOf("background-image:"), styleBody.indexOf(';'));
+				styleBody = styleBody.substring(styleBody.indexOf(';') + 1);
+				// showData("styleBody : "+styleBody);
+			} else {
+				styleBody = null;
+			}
+
+			if (block != null && block.contains("background-image:")) {
+				block = block.replace("background-image:", "");
+				block = block.replaceAll("url", "");
+				block = block.replaceAll(";", "");
+				block = block.trim();
+				if (block.contains("(") && block.startsWith("("))
+					block = block.substring(1);
+
+				if (block.contains(")") && block.endsWith(")"))
+					block = block.substring(0, block.length() - 1);
+				if (block.trim().length() > 0)
+					returnBlock = returnBlock + block + "|";
+			}
+		}// end while.
+		// showData("styleBody : "+returnBlock+":");
+		return returnBlock;
+	}
+
+	public class MessageListener implements IMessageListener {
+		private int messageSource;
+
+		public int getMessageSource() {
+			return 1;
+		}
+
+		public void setMessageSource(int messageSource) {
+			this.messageSource = messageSource;
+		}
+
+		public boolean isMessageHandled(Message msg) {
+
+			if (msg.getMessageSource() == (messageSource)) {
+				return true;
+			}
+			return false;
+		}
+
+		public void receiveMessage(Message msg) {
+			// showData("------------------------msg "+msg.getMessage());
+		}
+	}
+
+	public static void main(String[] args) {
+		try {
+			XMLParser xparser = new XMLParser();
+			// xparser.messageHandler = new MessageHandler();
+			// xparser.messageHandler.registerListener(xparser.new
+			// MessageListener());
+			// String fileName = "C:/Documents and
+			// Settings/sduvvuri/Desktop/Validator/Info.plist";
+			String fileName = "d:/test/abc/info.plist";
+			XmlElement rootXml = xparser.parseXML(new File(fileName));
+			showData("getName  " + rootXml.getName());
+			showData("getXmlDeclaration  " + rootXml.getXmlDeclaration());
+			showData("getDocType  " + rootXml.getDocType());
+			showData("child size  " + rootXml.getChildList().size());
+			if (rootXml != null) {
+				for (XmlElement elm : rootXml.getChildList()) {
+					xparser.getNameAndValue(elm);
+
+				}
+			}
+		} catch (Exception e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+
+	}
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/core/parser/XMLPlistParser.java	Wed Jan 27 15:05:37 2010 -0800
@@ -0,0 +1,529 @@
+/**
+ * Copyright (c) 2009 Symbian Foundation and/or its subsidiary(-ies).
+ * All rights reserved.
+ * This component and the accompanying materials are made available
+ * under the terms of the License "Eclipse Public License v1.0"
+ * which accompanies this distribution, and is available
+ * at the URL "http://www.eclipse.org/legal/epl-v10.html".
+ *
+ * Initial Contributors:
+ * Symbian Foundation - initial contribution.
+ * Contributors:
+ * Description:
+ * Overview:
+ * Details:
+ * Platforms/Drives/Compatibility:
+ * Assumptions/Requirement/Pre-requisites:
+ * Failures and causes:
+ */
+package org.symbian.tools.wrttools.core.parser;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.Stack;
+import java.util.logging.Logger;
+import org.symbian.tools.wrttools.core.exception.ValidationException;
+import org.symbian.tools.wrttools.core.report.Message;
+import org.symbian.tools.wrttools.core.status.IWRTConstants;
+import org.symbian.tools.wrttools.core.validator.ValidatorPropMessages;
+import org.symbian.tools.wrttools.core.widgetmodel.WidgetModel;
+
+public class XMLPlistParser extends XMLParser {
+	private Logger log = Logger.getLogger(getClass().getName());
+	public boolean isHomeScreenEnabled = false;
+
+	public enum plistElements {
+		plist, array, data, date, dict, real, integer, string, FALSE, TRUE, key, xml
+
+	};
+
+	public enum parentElements {
+		plist, dict
+
+	};
+
+	public enum emptyElements {
+		FALSE, TRUE
+
+	};
+	
+/**
+ * 
+ */
+	public void processStartElement(String startElem) {
+		log.finest("processStartElement >>--->>    : " + startElem);
+		// showData("processStartElement >>--->> : " + startElem);
+
+		String elmName = null;
+		Message msg = null;
+
+		if (error) {
+			String msgkey = null;
+			if (beginElementCount == 1 && endElementCount == 0) {
+				msgkey = "xml.element.error.missing.close";
+			}
+			if (beginElementCount == 0 && endElementCount == 1) {
+				msgkey = "xml.element.error.missing.open";
+			}
+			if (beginElementCount == 0 && endElementCount == 0) {
+				msgkey = "xml.element.error.missing.open.and.close";
+			}
+
+			msg = new Message();
+			msg.setMessageSource(IWRTConstants.VALIDATOR);
+			msg.setLineNumber(lineNumber);
+			msg.setTargetObject(targetFileName);
+			msg.setMessageKey(msgkey);
+			msg.setMessage(ValidatorPropMessages.getString(msgkey) +"      '"+ elmName+"'");
+			msg.setSeverity(IWRTConstants.ERROR);
+
+		}
+		elmName = getElementName(startElem);
+		if (rootXml == null) {
+			rootXml = new XmlElement();
+			xmlStackElements = new Stack();
+
+		}
+		if (rootElmStartSet) {
+
+			// ---------------------------------
+			if (xmlStackElements.lastElement().getName().trim()
+					.equalsIgnoreCase(elmName)) {
+				// identify error .
+				// a close element name which not matches with the last element
+				// in the stack.
+				String msgkey = null;
+				msgkey = "xml.element.not.closed";
+				msg = new Message();
+				msg.setMessageSource(IWRTConstants.VALIDATOR);
+				msg.setLineNumber(xmlStackElements.lastElement().getLineNo());
+				msg.setTargetObject(targetFileName);
+				msg.setMessageKey(msgkey);
+				msg.setMessage(ValidatorPropMessages.getString(msgkey) + "   '"	+ xmlStackElements.lastElement().getName()+"'");
+				msg.setSeverity(IWRTConstants.ERROR);
+				xmlStackElements.lastElement().addError(msg);
+//				showData(" -------------------adding msg  processStartElement : "	+ elmName + "    " + msgkey);
+
+				xmlStackElements.pop();
+			} else {
+				// -------------------------------
+				if (isEmpty(elmName)) {
+
+					String msgkey = null;
+					msgkey = "xml.empty.element.not.closed";
+					msg = new Message();
+					msg.setMessageSource(IWRTConstants.VALIDATOR);
+					msg.setLineNumber(lineNumber);
+					msg.setTargetObject(targetFileName);
+					msg.setMessageKey(msgkey);
+					msg.setMessage(ValidatorPropMessages.getString(msgkey)	+ "   '" + elmName+"'");
+					msg.setSeverity(IWRTConstants.ERROR);
+					if (rootXml == null) {
+						// this is an error first element must not be empty
+						rootXml = new XmlElement();
+						xmlStackElements = new Stack();
+						xmlStackElements.add(rootXml);
+					}
+					XmlElement emptyNode = new XmlElement();
+					emptyNode.setName(elmName);
+					emptyNode.setLineNo(lineNumber);
+					emptyNode.addError(msg);
+					addChild(emptyNode);
+
+				} else {
+
+					XmlElement xmlNode = new XmlElement();
+					xmlNode.setName(elmName);
+					xmlNode.setLineNo(lineNumber);
+					if (!xmlStackElements.isEmpty()) {
+						addChild(xmlNode);
+						// if(validateElement(elmName)) {
+						xmlStackElements.push(xmlNode);
+						// }
+
+						parseAttributes(xmlNode, startElem, elmName);
+						if (error) {
+							xmlNode.addError(msg);
+
+						}
+					}
+
+				}
+			}// ------------------------
+
+		} else {
+			rootElmStartSet = true;
+			rootXml.setName(elmName);
+			rootXml.setLineNo(lineNumber);
+			xmlStackElements.push(rootXml);
+			parseAttributes(rootXml, startElem, elmName);
+			if (error) {
+				rootXml.addError(msg);
+
+			}
+		}
+		log.finest("processStartElement <<--<<    : ");
+	}
+	// =======================================================================================//
+
+/**
+ * 
+ */
+	public void processCloseElement(String closeElem) {
+		log.finest("processCloseElement >>--->>   : " + closeElem);
+//		showData("processCloseElement >>--->> " + closeElem);
+		String elmName = null;
+		Message msg = null;
+		if (error) {
+			getcount(closeElem);
+			String msgkey = null;
+			if (beginElementCount == 1 && endElementCount == 0) {
+				msgkey = "xml.element.end.error.missing.close";
+			}
+			if (beginElementCount == 0 && endElementCount == 1) {
+				msgkey = "xml.element.end.error.missing.open";
+			}
+			if (beginElementCount == 0 && endElementCount == 0) {
+				msgkey = "xml.element.end.error.missing.open.and.close";
+			}
+
+			msg = new Message();
+			msg.setMessageSource(IWRTConstants.VALIDATOR);
+			msg.setLineNumber(lineNumber);
+			msg.setTargetObject(targetFileName);
+			msg.setMessageKey(msgkey);
+			msg.setMessage(ValidatorPropMessages.getString(msgkey) + "   '"+elmName+"'");
+			msg.setSeverity(IWRTConstants.ERROR);
+		}
+		elmName = getElementName(closeElem);
+
+		if (rootXml == null) {
+			rootXml = new XmlElement();
+			xmlStackElements = new Stack();
+			// error
+		}
+
+		if (!xmlStackElements.isEmpty()) {
+			if (xmlStackElements.lastElement().getName().trim()
+					.equalsIgnoreCase(elmName)) {
+				if (error) {
+					xmlStackElements.lastElement().addError(msg);
+				}
+				xmlStackElements.pop();
+			} else {
+				// identify error .
+				// a close element name which not matches with the last element
+				// in the stack.
+				String msgkey = null;
+				
+
+				if (isParent(getElementName(closeElem))) {
+//					showData(" --------- isParent : " + closeElem);
+					if (closeElementInStack(getElementName(closeElem))) {
+						msgkey = "xml.element.not.closed";
+						msg = new Message();
+						msg.setMessageSource(IWRTConstants.VALIDATOR);
+						msg.setLineNumber(lineNumber);
+						msg.setTargetObject(targetFileName);
+						msg.setMessageKey(msgkey);
+						msg.setMessage(ValidatorPropMessages.getString(msgkey) + "   '"	+ xmlStackElements.lastElement().getName()+"'");
+						msg.setSeverity(IWRTConstants.ERROR);
+						xmlStackElements.lastElement().addError(msg);
+						xmlStackElements.pop();
+						processCloseElement(closeElem);
+
+					} else {
+						msgkey = "xml.close.element.not.opened";
+						msg = new Message();
+						msg.setMessageSource(IWRTConstants.VALIDATOR);
+						msg.setLineNumber(lineNumber);
+						msg.setTargetObject(targetFileName);
+						msg.setMessageKey(msgkey);
+						msg.setMessage(ValidatorPropMessages.getString(msgkey)	+ "    '" + closeElem + "'");
+						msg.setSeverity(IWRTConstants.ERROR);
+						xmlStackElements.lastElement().addError(msg);
+					}
+
+				} else {
+					msgkey = "xml.close.element.not.opened";
+					msg = new Message();
+					msg.setMessageSource(IWRTConstants.VALIDATOR);
+					msg.setLineNumber(lineNumber);
+					msg.setTargetObject(targetFileName);
+					msg.setMessageKey(msgkey);
+					msg.setMessage(ValidatorPropMessages.getString(msgkey)
+							+ "    '" + closeElem + "'");
+					msg.setSeverity(IWRTConstants.ERROR);
+					xmlStackElements.lastElement().addError(msg);
+				}
+
+			}
+		}
+//		showData("processCloseElement <<--<<  " + closeElem);
+		log.finest("processCloseElement <<--<<   : ");
+	}
+	// =======================================================================================//
+
+
+/**
+ * 
+ * @param elmName
+ * @return
+ */
+	public boolean isParent(String elmName) {
+		parentElements[] values = parentElements.values();
+
+		boolean isValidParent = false;
+		for (parentElements validElement : values) {
+			if (validElement.toString().equalsIgnoreCase(elmName.trim())) {
+				isValidParent = true;
+				break;
+			}
+			continue;
+		}
+		return isValidParent;
+	}
+/**
+ * 
+ * @param elmName
+ * @return
+ */
+	public boolean isEmpty(String elmName) {
+		emptyElements[] values = emptyElements.values();
+
+		boolean isValidEmpty = false;
+		for (emptyElements validElement : values) {
+			if (validElement.toString().equalsIgnoreCase(elmName.trim())) {
+				isValidEmpty = true;
+				break;
+			}
+			continue;
+		}
+		return isValidEmpty;
+	}
+/**
+ * 
+ * @param chldelement
+ */
+	public void addChild(XmlElement chldelement) {
+
+		if (isParent(xmlStackElements.lastElement().getName())) {
+			xmlStackElements.lastElement().addChild(chldelement);
+
+		} else {
+			// a close element name which not matches with the last element in
+			// the stack.
+
+			String msgkey = null;
+			Message msg = null;
+			msgkey = "xml.element.not.closed";
+			msg = new Message();
+			msg.setMessageSource(IWRTConstants.VALIDATOR);
+			msg.setLineNumber(xmlStackElements.lastElement().getLineNo());
+			msg.setTargetObject(targetFileName);
+			msg.setMessageKey(msgkey);
+			msg.setMessage(ValidatorPropMessages.getString(msgkey) + "     '"
+					+ xmlStackElements.lastElement().getName()+"'");
+			msg.setSeverity(IWRTConstants.ERROR);
+			xmlStackElements.lastElement().addError(msg);
+//			showData("------------------- adding msg  addChild : "	+ chldelement.getName() + "    " + msgkey);
+			xmlStackElements.pop();
+			addChild(chldelement);
+
+		}
+
+	}
+/**
+ * 
+ * @param rootXmlElement
+ * @return
+ */
+	private boolean validateElement(String rootXmlElement) {
+		log.info("validateElement >>--->>");
+		plistElements[] values = plistElements.values();
+		boolean isValidElement = false;
+		for (plistElements validElement : values) {
+			if (validElement.toString().equalsIgnoreCase(rootXmlElement.trim())) {
+				isValidElement = true;
+				break;
+
+			}
+			continue;
+		}
+		log.info("validateElement <<---<<");
+		return isValidElement;
+	}
+	
+	private void Replace(String fname, String oldPattern, String replPattern){
+		String line;
+		StringBuffer sb = new StringBuffer();
+		try {
+			FileInputStream fis = new FileInputStream(fname);
+			BufferedReader reader=new BufferedReader ( new InputStreamReader(fis));
+			while((line = reader.readLine()) != null) {
+				line = line.replaceAll(oldPattern, replPattern);
+				sb.append(line+"\n");
+			}
+			reader.close();
+			BufferedWriter out=new BufferedWriter ( new FileWriter(fname));
+			out.write(sb.toString());
+			out.close();
+		}
+		catch (Throwable e) {
+		            System.err.println("*** exception ***");
+		}
+	}
+	private void ReplaceMiniViewEnabled(String fname, String oldPattern, String replPattern){
+		try {
+			String line;
+			boolean miniViewEnableTurn = false;
+			StringBuffer sb = new StringBuffer();
+			FileInputStream fis = new FileInputStream(fname);
+			BufferedReader reader=new BufferedReader ( new InputStreamReader(fis));
+			while((line = reader.readLine()) != null) {
+				if(!miniViewEnableTurn){
+					sb.append(line+"\n");
+				}
+				else if(miniViewEnableTurn){
+					line = line.replace(oldPattern, replPattern);
+					sb.append(line+"\n");
+					miniViewEnableTurn = false;
+				}
+				if(line.indexOf("MiniViewEnabled")> 0){
+					miniViewEnableTurn = true;
+				}
+			}
+			reader.close();
+			BufferedWriter out=new BufferedWriter ( new FileWriter(fname.toString()));
+			out.write(sb.toString());
+			out.close();
+		}
+		catch (Throwable e) {
+	            System.err.println("*** exception ***");
+	    }	
+	}
+
+	public void updateKeyValueInPlist(String newWidegtName,String newWidgetID,File widgetPath, File location, String homeScreenValue){
+		boolean isHomeScreenWidget = false;
+		WidgetModel widgetModel = new WidgetModel();
+		try {
+			widgetModel.getWidgetModelForWizard(widgetPath);			
+		} catch (ValidationException e) {
+			e.printStackTrace();
+		}
+	    File pList = new File(location.toString() + File.separator + widgetModel.getPlistFileName());
+	    
+		XmlElement rootXml;
+		try {
+			rootXml = parseXML(pList);
+			if (rootXml!=null&&rootXml.getChildList()!=null&&rootXml.getChildList().size() == 1) {
+				XmlElement dict = rootXml.getChildList().get(0);
+				XmlElement key = null;
+				if (dict.getChildList().size() > 1) {
+					for (XmlElement elm : dict.getChildList()) {	
+							
+						if (elm.getName().trim().equalsIgnoreCase("String")) {
+							if (key != null && key.getValue() != null) {												        
+								if (key.getValue().trim().equalsIgnoreCase(	"DisplayName")&& !(widgetModel.getDisplayname().equalsIgnoreCase(newWidegtName))) {
+									Replace(pList.toString(),">"+elm.getValue(), ">"+newWidegtName);
+								}
+								if (key.getValue().trim().equalsIgnoreCase(	"Identifier")&& !(widgetModel.getIdentifier().equalsIgnoreCase(newWidgetID))) {
+									Replace(pList.toString(),">"+elm.getValue(), ">"+newWidgetID);
+								}
+								key = null;
+							}
+						} 
+						else if (elm.getName().trim().equalsIgnoreCase("key")) {
+							key = elm;
+							if (key.getValue().trim().equalsIgnoreCase(	"MiniViewEnabled")) {
+								isHomeScreenWidget = true;							
+							}
+						}
+						else{
+							if(isHomeScreenWidget){
+								Boolean h1 = new Boolean(widgetModel.getHomeScreenValue());
+								Boolean h2 = new Boolean(homeScreenValue);
+								isHomeScreenEnabled = new Boolean(elm.getName());
+								if(!(h1.equals(h2))){
+								widgetModel.setHomeScreenValue(new Boolean(homeScreenValue));
+								ReplaceMiniViewEnabled(pList.toString(),elm.getName(), homeScreenValue);
+								isHomeScreenWidget = false;
+								}
+							}
+						}
+					}
+				}
+			}
+		} catch (IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	}
+	
+	
+/**
+ * 
+ * @param elmName
+ * @return
+ */
+	private boolean closeElementInStack(String elmName) {
+		log.info("closeElementInStack >>--->>");
+		boolean elementPresent = false;
+//		showData("------------------- xmlStackElements size: "		+ xmlStackElements.size());
+
+		for (int i = 0; i < xmlStackElements.size(); i++) {
+//			showData("------------------- xmlStackElements.get(i).getName() : "		+ xmlStackElements.get(i).getName());
+
+			if (xmlStackElements.get(i).getName().equalsIgnoreCase(elmName)) {
+				elementPresent = true;
+//				break;
+			}
+
+		}
+//		showData("------------------- elementPresent : " + elementPresent	+ "    " + elmName);
+//		showData("------------------- xmlStackElements is empty : "	+ xmlStackElements.isEmpty());
+
+		log.info("closeElementInStack <<---<<");
+		return elementPresent;
+	}
+	
+	
+	
+	/**
+	 * 
+	 * @param args
+	 */
+		public static void main(String[] args) {
+			try {
+				XMLPlistParser xparser = new XMLPlistParser();
+				// xparser.messageHandler = new MessageHandler();
+				// xparser.messageHandler.registerListener(xparser.new
+				// MessageListener());
+				// String fileName = "C:/Documents and
+				// Settings/sduvvuri/Desktop/Validator/Info.plist";
+				String fileName = "d:/test/abc/info.plist";
+				XmlElement rootXml = xparser.parseXML(new File(fileName));
+				showData("getName  " + rootXml.getName());
+				showData("getXmlDeclaration  " + rootXml.getXmlDeclaration());
+				showData("getDocType  " + rootXml.getDocType());
+				showData("child size  " + rootXml.getChildList().size());
+				if (rootXml != null) {
+					for (XmlElement elm : rootXml.getChildList()) {
+
+						xparser.getNameAndValue(elm);
+
+					}
+				}
+			} catch (Exception e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+
+		}
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/core/parser/XmlElement.java	Wed Jan 27 15:05:37 2010 -0800
@@ -0,0 +1,192 @@
+/**
+ * Copyright (c) 2009 Symbian Foundation and/or its subsidiary(-ies).
+ * All rights reserved.
+ * This component and the accompanying materials are made available
+ * under the terms of the License "Eclipse Public License v1.0"
+ * which accompanies this distribution, and is available
+ * at the URL "http://www.eclipse.org/legal/epl-v10.html".
+ *
+ * Initial Contributors:
+ * Symbian Foundation - initial contribution.
+ * Contributors:
+ * Description:
+ * Overview:
+ * Details:
+ * Platforms/Drives/Compatibility:
+ * Assumptions/Requirement/Pre-requisites:
+ * Failures and causes:
+ */
+
+package org.symbian.tools.wrttools.core.parser;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.symbian.tools.wrttools.core.report.Message;
+
+public class XmlElement {
+
+	/**
+	 * @param args
+	 */
+	public enum nodeTypes{
+		root, parent, child
+	};
+	private String xmlDeclaration  ;
+	private String docType  ;
+
+	private String nodeType;
+	private String name;
+	private boolean empty;
+	private String value;
+	private List<Attribute> attrList;
+	private List<Message> errorList;
+	private List<XmlElement> childList= new ArrayList<XmlElement>();
+	private int lineNo  ;
+	
+
+
+
+//-------------only for root node--------------------//
+
+
+	public int getLineNo() {
+		return lineNo;
+	}
+
+	public void setLineNo(int lineNo) {
+		this.lineNo = lineNo;
+	}
+
+	public String getXmlDeclaration() {
+		return xmlDeclaration;
+	}
+
+	public void setXmlDeclaration(String xmlDeclaration) {
+		this.xmlDeclaration = xmlDeclaration;
+	}
+
+	public String getDocType() {
+		return docType;
+	}
+
+
+	public void setDocType(String docType) {
+		this.docType = docType;
+	}
+	
+	//-------------only for root node--------------------//
+
+	
+	
+
+
+	public String getNodeType() {
+		return nodeType;
+	}
+
+
+	public void setNodeType(String nodeType) {
+		this.nodeType = nodeType;
+	}
+
+
+	public String getName() {
+		return name;
+	}
+
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+
+	public boolean isEmpty() {
+		return empty;
+	}
+
+
+	public void setEmpty(boolean empty) {
+		this.empty = empty;
+	}
+
+
+	public String getValue() {
+		return value;
+	}
+
+
+	public void setValue(String value) {
+		this.value = value;
+	}
+
+
+	public List<Attribute> getAttrList() {
+
+		return attrList;
+	}
+
+
+	public void setAttrList(List attrList) {
+		this.attrList = attrList;
+	}
+	
+	public void addAttribute(Attribute attr) {
+		if(attrList==null)
+		{
+			attrList = new ArrayList<Attribute>();
+		}
+		attrList.add(attr);
+	}
+	
+	public void addError(Message msg) {
+		if(errorList==null)
+		{
+			errorList = new ArrayList<Message>();
+		}
+		errorList.add(msg);
+	}
+	public List<Message> getErrorList() {
+		return errorList;
+	}
+
+	public void setErrorList(List<Message> errorList) {
+		this.errorList = errorList;
+	}
+		
+	public List<XmlElement> getChildList() {
+		return childList;
+	}
+
+
+	public void setChildList(List<XmlElement> childList) {
+		this.childList = childList;
+	}
+	public void addChild(XmlElement child) {
+		if(childList==null)
+		{
+			childList = new ArrayList<XmlElement>();
+		}
+		childList.add(child);
+	}
+public class Attribute  {
+    
+	private String key;
+	private String value;
+	public String getKey() {
+		return key;
+	}
+	public void setKey(String key) {
+		this.key = key;
+	}
+	public String getValue() {
+		return value;
+	}
+	public void setValue(String value) {
+		this.value = value;
+	}
+}
+
+	
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/core/report/IMessageListener.java	Wed Jan 27 15:05:37 2010 -0800
@@ -0,0 +1,31 @@
+/* ============================================================================
+ * Copyright © 2008 Nokia. All rights reserved.
+ * This material, including documentation and any related computer
+ * programs, is protected by copyright controlled by Nokia. All
+ * rights are reserved. Copying, including reproducing, storing,
+ * adapting or translating, any or all of this material requires the
+ * prior written consent of Nokia. This material also contains
+ * confidential information which may not be disclosed to others
+ * without the prior written consent of Nokia.
+ * ============================================================================*/
+
+package org.symbian.tools.wrttools.core.report;
+
+public interface IMessageListener {
+	/**
+	 * Tell if the Message should be listened by this listener,
+	 * usually true for a solitary listener.  It would return false,
+	 * e.g., if several listeners are attached and each has a particular 
+	 * scope for status, and the given status doesn't match
+	 * this listener's scope. 
+	 */
+	public boolean isMessageHandled(Message message);
+	
+    /**
+     * publish  a message  this message should be handles by the client class
+     * default way is to add to a list and pass the list to the report handler to 
+     * generate report.
+     * @param status
+     */
+    public void receiveMessage(Message message);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/core/report/Message.java	Wed Jan 27 15:05:37 2010 -0800
@@ -0,0 +1,155 @@
+/**
+ * Copyright (c) 2009 Symbian Foundation and/or its subsidiary(-ies).
+ * All rights reserved.
+ * This component and the accompanying materials are made available
+ * under the terms of the License "Eclipse Public License v1.0"
+ * which accompanies this distribution, and is available
+ * at the URL "http://www.eclipse.org/legal/epl-v10.html".
+ *
+ * Initial Contributors:
+ * Symbian Foundation - initial contribution.
+ * Contributors:
+ * Description:
+ * Overview:
+ * Details:
+ * Platforms/Drives/Compatibility:
+ * Assumptions/Requirement/Pre-requisites:
+ * Failures and causes:
+ */
+
+package org.symbian.tools.wrttools.core.report;
+
+public class Message {
+
+	/**
+	 * The name of the resource bundle category which contains the string. (A
+	 * resource bundle category identifies the base name of the .properties
+	 * file, e.g. "mymessages.properties", "mymessages_en_US.properties" both
+	 * have the same resource bundle category: "mymessages"
+	 * 
+	 */
+	private String bundle;
+	/**
+	 * The id of the message in the resource bundle; used to extract the message
+	 * from the bundle.
+	 */
+	private String messageKey;
+
+	/**
+	 * If the message applies to a particular object (e.g. a plist,html
+	 * css,javascript), this parameter identifies the object. Otherwise, this
+	 * value is null.
+	 */
+	private String targetObject;
+
+	// Identifies the severity of the message. This flag's value is one of the
+	// widget constants.
+
+	private String severity;
+
+	private String message;
+
+	/**
+	 * when a message is created
+	 */
+	private int messageSource;
+
+	private int lineNumber;
+
+	private String fullPath;
+	
+	private String fileName;
+
+	private boolean fileTypeZip = false;
+	private String recommendAction;
+
+	public String getBundle() {
+		return bundle;
+	}
+
+	public void setBundle(String bundle) {
+		this.bundle = bundle;
+	}
+
+	public String getTargetObject() {
+		return targetObject;
+	}
+
+	public void setTargetObject(String targetObject) {
+		this.targetObject = targetObject;
+	}
+
+	public String getSeverity() {
+		return severity;
+	}
+
+	public void setSeverity(String _severity) {
+		severity = _severity;
+	}
+
+	public String getMessage() {
+		return message;
+	}
+
+	public void setMessage(String _message) {
+		message = _message;
+	}
+
+	public String getMessageKey() {
+		return messageKey;
+	}
+
+	public void setMessageKey(String _messageKey) {
+
+		messageKey = _messageKey;
+	}
+
+	public int getMessageSource() {
+		return messageSource;
+	}
+
+	public void setMessageSource(int _module) {
+		messageSource = _module;
+	}
+
+	public int getLineNumber() {
+		return lineNumber;
+	}
+
+	public void setLineNumber(int lineNumber) {
+		this.lineNumber = lineNumber;
+	}
+
+	public String getFullPath() {
+		return fullPath;
+	}
+
+	public void setFullPath(String fullPath) {
+		this.fullPath = fullPath;
+	}
+
+	public boolean isFileTypeZip() {
+		return fileTypeZip;
+	}
+
+	public void setFileTypeZip(boolean fileTypeZip) {
+		this.fileTypeZip = fileTypeZip;
+	}
+
+	public String getRecommendAction() {
+		return recommendAction;
+	}
+
+	public void setRecommendAction(String recommendAction) {
+		this.recommendAction = recommendAction;
+	}
+
+	public String getFileName() {
+		return fileName;
+	}
+
+	public void setFileName(String fileName) {
+		this.fileName = fileName;
+	}
+	
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/core/report/MessageHandler.java	Wed Jan 27 15:05:37 2010 -0800
@@ -0,0 +1,90 @@
+/**
+ * Copyright (c) 2009 Symbian Foundation and/or its subsidiary(-ies).
+ * All rights reserved.
+ * This component and the accompanying materials are made available
+ * under the terms of the License "Eclipse Public License v1.0"
+ * which accompanies this distribution, and is available
+ * at the URL "http://www.eclipse.org/legal/epl-v10.html".
+ *
+ * Initial Contributors:
+ * Symbian Foundation - initial contribution.
+ * Contributors:
+ * Description:
+ * Overview:
+ * Details:
+ * Platforms/Drives/Compatibility:
+ * Assumptions/Requirement/Pre-requisites:
+ * Failures and causes:
+ */
+
+package org.symbian.tools.wrttools.core.report;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.logging.Logger;
+
+/**
+ * Message Handler contains list of Listener. It publish all the messages generated 
+ * to all the registered listeners. 
+ *   
+ * @author Sailaja Duvvuri
+ */
+
+public class MessageHandler {
+
+	private Logger log = Logger.getLogger(getClass().getName());
+	private boolean fileTypeZip = false;
+
+	public boolean isFileTypeZip() {
+		return fileTypeZip;
+	}
+
+	public void setFileTypeZip(boolean fileTypeZip) {
+		this.fileTypeZip = fileTypeZip;
+	}
+	
+	  /**
+     * The list of listeners added to the message handler.
+     */
+    private List<IMessageListener> listeners = new ArrayList<IMessageListener>();
+
+    /**
+     * Register the message listener to the handler. 
+     * @param messageListener the listener which is added to the handler
+     */
+    public void registerListener(IMessageListener messageListener) {
+        listeners.add(messageListener);
+    }
+    
+    /**
+     * Removes the message listener from the handler list.
+     * @param messageListener the listener which needs to be removed from the handler.
+     */
+    public void removeListener(IMessageListener messageListener) {
+        listeners.remove(messageListener);
+    }
+        
+    /**
+     * Publish  the message from the listener.
+     * Message needs to be handled in the client side .
+     * @param message The message  needs to be handled.
+     */
+    public void publishMessage(Message message) {
+       for (Iterator<IMessageListener> iter = listeners.iterator(); iter.hasNext();) {
+    	   IMessageListener messageListener = (IMessageListener) iter.next();
+           if (messageListener.isMessageHandled(message)) {
+        	   messageListener.receiveMessage(message);
+
+           }
+       }
+    }
+
+    /**
+     * Resets the existing message listeners.
+     */
+    public void reset() {
+        listeners.clear();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/core/status/IWRTConstants.java	Wed Jan 27 15:05:37 2010 -0800
@@ -0,0 +1,95 @@
+/**
+ * Copyright (c) 2009 Symbian Foundation and/or its subsidiary(-ies).
+ * All rights reserved.
+ * This component and the accompanying materials are made available
+ * under the terms of the License "Eclipse Public License v1.0"
+ * which accompanies this distribution, and is available
+ * at the URL "http://www.eclipse.org/legal/epl-v10.html".
+ *
+ * Initial Contributors:
+ * Symbian Foundation - initial contribution.
+ * Contributors:
+ * Description:
+ * Overview:
+ * Details:
+ * Platforms/Drives/Compatibility:
+ * Assumptions/Requirement/Pre-requisites:
+ * Failures and causes:
+ */
+
+package org.symbian.tools.wrttools.core.status;
+
+public interface IWRTConstants {
+	
+	public enum StatusSourceType {
+		VALIDATOR("IWRTConstants.validator"), //$NON-NLS-1$
+		PACKAGER("IWRTConstants.packager"),  //$NON-NLS-1$
+		DEPLOYER("IWRTConstants.deployer"), //$NON-NLS-1$
+		CONVERTER("IWRTConstants.converter"), //$NON-NLS-1$
+		CONVERTER_TODO("IWRTConstants.converter_todo");//$NON-NLS-1$
+
+		
+		private String name;
+		StatusSourceType(String nameKey) {
+			this.name = Messages.getString(nameKey);
+		}
+		public String getName() {
+			return name;
+		}
+	};
+	
+
+	public static final int  VALIDATOR=50;
+	public static final int  CONVERTOR=60;
+	public static final int CONVERTOR_TODO = 65;
+	public static final int  DEPLOYER=70;
+	public static final int  PACKAGER=80;
+	public static final int  ADDPROJECT=90;
+
+	public static final String  IMAGE_REF="IMAGE-REF:|";
+	
+	//Report severity type
+	public static final String  WARN = Messages.getString("IWRTConstants.report.warning");
+	public static final String  ERROR = Messages.getString("IWRTConstants.report.error");
+	public static final String  FATAL = Messages.getString("IWRTConstants.report.fatal");
+	public static final String  INFO = Messages.getString("IWRTConstants.report.information");
+	public static final String  SUCCESS = Messages.getString("IWRTConstants.report.success");
+	public static final String  MANDATORY = Messages.getString("IWRTConstants.report.mandatory");
+	public static final String  OPTIONAL = Messages.getString("IWRTConstants.report.optional");
+	
+	public static final int  MESSAGE_LIMIT=50;
+	public static final int  VALIDATOR_MESSAGE_LIMIT=15;
+	public static final int  CONVERTOR_MESSAGE_LIMIT=15;
+	public static final int  DEPLOYER_MESSAGE_LIMIT=15;
+	public static final int  PACKAGER_MESSAGE_LIMIT=15;
+	
+	public static final String	PROPERTIES_DIR="bin"; //$NON-NLS-1$
+	
+	public static final String WIDGET_FILE_EXTENSION = ".wgz"; //$NON-NLS-1$
+	
+	public static final String OS = System.getProperty("os.name"); //$NON-NLS-1$
+	
+	public static final String MAC_OS="Mac OS X"; //$NON-NLS-1$
+	
+	/**
+	 * Locally stored Nokia DTD
+	 */
+	public static String NOKIA_PLIST_DTD = "/com/nokia/wrt/core/widgetmodel/plist-1.0.dtd";
+	/**
+	 * Locally stored Apple DTD
+	 */
+	public static String APPLE_PLIST_DTD = "/com/nokia/wrt/core/converter/PropertyList-1.0.dtd";
+	/**
+	 * Nokia DTD in nfo.plist file 
+	 */
+	public static String NOKIA_DTD_SYS_ID = "http://www.nokia.com/DTDs/plist-1.0.dtd";
+	public static String NOKIA_DTD_PUBLIC_ID = "-//Nokia//DTD PLIST 1.0//EN";
+	/**
+	 * Apple DTD in info.plist file
+	 */
+	public static String APPLE_DTD_SYS_ID = "http://www.apple.com/DTDs/PropertyList-1.0.dtd";
+	public static String APPLE_DTD_PUBLIC_ID = "-//Apple Computer//DTD PLIST 1.0//EN";
+	
+	
+	
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/core/status/IWRTStatusListener.java	Wed Jan 27 15:05:37 2010 -0800
@@ -0,0 +1,37 @@
+/**
+ * Copyright (c) 2009 Symbian Foundation and/or its subsidiary(-ies).
+ * All rights reserved.
+ * This component and the accompanying materials are made available
+ * under the terms of the License "Eclipse Public License v1.0"
+ * which accompanies this distribution, and is available
+ * at the URL "http://www.eclipse.org/legal/epl-v10.html".
+ *
+ * Initial Contributors:
+ * Symbian Foundation - initial contribution.
+ * Contributors:
+ * Description:
+ * Overview:
+ * Details:
+ * Platforms/Drives/Compatibility:
+ * Assumptions/Requirement/Pre-requisites:
+ * Failures and causes:
+ */
+
+package org.symbian.tools.wrttools.core.status;
+
+public interface IWRTStatusListener {
+	/**
+	 * Tell if the status should be emitted by this listener,
+	 * usually true for a solitary listener.  It would return false,
+	 * e.g., if several listeners are attached and each has a particular 
+	 * scope for status, and the given status doesn't match
+	 * this listener's scope. 
+	 */
+	public boolean isStatusHandled(WRTStatus status);
+	
+    /**
+     * Emit a status if #isStatusHandled() returned true.
+     * @param status
+     */
+    public void emitStatus(WRTStatus status);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/core/status/Messages.java	Wed Jan 27 15:05:37 2010 -0800
@@ -0,0 +1,41 @@
+/**
+ * Copyright (c) 2009 Symbian Foundation and/or its subsidiary(-ies).
+ * All rights reserved.
+ * This component and the accompanying materials are made available
+ * under the terms of the License "Eclipse Public License v1.0"
+ * which accompanies this distribution, and is available
+ * at the URL "http://www.eclipse.org/legal/epl-v10.html".
+ *
+ * Initial Contributors:
+ * Symbian Foundation - initial contribution.
+ * Contributors:
+ * Description:
+ * Overview:
+ * Details:
+ * Platforms/Drives/Compatibility:
+ * Assumptions/Requirement/Pre-requisites:
+ * Failures and causes:
+ */
+
+package org.symbian.tools.wrttools.core.status;
+
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+public class Messages {
+	private static final String BUNDLE_NAME = "com.nokia.wrt.core.status.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 + '!';
+		}
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/core/status/WRTStatus.java	Wed Jan 27 15:05:37 2010 -0800
@@ -0,0 +1,88 @@
+/**
+ * Copyright (c) 2009 Symbian Foundation and/or its subsidiary(-ies).
+ * All rights reserved.
+ * This component and the accompanying materials are made available
+ * under the terms of the License "Eclipse Public License v1.0"
+ * which accompanies this distribution, and is available
+ * at the URL "http://www.eclipse.org/legal/epl-v10.html".
+ *
+ * Initial Contributors:
+ * Symbian Foundation - initial contribution.
+ * Contributors:
+ * Description:
+ * Overview:
+ * Details:
+ * Platforms/Drives/Compatibility:
+ * Assumptions/Requirement/Pre-requisites:
+ * Failures and causes:
+ */
+
+package org.symbian.tools.wrttools.core.status;
+
+/**
+ * The main class for the WRT status raiser.This is defined the status which can be raised
+ * from various sources e.g validator, packager or deployer . The status contains the 
+ * source from it was raised and the corresponding description about the status which is
+ * like some information.
+ * 
+ * @author avraina
+ * 
+ */
+public class WRTStatus {
+	/**
+	 * The source of the status, e.g. validator , packaging or deployer.
+	 */
+	private String statusSource;
+	/**
+	 * Status description.
+	 */
+	private String statusDescription;
+	
+	/**
+	 * Default Constructor.
+	 */
+	public WRTStatus(){
+		
+	}
+
+	/**
+	 * Create a new <code>WRTStatus</code> object.
+	 * @param statusSource The source of the status. E.g. validator, deployer or packaging.
+	 * @param statusDescription The status description.
+	 */
+	public WRTStatus(final String statusSource, final String statusDescription) {
+		setStatusSource(statusSource);
+		setStatusDescription(statusDescription);
+	}
+	/**
+	 * Returns the source of the status.The source can be validator, deployer or packaging etc.
+	 * @return the statusSource
+	 */
+	public String getStatusSource() {
+		return statusSource;
+	}
+
+	/**
+	 * Sets the source of the status.Source can be from the status is to be emitted.
+	 * @param source the statusSource to set
+	 */
+	public void setStatusSource(String source) {
+		statusSource = source;
+	}
+
+	/**
+	 * Returns the status description. This the information which status needs to emit.
+	 * @return the statusDescription the description of the source.
+	 */
+	public Object getStatusDescription() {
+		return statusDescription;
+	}
+
+	/**
+	 * Set the description for the status.This is the information which status will emit.
+	 * @param subject the statusDescription to set
+	 */
+	public void setStatusDescription(String information) {
+		statusDescription = information;
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/core/status/WRTStatusHandler.java	Wed Jan 27 15:05:37 2010 -0800
@@ -0,0 +1,75 @@
+/**
+ * Copyright (c) 2009 Symbian Foundation and/or its subsidiary(-ies).
+ * All rights reserved.
+ * This component and the accompanying materials are made available
+ * under the terms of the License "Eclipse Public License v1.0"
+ * which accompanies this distribution, and is available
+ * at the URL "http://www.eclipse.org/legal/epl-v10.html".
+ *
+ * Initial Contributors:
+ * Symbian Foundation - initial contribution.
+ * Contributors:
+ * Description:
+ * Overview:
+ * Details:
+ * Platforms/Drives/Compatibility:
+ * Assumptions/Requirement/Pre-requisites:
+ * Failures and causes:
+ */
+
+package org.symbian.tools.wrttools.core.status;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+public class WRTStatusHandler {
+
+    /**
+     * The list of listeners added to the status handler.
+     */
+    private List<IWRTStatusListener> listeners = new ArrayList<IWRTStatusListener>();
+    
+    /**
+     * Constructor
+     */
+    public WRTStatusHandler() {
+    }
+
+    /**
+     * Adds the status listener to the handler. 
+     * @param statusListener the listener which is added to the handler
+     */
+    public void addListener(IWRTStatusListener statusListener) {
+        listeners.add(statusListener);
+    }
+    
+    /**
+     * Removes the status listener from the handler list.
+     * @param statusListener the listener which needs to be removed from the handler.
+     */
+    public void removeListener(IWRTStatusListener statusListener) {
+        listeners.remove(statusListener);
+    }
+        
+    /**
+     * Emit the status . This will basically emit the status from the listener.
+     * If the status needs to be handled it will be emitted else nothing will happen.
+     * @param status The status which needs to be handled.
+     */
+    public void emitStatus(WRTStatus status) {
+       for (Iterator<IWRTStatusListener> iter = listeners.iterator(); iter.hasNext();) {
+           IWRTStatusListener statusListener = (IWRTStatusListener) iter.next();
+           if (statusListener.isStatusHandled(status)) {
+        	   statusListener.emitStatus(status);
+           }
+       }
+    }
+
+    /**
+     * Resets the existing status listeners.
+     */
+    public void reset() {
+        listeners.clear();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/core/validator/HtmlValidator.java	Wed Jan 27 15:05:37 2010 -0800
@@ -0,0 +1,259 @@
+/**
+ * Copyright (c) 2009 Symbian Foundation and/or its subsidiary(-ies).
+ * All rights reserved.
+ * This component and the accompanying materials are made available
+ * under the terms of the License "Eclipse Public License v1.0"
+ * which accompanies this distribution, and is available
+ * at the URL "http://www.eclipse.org/legal/epl-v10.html".
+ *
+ * Initial Contributors:
+ * Symbian Foundation - initial contribution.
+ * Contributors:
+ * Description:
+ * Overview:
+ * Details:
+ * Platforms/Drives/Compatibility:
+ * Assumptions/Requirement/Pre-requisites:
+ * Failures and causes:
+ */
+
+package org.symbian.tools.wrttools.core.validator;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.text.MessageFormat;
+import java.util.List;
+import java.util.Stack;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.w3c.tidy.Node;
+import org.w3c.tidy.Tidy;
+import org.w3c.tidy.TidyMessage;
+import org.w3c.tidy.TidyMessageListener;
+
+import org.symbian.tools.wrttools.core.report.Message;
+import org.symbian.tools.wrttools.core.report.MessageHandler;
+import org.symbian.tools.wrttools.core.status.IWRTConstants;
+import org.symbian.tools.wrttools.core.widgetmodel.WidgetModel;
+import org.symbian.tools.wrttools.util.FileUtil;
+import org.symbian.tools.wrttools.util.Util;
+
+/**
+* Html Validator
+* Accepts the MessageManager .
+* Accept File projDir.
+* Use xmlParser to get all elements in a stack.
+* Call rule methods() passing the MessageManager and the stack of elements.
+*
+* @author Sailaja duvvuri
+*/
+public class HtmlValidator implements IValidator {
+    boolean htmlValidationStaus;
+    private String htmlFileName=null;
+    private String htmlPlistFileName=null;
+    private File htmlFile=null;
+    private Logger log = Logger.getLogger(getClass().getName());
+    private MessageHandler messageHandler;
+    private WidgetModel widgetModel;
+    private boolean allRulesPassed;
+    
+    
+
+	public WidgetModel getWidgetModel() {
+		return widgetModel;
+	}
+
+	public void setWidgetModel(WidgetModel widgetModel) {
+		this.widgetModel = widgetModel;
+	}
+	
+
+	public MessageHandler getMessageHandler() {
+		return messageHandler;
+	}
+
+
+	public void setMessageHandler(MessageHandler messageHandler) {
+		this.messageHandler = messageHandler;
+	}
+    
+	public boolean validate( File projDir) {
+	
+			Stack<String> htmlElements = null;
+		FileUtil fileUtil = new FileUtil();
+		List<File> dirList = fileUtil.getCurrDirFiles(projDir);
+		htmlFileName=widgetModel.getMainHtml();
+
+		 try {
+			
+				htmlFile = fileUtil.getFile(dirList, htmlFileName);
+			
+			if (htmlFile != null){
+				htmlFileName = htmlFile.getName();
+			if (widgetModel.getHtmlXmlFile()!=null) {
+					checkWellformed(htmlFile,true);
+					for(int i=0;i<widgetModel.getReferencedHtmlFiles().size();i++){
+						File refHtmlFile=new File(widgetModel.widgetDirectory+widgetModel.widgetName+"/"+widgetModel.getReferencedHtmlFiles().get(i));
+						if(refHtmlFile!=null)
+						checkWellformed(refHtmlFile,true);
+					}
+					for(int i=0;i<widgetModel.getReferencedCssFiles().size();i++){
+						File refHtmlFile=new File(widgetModel.widgetDirectory+widgetModel.widgetName+"/"+widgetModel.getReferencedCssFiles().get(i));
+						if(refHtmlFile!=null)
+						checkWellformed(refHtmlFile,false);
+					}
+					for(int i=0;i<widgetModel.getReferencedJavaScriptFiles().size();i++){
+						File refHtmlFile=new File(widgetModel.widgetDirectory+widgetModel.widgetName+"/"+widgetModel.getReferencedJavaScriptFiles().get(i));
+						if(refHtmlFile!=null)
+						checkWellformed(refHtmlFile,false);
+					}	
+					for(int i=0;i<widgetModel.getReferencedImageFiles().size();i++){
+						File refHtmlFile=new File(widgetModel.widgetDirectory+widgetModel.widgetName+"/"+widgetModel.getReferencedImageFiles().get(i));
+						if(refHtmlFile!=null)
+						checkWellformed(refHtmlFile,false);
+					}	
+					for(int i=0;i<widgetModel.getReferencedIFrameFiles().size();i++){
+						File refHtmlFile=new File(widgetModel.widgetDirectory+widgetModel.widgetName+"/"+widgetModel.getReferencedIFrameFiles().get(i));
+						if(refHtmlFile!=null)
+						checkWellformed(refHtmlFile,false);
+					}	
+					for(int i=0;i<widgetModel.getReferencedEmbedFiles().size();i++){
+						File refHtmlFile=new File(widgetModel.widgetDirectory+widgetModel.widgetName+"/"+widgetModel.getReferencedEmbedFiles().get(i));
+						if(refHtmlFile!=null)
+						checkWellformed(refHtmlFile,false);
+					}	
+				
+			} else {
+				Message msg = new Message();
+				msg.setMessageSource(IWRTConstants.VALIDATOR);
+				msg.setMessageKey("no.html.element");
+				msg.setMessage(ValidatorPropMessages.getString("no.html.element"));
+				msg.setFileTypeZip(messageHandler.isFileTypeZip());
+				msg.setTargetObject(htmlFileName);
+				msg.setFullPath(htmlFile.getAbsolutePath());
+				msg.setSeverity(IWRTConstants.ERROR);
+				msg.setRecommendAction(ValidatorPropMessages.getString("todo.no.html.element"));
+				messageHandler.publishMessage(msg);
+				allRulesPassed = false;
+
+			}
+		 }else{
+			 Message msg = new Message();
+				msg.setMessageSource(IWRTConstants.VALIDATOR);
+				msg.setMessage(ValidatorPropMessages.getString("html.File.Not.Present"));
+				msg.setFileTypeZip(messageHandler.isFileTypeZip());
+				msg.setSeverity(IWRTConstants.FATAL);
+				messageHandler.publishMessage(msg);
+		 }
+
+		} catch (Exception e) {
+
+			Util.logEvent(log, Level.SEVERE, e);
+			Message msg = new Message();
+			msg.setMessageSource(IWRTConstants.VALIDATOR);
+			msg.setMessageKey("html.File.Not.Present");
+			
+			msg.setMessage(ValidatorPropMessages.getString("html.File.Not.Present"));
+			msg.setFileTypeZip(messageHandler.isFileTypeZip());
+			msg.setSeverity(IWRTConstants.FATAL);
+			messageHandler.publishMessage(msg);
+		}
+
+		log.info("validate<<---<<");
+
+		return allRulesPassed;
+	}
+
+	public String getHtmlPlistFileName() {
+		return htmlPlistFileName;
+	}
+
+
+
+	public void setHtmlPlistFileName(String htmlPlistFileName) {
+		this.htmlPlistFileName = htmlPlistFileName;
+	}
+	//---------------------------------code for Jtidy--------------------------------------->>
+  private boolean checkWellformed(File htmlfile, boolean isParsingNeeded) {
+	  String userDir = System.getProperty("user.dir");
+	  String outputFile = userDir+ "/tidy.html";
+	  //htmlfile will behave as directory when src field in html is blank (src =""), so skipping that.
+	  if(htmlfile.isDirectory()){
+		  return true;
+	  }
+      InputStream inStream;
+      try {
+		inStream = new FileInputStream(htmlfile);
+		OutputStream outStream = new FileOutputStream(outputFile);
+		//Parsing here is required only for html, coz js, css files cannot have reference files.
+		//fixing bug 742
+		if(isParsingNeeded){
+		  Tidy jtidy = new Tidy();
+		  TMessageListener msglis= new TMessageListener();
+		  jtidy.setMessageListener(msglis);	  
+		  Node xmlDocument = jtidy.parse(inStream, outStream);
+		}
+		  inStream.close();
+      } catch (FileNotFoundException e) {
+		Message msg = new Message();
+		msg.setMessageSource(IWRTConstants.VALIDATOR);
+		msg.setMessageKey("no.element");
+		msg.setMessage(htmlfile.getName()+ " referred in main html" + " could not be found");
+		msg.setFileTypeZip(messageHandler.isFileTypeZip());
+		msg.setTargetObject(htmlfile.toString());
+		msg.setFullPath(htmlfile.getAbsolutePath());
+		msg.setSeverity(IWRTConstants.WARN);
+		msg.setRecommendAction(ValidatorPropMessages.getString("todo.no.html.element"));
+		messageHandler.publishMessage(msg);
+		Util.logEvent(log, Level.SEVERE, e);			
+		log.severe(e.getMessage());
+	} catch (IOException e) {
+		 Util.logEvent(log, Level.SEVERE, e);			
+			log.severe(e.getMessage());
+	}
+	return false;
+}
+	
+	public class TMessageListener implements TidyMessageListener {
+
+		public void messageReceived(TidyMessage tdyMsg) {
+			
+			if (tdyMsg.getLevel().equals(TidyMessage.Level.ERROR)) {
+				log.info("line     :" + tdyMsg.getLine());
+				log.info("message  :" + tdyMsg.getMessage());
+				Message msg = new Message();
+				msg.setMessageSource(IWRTConstants.VALIDATOR);
+				msg.setMessageKey("html.wellform.error");
+				msg.setMessage(tdyMsg.getMessage());
+				msg.setFileTypeZip(messageHandler.isFileTypeZip());
+				msg.setTargetObject(htmlFileName);
+				msg.setFullPath(htmlFile.getAbsolutePath());
+				msg.setSeverity(IWRTConstants.WARN);
+				msg.setLineNumber(tdyMsg.getLine());
+				// msg.setRecommendAction(ValidatorPropMessages.getString("todo.correct.html.tag")+
+				// tdyMsg.getLine()+" of "+htmlFileName);
+				Object[] arguments = { tdyMsg.getLine(), " of , ", htmlFileName };
+				String message = MessageFormat.format(ValidatorPropMessages
+						.getString("todo.correct.html.tag")
+						+ "{0}" + "{1}" + "{2}", arguments);
+				msg.setRecommendAction(message);
+
+				// set all msg fields
+				// For generating TO DO list
+				messageHandler.publishMessage(msg);
+				allRulesPassed = false;
+
+			}
+
+		}
+	}
+//////<<<-----------------------------------code for Jtidy---------------------------------------//
+
+
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/core/validator/IValidator.java	Wed Jan 27 15:05:37 2010 -0800
@@ -0,0 +1,87 @@
+/**
+ * Copyright (c) 2009 Symbian Foundation and/or its subsidiary(-ies).
+ * All rights reserved.
+ * This component and the accompanying materials are made available
+ * under the terms of the License "Eclipse Public License v1.0"
+ * which accompanies this distribution, and is available
+ * at the URL "http://www.eclipse.org/legal/epl-v10.html".
+ *
+ * Initial Contributors:
+ * Symbian Foundation - initial contribution.
+ * Contributors:
+ * Description:
+ * Overview:
+ * Details:
+ * Platforms/Drives/Compatibility:
+ * Assumptions/Requirement/Pre-requisites:
+ * Failures and causes:
+ */
+
+package org.symbian.tools.wrttools.core.validator;
+
+import java.io.File;
+
+import org.symbian.tools.wrttools.core.report.MessageHandler;
+
+/**
+* IValidator is an interface that, when implemented, validates a model. A Model
+* can be any file for widget project plist,html, javaScript, css are in the set of model.
+* A validator loads its model through an FileUtil, traverses the model
+* itself, and communicates with the user through the IReporter. Because each
+* validator instance performs on the same type of model input, and performs the
+* same rule checks against that input, no more than one instance of a validator
+* is needed.
+*
+* When a validator adds a validation message, it identifies itself through a
+* unique id; thus, when a particular's file's validation messages need to be
+* removed , all messages associated with that file, by that validator, are
+* removed. Every message shown to the user, whether it's the message in a
+* ValidationException, or a validation error, will be displayed to the user.
+* Validators do not display messages to the user other than validation messages
+* and subtask messages. This is necessary for Locale-neutrality and
+* environment-neutrality. If a catastrophic error occurs, from which the
+* validator cannot recover, the validator should throw a ValidationException
+*
+* A dummy List<IMessage> is passed as parameter to which the Rule methods will
+* add messages when a validation rules is failed. Boolean variable will be
+* returned to indicate the overall status of validation even if one procedure
+* is failed boolean false will be returned. If returned value is false then
+* List<IMessage> messageList size will be greater than zero if returned value
+* is true the List<IMessage> messageList will be empty creating a dummy list
+* to pass a parameter to the calling method this list will be used by the rules
+* method to add the validation messages if any rules validation is failed
+*
+* @author Sailaja Duvvuri
+* 
+*/
+public interface IValidator {
+
+	
+	
+		/**
+		* Every validator class must implement this method. Validation logic for each
+		* type will be different A dummy List<IMessage> is passed as parameter to
+		* which the Rule methods will add messages when a validation rules is failed.
+		*
+		* Boolean variable will be returned to indicate the overall status of
+		* validation even if one procedure is failed boolean false will be returned. If
+		* returned value is false then List<IMessage> messageList size will be greater
+		* than zero if returned value is true the List<IMessage> messageList will be
+		* empty creating a dummy list to pass a parameter to the calling method this
+		* list will be used by the rules method to add the validation messages if any
+		* rules validation is failed
+		*
+		* filename is assumed as absolute path.
+		* need to set the option a relative path will be implemented 
+		*  
+		* @param filenme
+		* @return
+		*/	
+		public boolean validate(File filename)throws Exception ;
+
+
+		public MessageHandler getMessageHandler() ;
+
+
+		public void setMessageHandler(MessageHandler messageHandler) ;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/core/validator/MandatoryFilesValidator.java	Wed Jan 27 15:05:37 2010 -0800
@@ -0,0 +1,351 @@
+/**
+ * Copyright (c) 2009 Symbian Foundation and/or its subsidiary(-ies).
+ * All rights reserved.
+ * This component and the accompanying materials are made available
+ * under the terms of the License "Eclipse Public License v1.0"
+ * which accompanies this distribution, and is available
+ * at the URL "http://www.eclipse.org/legal/epl-v10.html".
+ *
+ * Initial Contributors:
+ * Symbian Foundation - initial contribution.
+ * Contributors:
+ * Description:
+ * Overview:
+ * Details:
+ * Platforms/Drives/Compatibility:
+ * Assumptions/Requirement/Pre-requisites:
+ * Failures and causes:
+ */
+
+package org.symbian.tools.wrttools.core.validator;
+
+import java.io.File;
+import java.text.MessageFormat;
+import java.util.List;
+import java.util.logging.Logger;
+
+import org.symbian.tools.wrttools.core.exception.ValidationException;
+import org.symbian.tools.wrttools.core.report.Message;
+import org.symbian.tools.wrttools.core.report.MessageHandler;
+import org.symbian.tools.wrttools.core.status.IWRTConstants;
+import org.symbian.tools.wrttools.core.widgetmodel.WidgetModel;
+import org.symbian.tools.wrttools.util.FileUtil;
+import org.symbian.tools.wrttools.util.Util;
+
+/**
+ *Each project folder must contain mandatory files
+ *a.        One  Html
+ *b.        One  Plist 
+ * This Class implements IValidator
+ *Only one method validate(List <IMessage> messageList,String fileName)
+ *The functionality of the mandatory files validation is to find all the files in the project 
+ *directory and verify all the files are present the business logic will be implemented in the
+ *rules class apply rules method Instantiate the MandatoryFilesRule and call the applyrules 
+ *method ().
+ *   - Calls the corresponding rules class and pass the filename
+ * @author Sailaja Duvvuri
+ *
+ */
+ 
+public class MandatoryFilesValidator implements IValidator {
+	
+	public enum FileTypeENUM {
+		css, js, plist, png, jpeg, gif, jpg, htm, html, swf, strings
+
+	};
+	
+	private Logger log = Logger.getLogger(getClass().getName());
+	private boolean allRulesPassed;
+
+	private boolean filesSeleced = false;
+	public List<String> selectedFileList;
+	public String widgetDirPath;
+	public String widgetName;
+	private MessageHandler messageHandler;
+	private WidgetModel widgetModel;
+	
+	
+    public List<String> getSelectedFileList() {
+		return selectedFileList;
+	}
+
+	public void setSelectedFileList(List<String> filesToValidate) {
+		this.selectedFileList = filesToValidate;
+	}
+	
+
+	public WidgetModel getWidgetModel() {
+		return widgetModel;
+	}
+
+	public void setWidgetModel(WidgetModel widgetModel) {
+		this.widgetModel = widgetModel;
+	}
+   
+
+	public MessageHandler getMessageHandler() {
+		return messageHandler;
+	}
+
+
+	public void setMessageHandler(MessageHandler messageHandler) {
+		this.messageHandler = messageHandler;
+	}
+
+	/*
+     * Calls the corresponding rules class and pass the filename
+     * List <IMessage> messageList may contain messages if the client has already
+     * called called ant other validation and failed .
+     */
+    public boolean validate( File widgetFile) throws ValidationException {
+		try{
+    	log.info("validate( )>>--->>");
+    	widgetDirPath=widgetModel.widgetDirectory;
+		widgetName=widgetModel.getWidgetName();
+		allRulesPassed = true;
+		FileUtil filehelper = new FileUtil();
+		List<String> fileNames=null;	
+		
+		if((selectedFileList!=null&&selectedFileList.size()>0)){
+			filesSeleced=true;
+			fileNames=selectedFileList;
+		}else{
+			selectedFileList=filehelper.getCurrDirFileNames(widgetFile);	
+			fileNames=	  filehelper.getDirFileFullNames(widgetFile);
+			
+		}
+	
+		isPlistPresent();
+		isHtmlPresent( fileNames);
+		
+		isPlistCopiesPresent( fileNames);
+		
+		log.info("validate<<---<<");
+		}catch (Exception e) {	
+//			e.printStackTrace();
+			log.severe(e.getCause().toString());			
+			throw new ValidationException(e);
+		}
+		return allRulesPassed;
+	}
+
+    /**
+	 * Accept msg list and List of filenames Loop throught the filelist and see
+	 * if Plist is present. if Plist is present return to the apply rule method
+	 * if Plist is not present after the loop boolean var is set to false and an
+	 * appropriate message is added to the msg list
+	 * 
+	 * @param messageList
+	 * @param fileNames
+	 */
+    private void isPlistPresent() {   	
+
+		log.info("isPlistPresent >>--->>");
+    	
+		if(widgetModel.isPlistPresent()){
+			boolean plistSelected=false;
+			
+			if(filesSeleced){
+				for(String fileName :selectedFileList){
+					fileName = fileName.substring((fileName.indexOf(widgetName	+ "/")+ widgetName.length() + 1));
+					
+					if(fileName.equalsIgnoreCase(widgetModel.getPlistFileName())){
+						plistSelected=true;
+						break;
+					}
+						
+				}
+				
+				
+				if(!plistSelected){					
+					Message msg = new Message();
+					msg.setMessageSource(IWRTConstants.VALIDATOR);
+					msg.setMessageSource(IWRTConstants.VALIDATOR);
+					String key="plist.File.Not.selected";
+					msg.setMessageKey(key);
+					msg.setMessage(ValidatorPropMessages.getString(key)); //$NON-NLS-1$
+					msg.setSeverity(IWRTConstants.FATAL);
+					msg.setRecommendAction(ValidatorPropMessages.getString("todo."+key));
+					// need to set all msg fields
+					getMessageHandler().publishMessage(msg);
+					allRulesPassed = false;						
+				}
+		    	}
+		}else{
+		Message msg = new Message();
+		msg.setMessageSource(IWRTConstants.VALIDATOR);
+		msg.setMessageKey("plist.File.Not.Present");
+		msg.setMessage(ValidatorPropMessages.getString("plist.File.Not.Present")); //$NON-NLS-1$
+		msg.setSeverity(IWRTConstants.FATAL);
+		msg.setRecommendAction(ValidatorPropMessages.getString("todo.include.plist"));
+		// need to set all msg fields
+		getMessageHandler().publishMessage(msg);
+		log.info("isPlistPresent <<---<<");
+		allRulesPassed = false;
+		}
+	}
+   
+    /**
+	 * 
+	 * @param messageList
+	 * @param fileNames
+	 */
+    private void isHtmlPresent(List<String>  fileNames){
+        log.info("isHtmlPresent>>--->> new ");
+        boolean htmlSelected = false;
+    
+        if(fileNames!=null&&fileNames.size()>0){
+      
+        for (String fileName : fileNames) {
+            if ( filesSeleced && fileName.trim().startsWith(widgetName + "/")) {
+                fileName = fileName.substring((fileName.indexOf(widgetName    + "/")+ widgetName.length() + 1));
+                int extLen = fileName.lastIndexOf('.');
+                String extention = "";
+                if(extLen > 0){
+                	extention = fileName.substring(extLen ,fileName.length());
+                }
+                    if (fileName.equalsIgnoreCase(widgetModel.getMainHtml())&& 
+    						(extention.equalsIgnoreCase(".htm")|| extention.equalsIgnoreCase(".html"))) {
+                        htmlSelected = true;
+                    }
+
+            }
+           
+            if(!filesSeleced){
+                if (fileName.trim().startsWith(widgetDirPath+widgetName + "/")) {
+                    fileName = fileName.substring((fileName.indexOf(widgetDirPath+widgetName+ "/")+ (widgetDirPath+widgetName+"/").length()));
+               
+                }
+            }
+            String fileType=fileName.substring(fileName.lastIndexOf('.')+1);
+            if (fileType.trim().equalsIgnoreCase("htm")
+                    || fileType.trim().equalsIgnoreCase("html")) {
+                if(fileName!=null&&widgetModel.getMainHtml()!=null&&!fileName.trim().equalsIgnoreCase(widgetModel.getMainHtml().trim())){
+                     if(!widgetModel.getReferencedHtmlFiles().contains(fileName.toLowerCase()))
+                     {
+                            Message msg= new Message();
+                            msg.setMessageSource(IWRTConstants.VALIDATOR);
+                            String key=("non.referenced.html.File.Present");
+                             msg.setMessage(ValidatorPropMessages.getString(key));
+                            msg.setTargetObject(fileName);
+                               msg.setRecommendAction(ValidatorPropMessages.getString("todo."+key)+"   --: "+fileName);           
+                            msg.setSeverity(IWRTConstants.WARN);
+                            getMessageHandler().publishMessage(msg);
+                            log.finest("isHtmlPresent(MessageManager messageManager,List<String>  fileNames)<<---<<");
+                            allRulesPassed=false;     
+                         
+                           
+                 }
+                   
+                }
+            }
+        }
+        //<<---end for loop<<---<<
+       
+        if(!htmlSelected &&filesSeleced&&widgetModel.isPlistPresent()){
+           
+            Message msg = new Message();
+            msg.setMessageSource(IWRTConstants.VALIDATOR);
+            msg.setMessageSource(IWRTConstants.VALIDATOR);
+            String key="html.File.Not.selected";
+            msg.setMessageKey(key);
+            msg.setMessage(ValidatorPropMessages.getString(key)); //$NON-NLS-1$
+            msg.setSeverity(IWRTConstants.FATAL);
+            msg.setRecommendAction(ValidatorPropMessages.getString("todo."+key));
+            // need to set all msg fields
+            getMessageHandler().publishMessage(msg);
+            allRulesPassed = false;   
+        }
+
+        }// end if filenames
+     if( widgetModel.isPlistPresent()) {
+        if(!widgetModel.isHtmlPresent()){
+        Message msg= new Message();
+        msg.setMessageSource(IWRTConstants.VALIDATOR);
+        msg.setMessageKey("html.File.Not.Present");
+        msg.setMessage(ValidatorPropMessages.getString("html.File.Not.Present"));
+        msg.setSeverity(IWRTConstants.FATAL);
+        msg.setRecommendAction(ValidatorPropMessages.getString("todo.include.html"));
+        getMessageHandler().publishMessage(msg);
+        log.info("isHtmlPresent(MessageManager messageManager,List<String>  fileNames)<<---<<");
+        allRulesPassed=false;
+        }
+     }
+        log.info("isHtmlPresent<<---<<");
+       
+
+    }
+
+    
+    
+    private void isPlistCopiesPresent(    List<String> fileNames) {
+        log.info("isPlistCopiesPresent >>-->>");
+        int len=widgetName.length()+1;
+        if (fileNames != null && widgetModel.getPlistFileName()!=null&& fileNames.size() > 0) 
+        {
+                for (String fileName : fileNames) {
+                log.info("isPlistCopiesPresent >>-->>2");
+//                System.out.println("file names 1  ****: "+fileName);
+           
+                log.info("isPlistCopiesPresent fileName  :" + fileName);
+                if (fileName.endsWith(".plist")) {                   
+                    log.info("isPlistCopiesPresent fileName  :" + fileName);
+//                    System.out.println("only plist file names ****  2: "+fileName);
+                    if (!filesSeleced) {                       
+                        log.info(" selected   :" + widgetDirPath+ widgetName + "/" + ":");
+                        fileName = fileName.replace(widgetDirPath+ widgetName + "/", "");
+                           
+                    } else {
+                        log.info(" selected   :" + widgetName + "/" + ":");
+//                        System.out.println("plist file names ****  3: "+fileName);
+                        fileName = fileName.substring(len);
+//                        System.out.println("plist file names AFTER ****  4: "+fileName +" : "+widgetName);
+                                                   
+                    }
+                    log.info("isPlistCopiesPresent fileName  :" + fileName);
+                   
+//                    if(fileName.trim().contains("/"))
+//                    {
+//                    }
+                   
+                if(!(   fileName.trim().equalsIgnoreCase(widgetModel.getPlistFileName().trim()))){
+                   
+                    if(fileName.trim().contains("/")){
+                        Message msg = new Message();
+                        msg.setMessageSource(IWRTConstants.VALIDATOR);
+                        msg.setMessageKey("subfolder.duplicate.plist.file.present");
+                        msg.setTargetObject(fileName);
+                        msg.setMessage(ValidatorPropMessages.getString(msg.getMessageKey()));
+                        msg.setSeverity(IWRTConstants.WARN);
+//                        msg.setRecommendAction(ValidatorPropMessages.getString("todo."+msg.getMessageKey())+"  --:"+fileName);
+                        getMessageHandler().publishMessage(msg);
+                        allRulesPassed = false;
+                       
+                    }
+                    else{
+
+                        Message msg = new Message();
+                        msg.setMessageSource(IWRTConstants.VALIDATOR);
+                        msg.setMessageKey("duplicate.plist.file.present");
+                        msg.setTargetObject(fileName);
+                        msg.setMessage(ValidatorPropMessages.getString(msg.getMessageKey()));
+                        msg.setSeverity(IWRTConstants.WARN);
+                        msg.setRecommendAction(ValidatorPropMessages.getString("todo."+msg.getMessageKey())+"  --:"+fileName);
+                        getMessageHandler().publishMessage(msg);
+                        allRulesPassed = false;
+                       
+                    }
+                }
+               
+
+               
+                }
+
+            }
+
+        }
+        log.info("isPlistCopiesPresent <<--<<");
+
+        //        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/core/validator/Messages.java	Wed Jan 27 15:05:37 2010 -0800
@@ -0,0 +1,41 @@
+/**
+ * Copyright (c) 2009 Symbian Foundation and/or its subsidiary(-ies).
+ * All rights reserved.
+ * This component and the accompanying materials are made available
+ * under the terms of the License "Eclipse Public License v1.0"
+ * which accompanies this distribution, and is available
+ * at the URL "http://www.eclipse.org/legal/epl-v10.html".
+ *
+ * Initial Contributors:
+ * Symbian Foundation - initial contribution.
+ * Contributors:
+ * Description:
+ * Overview:
+ * Details:
+ * Platforms/Drives/Compatibility:
+ * Assumptions/Requirement/Pre-requisites:
+ * Failures and causes:
+ */
+
+package org.symbian.tools.wrttools.core.validator;
+
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+public class Messages {
+	private static final String BUNDLE_NAME = "com.nokia.wrt.core.validator"; //$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 + '!';
+		}
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/core/validator/PlistValidator.java	Wed Jan 27 15:05:37 2010 -0800
@@ -0,0 +1,466 @@
+/**
+ * Copyright (c) 2009 Symbian Foundation and/or its subsidiary(-ies).
+ * All rights reserved.
+ * This component and the accompanying materials are made available
+ * under the terms of the License "Eclipse Public License v1.0"
+ * which accompanies this distribution, and is available
+ * at the URL "http://www.eclipse.org/legal/epl-v10.html".
+ *
+ * Initial Contributors:
+ * Symbian Foundation - initial contribution.
+ * Contributors:
+ * Description:
+ * Overview:
+ * Details:
+ * Platforms/Drives/Compatibility:
+ * Assumptions/Requirement/Pre-requisites:
+ * Failures and causes:
+ */
+
+package org.symbian.tools.wrttools.core.validator;
+
+import java.io.File;
+import java.text.MessageFormat;
+import java.util.List;
+import java.util.logging.Logger;
+
+import org.symbian.tools.wrttools.core.exception.ValidationException;
+import org.symbian.tools.wrttools.core.parser.XmlElement;
+import org.symbian.tools.wrttools.core.report.Message;
+import org.symbian.tools.wrttools.core.report.MessageHandler;
+import org.symbian.tools.wrttools.core.status.IWRTConstants;
+import org.symbian.tools.wrttools.core.widgetmodel.WidgetModel;
+import org.symbian.tools.wrttools.util.FileUtil;
+import org.symbian.tools.wrttools.util.Util;
+
+/**
+ * PlistValidator Accepts the List <IMessage> messageList and will not process
+ * it. Accept String fileName. Use HtmlParser to get all elements in a stack.
+ * 
+ * @author Sailaja duvvuri
+ */
+public class PlistValidator implements IValidator {
+	
+	public enum plistElements {
+		plist, array, data, date, dict, real, integer, string, FALSE, TRUE, key, xml
+
+	};
+
+	public enum mandatoryPlistValues {
+		DisplayName, Identifier, MainHTML
+	};
+
+	
+//	private Hashtable<String, String> plistHashKey = null;
+	private MessageHandler messageHandler;
+	private FileUtil fileUtil = new FileUtil();
+	private String plistFileName = null;
+	private File plistFile = null;
+	
+	public List<String> filesToValidate;
+	public String projDirParenPath;
+	public String projDirName;
+	
+	private boolean filesSeleced = false;
+	private boolean allRulesPassed;	
+	
+	private WidgetModel widgetModel;
+	
+
+	private Logger log = Logger.getLogger(getClass().getName());
+	
+	
+	
+	public WidgetModel getWidgetModel() {
+		return widgetModel;
+	}
+
+	public void setWidgetModel(WidgetModel widgetModel) {
+		this.widgetModel = widgetModel;
+	}
+	public MessageHandler getMessageHandler() {
+		return messageHandler;
+	}
+
+
+	public void setMessageHandler(MessageHandler messageHandler) {
+		this.messageHandler = messageHandler;
+	}
+
+	public List<String> getFilesToValidate() {
+		return filesToValidate;
+	}
+
+	public void setFilesToValidate(List<String> filesToValidate) {
+		this.filesToValidate = filesToValidate;
+	}
+/**
+	 * @throws ValidationException 
+ * @throws Exception 
+	 * 
+	 */
+	public boolean validate( File widgetFile) throws ValidationException{
+		log.info("validate>>--->>");
+		List <File>dirList = fileUtil.getCurrDirFiles(widgetFile);
+		projDirParenPath=widgetFile.getPath().substring(0,widgetFile.getPath().indexOf(widgetFile.getName()));
+		projDirName=widgetFile.getName();
+		FileUtil filehelper = new FileUtil();
+	
+		if((filesToValidate!=null&&filesToValidate.size()>1)){
+			filesSeleced=true;
+		}else{
+			filesToValidate=filehelper.getCurrDirFileNames(widgetFile);			
+		}
+
+		plistFileName =widgetModel.getPlistFileName();
+		projDirParenPath=widgetModel.widgetDirectory;
+		projDirName=widgetModel.getWidgetName();
+	
+		if(plistFileName!=null&& plistFileName.length()>0)
+		{
+		plistFile=new File(projDirParenPath+projDirName+"/"+plistFileName);
+		
+		}else{		
+			Message msg = new Message();
+			msg.setMessageSource(IWRTConstants.VALIDATOR);
+			msg.setMessageKey("plist.file.not.present");
+			msg.setMessage(ValidatorPropMessages.getString("plist.file.not.present"));			
+			msg.setRecommendAction(ValidatorPropMessages.getString("todo.include.plist"));
+			msg.setFileTypeZip(getMessageHandler().isFileTypeZip());				
+			msg.setSeverity(IWRTConstants.FATAL);
+			getMessageHandler().publishMessage(msg);
+			throw new ValidationException(ValidatorPropMessages.getString("plist.file.not.present"));
+		}
+		if(widgetModel.getPlistXmlFile()!=null){
+			checkWellformedAndValidate();
+			checkHtml(dirList);
+			checkPlistValues();
+			
+		}else{
+			Message msg = new Message();
+			msg.setMessageSource(IWRTConstants.VALIDATOR);
+			msg.setMessageKey("no.plist.element");
+			msg.setMessage(ValidatorPropMessages.getString("no.plist.element"));
+			msg.setFileTypeZip(getMessageHandler().isFileTypeZip());
+			msg.setTargetObject(plistFileName);
+			msg.setFullPath(plistFile.getAbsolutePath());
+			msg.setSeverity(IWRTConstants.ERROR);
+			msg.setRecommendAction(ValidatorPropMessages.getString("todo.no.plist.element"));
+			getMessageHandler().publishMessage(msg);				
+		allRulesPassed=false;	
+			
+			
+			
+		}		
+	
+		
+
+		log.info("validate<<---<<");
+		return allRulesPassed;
+	}
+
+	
+	
+	
+	//---------------check plist wellformness----------------------//
+	/**
+	 * 
+	 * @return
+	 */
+	private boolean checkWellformedAndValidate() {
+		log.info("checkWellformedAndValidate>>---->>");
+		boolean returnVal=true;
+//		//commented out because  saxPlistParser is slow -------->>
+//		PlistValidatorParser saxPlistParser= new PlistValidatorParser();
+//		saxPlistParser.setMessageHandler(this.getMessageHandler());
+
+//		if(!(saxPlistParser.parsePlist(projDirParenPath+projDirName+"/"+widgetModel.getPlistFileName())))
+//		///<<-----------------------------<<
+		{			
+			
+			parsePlistError(widgetModel.getPlistXmlFile() );
+			validateElement(widgetModel.getPlistXmlFile());
+//			if()
+			returnVal= false;
+		}
+		log.info("checkWellformedAndValidate<<---<<");
+		
+		return returnVal;
+	}
+	
+	
+	private void parsePlistError(XmlElement rootXmlElement) {
+		log.info("parsePlistError>>-->>");
+		
+		if (rootXmlElement.getErrorList() != null) {
+			int errSize = rootXmlElement.getErrorList().size();
+			for (int i = 0; i < errSize; i++) {
+				Message msg = rootXmlElement.getErrorList().get(i);
+				getMessageHandler().publishMessage(msg);
+
+			}
+		}
+
+		if (rootXmlElement.getChildList() != null)
+			for (XmlElement elm : rootXmlElement.getChildList()) {
+				parsePlistError(elm);
+			}
+		log.info("parsePlistError<<---<<");
+		
+	}
+	
+	//---------------------------check html------------------------------//
+	/**
+	 * 
+	 * @param dirList
+	 * @return
+	 */
+	
+	private boolean checkHtml(List<File> dirList) {
+			boolean checkHtml = false;
+		log.info("checkHtml>>--->>");
+			if (widgetModel.getMainHtml()!=null&&widgetModel.getMainHtml().trim().length()>0){
+			String htmlName	=widgetModel.getMainHtml();
+		File htmlFile = fileUtil.getFile(dirList, widgetModel.getMainHtml());
+		if(htmlFile==null)
+		{
+			htmlFile = fileUtil.getFile(dirList, "html","htm");			
+			}
+			if (htmlFile != null) {
+				
+				if (htmlFile.getName().equalsIgnoreCase(htmlName)) {
+				checkHtml=true;
+			} else {
+				
+				Message msg = new Message();
+				msg.setMessageSource(IWRTConstants.VALIDATOR);
+				msg.setMessageKey("plist.html.element.mismatch");				
+				Object[] arguments = {htmlFile.getName() , "<>" , htmlName}; 
+				String message = MessageFormat.format(ValidatorPropMessages.getString("plist.html.element.mismatch")+"{0}"+"{1}"+"{2}",arguments); 
+				msg.setMessage(message);				
+				msg.setFileTypeZip(getMessageHandler().isFileTypeZip());
+				
+				msg.setTargetObject(plistFile.getName());
+				msg.setFullPath(plistFile.getAbsolutePath());
+				msg.setSeverity(IWRTConstants.ERROR);
+				msg.setRecommendAction(ValidatorPropMessages.getString("todo.correct.plist.for.html"));				
+				getMessageHandler().publishMessage(msg);
+				allRulesPassed=false;
+			}
+		}
+	}else{
+		
+		Message msg = new Message();
+		msg.setMessageSource(IWRTConstants.VALIDATOR);
+		msg.setMessageKey("plist.html.element.mailHtml.missing");				
+		msg.setMessage(ValidatorPropMessages.getString("plist.html.element.mailHtml.missing"));
+		
+		msg.setFileTypeZip(getMessageHandler().isFileTypeZip());		
+		msg.setTargetObject(plistFile.getName());
+		msg.setFullPath(plistFile.getAbsolutePath());
+		msg.setSeverity(IWRTConstants.ERROR);
+		msg.setRecommendAction(ValidatorPropMessages.getString("todo.correct.plist"));
+		
+		getMessageHandler().publishMessage(msg);
+		allRulesPassed=false;	
+	}
+		
+			log.info("checkHtml<<---<<");
+		
+		return checkHtml;
+	}	
+	
+	
+	
+	
+	
+	
+	private boolean checkPlistValues() {
+		boolean checkPlistValues = true;
+		log.info("checkPlistValies >>--->>");		
+				
+			if(!(widgetModel.getDisplayname()!=null&&widgetModel.getDisplayname().trim().length()>0)){
+				Message msg = new Message();
+				msg.setMessageSource(IWRTConstants.VALIDATOR);
+				msg.setMessageKey("plist.mankey.mising");
+				
+				Object[] arguments = {" 'Display Name'  ", ValidatorPropMessages.getString("not.in.plist.file")}; 
+				String message = MessageFormat.format(ValidatorPropMessages.getString("plist.mankey.mising")+"{0}"+"{1}",arguments); 
+				msg.setMessage(message);
+
+				msg.setFileTypeZip(getMessageHandler().isFileTypeZip());
+
+				msg.setTargetObject(plistFile.getName());
+				msg.setFullPath(plistFile.getAbsolutePath());
+				Object[] arguments2 = {" 'Display Name'  "  ,"to plistFile."}; 
+				String message2 = MessageFormat.format(ValidatorPropMessages.getString("todo.add.mankey.plist.element")+"{0}"+"{1}",arguments2); 
+				msg.setRecommendAction(message2);
+				
+				msg.setSeverity(IWRTConstants.ERROR);
+				getMessageHandler().publishMessage(msg);
+				
+			} else /* validating Widget name (Display name) */
+			{
+				String strError = Util.validateWidgetName(widgetModel.getDisplayname());				
+				if ( strError != null ){
+					Message msg = new Message();
+					msg.setMessageSource(IWRTConstants.VALIDATOR);
+					msg.setMessageKey("plist.mankey.mising");
+					
+					Object[] arguments = {" 'Display Name'  ", ValidatorPropMessages.getString("contains.invalid.character")}; 
+					String message = MessageFormat.format(ValidatorPropMessages.getString("plist.mankey.mising")+"{0}"+"{1}",arguments); 
+					msg.setMessage(message);
+
+					msg.setFileTypeZip(getMessageHandler().isFileTypeZip());
+
+					msg.setTargetObject(plistFile.getName());
+					msg.setFullPath(plistFile.getAbsolutePath());
+					Object[] arguments2 = {" 'Display Name'  "  ,"to plistFile."}; 
+					String message2 = MessageFormat.format(ValidatorPropMessages.getString("todo.valid.character")+"{0}"+"{1}",arguments2); 
+					msg.setRecommendAction(message2);
+					
+					msg.setSeverity(IWRTConstants.ERROR);
+					getMessageHandler().publishMessage(msg);					
+				}
+			}
+
+			if(!(widgetModel.getMainHtml()!=null&&widgetModel.getMainHtml().trim().length()>0)){
+				Message msg = new Message();
+				msg.setMessageSource(IWRTConstants.VALIDATOR);
+				msg.setMessageKey("plist.mankey.mising");
+
+				Object[] arguments = {" 'MainHTML '  ", ValidatorPropMessages.getString("not.in.plist.file")}; 
+				String message = MessageFormat.format(ValidatorPropMessages.getString("plist.mankey.mising")+"{0}"+"{1}",arguments); 
+				msg.setMessage(message);
+
+				msg.setFileTypeZip(getMessageHandler().isFileTypeZip());
+
+				msg.setTargetObject(plistFile.getName());
+				msg.setFullPath(plistFile.getAbsolutePath());
+				Object[] arguments2 = {" 'MainHTML'  "  ,"to plistFile."}; 
+				String message2 = MessageFormat.format(ValidatorPropMessages.getString("todo.add.mankey.plist.element")+"{0}"+"{1}",arguments2); 
+				msg.setRecommendAction(message2);
+				
+				msg.setSeverity(IWRTConstants.ERROR);
+				getMessageHandler().publishMessage(msg);
+				
+			}
+			if(!(widgetModel.getIdentifier()!=null&&widgetModel.getIdentifier().trim().length()>0)){
+				Message msg = new Message();
+				msg.setMessageSource(IWRTConstants.VALIDATOR);
+				msg.setMessageKey("plist.mankey.mising");
+				Object[] arguments = {" 'Identifier '  ", ValidatorPropMessages.getString("not.in.plist.file")}; 
+				String message = MessageFormat.format(ValidatorPropMessages.getString("plist.mankey.mising")+"{0}"+"{1}",arguments); 
+				msg.setMessage(message);
+
+				msg.setFileTypeZip(getMessageHandler().isFileTypeZip());
+
+				msg.setTargetObject(plistFile.getName());
+				msg.setFullPath(plistFile.getAbsolutePath());
+				Object[] arguments2 = {" 'Identifier'  "  ,"to plistFile."}; 
+				String message2 = MessageFormat.format(ValidatorPropMessages.getString("todo.add.mankey.plist.element")+"{0}"+"{1}",arguments2); 
+				msg.setRecommendAction(message2);
+				
+				msg.setSeverity(IWRTConstants.ERROR);
+				getMessageHandler().publishMessage(msg);
+				
+			} else /* validating Widget Idenfier (UID) */
+			{
+				String strError = Util.validateWidgetID(widgetModel.getIdentifier());				
+				if ( strError != null ){
+					Message msg = new Message();
+					msg.setMessageSource(IWRTConstants.VALIDATOR);
+					msg.setMessageKey("plist.mankey.mising");
+					
+					Object[] arguments = {" 'Identifier'  ", ValidatorPropMessages.getString("contains.invalid.character")}; 
+					String message = MessageFormat.format(ValidatorPropMessages.getString("plist.mankey.mising")+"{0}"+"{1}",arguments); 
+					msg.setMessage(message);
+
+					msg.setFileTypeZip(getMessageHandler().isFileTypeZip());
+
+					msg.setTargetObject(plistFile.getName());
+					msg.setFullPath(plistFile.getAbsolutePath());
+					Object[] arguments2 = {" 'Identifier'  "  ,"to plistFile."}; 
+					String message2 = MessageFormat.format(ValidatorPropMessages.getString("todo.valid.character")+"{0}"+"{1}",arguments2); 
+					msg.setRecommendAction(message2);
+					
+					msg.setSeverity(IWRTConstants.ERROR);
+					getMessageHandler().publishMessage(msg);					
+				}
+			}
+			log.info("checkPlistValues<<---<<");
+		return checkPlistValues;
+	}
+	
+
+	private void validateElement(XmlElement rootXmlElement) {
+		log.info("validateElement >>--->>");		
+		
+		
+//		showData("");
+			plistElements[] values = plistElements.values();
+			boolean isValidElement = false;
+			for (plistElements validElement: values)
+			{
+				if (validElement.toString().equalsIgnoreCase(rootXmlElement.getName().trim()))
+						{
+					         isValidElement=true;
+					         break;
+					
+						}
+				continue;
+			}
+			if (! isValidElement)
+			{
+				Message msg = new Message();
+				
+				msg.setMessageSource(IWRTConstants.VALIDATOR);
+				msg.setMessageKey("plist.element.not.supported");
+				String msgtxt=ValidatorPropMessages.getString("plist.element.not.supported");
+				Object[] arguments = {"   "  ,rootXmlElement.getName().trim()}; 
+				String message = MessageFormat.format(ValidatorPropMessages.getString("plist.element.not.supported")+"{0}"+"{1}",arguments); 
+				msg.setMessage(message);
+
+				
+				msg.setRecommendAction(ValidatorPropMessages.getString("todo.plist.element.not.Valid"));
+				msg.setFileTypeZip(getMessageHandler().isFileTypeZip());
+			
+				msg.setTargetObject(plistFile.getName());
+				msg.setFullPath(plistFile.getAbsolutePath());
+				msg.setSeverity(IWRTConstants.ERROR);
+				msg.setLineNumber(rootXmlElement.getLineNo());
+				// need to set all msg fields
+				getMessageHandler().publishMessage(msg);
+				allRulesPassed=false;
+			}		
+		
+
+		if (rootXmlElement.getChildList() != null)
+			for (XmlElement elm : rootXmlElement.getChildList()) {
+				validateElement(elm);
+			}
+		log.info("validateElement <<---<<");		
+		
+	}
+	
+	
+
+	  private static void showData(String s) {
+		}
+	
+	public static void main(String argv[]) throws Exception {
+		PlistValidator validator = new PlistValidator();
+//		validator.trimElementSpace("    s  ai   lu  ");
+//		boolean isbegin=validator.isBeginAndCloseElement("<   key  >", "< \\    key1  >");
+
+		final String XML_FILE_NAME = "C:\\Parser\\sax\\info.plist";
+		try {
+			validator.validate( new File (XML_FILE_NAME));
+		} catch (ValidationException e) {			
+		}
+//		 bl.stackData("C:\\Parser\\sax\\info.plist");
+	}
+
+	
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/core/validator/ValidateAction.java	Wed Jan 27 15:05:37 2010 -0800
@@ -0,0 +1,300 @@
+/**
+ * Copyright (c) 2009 Symbian Foundation and/or its subsidiary(-ies).
+ * All rights reserved.
+ * This component and the accompanying materials are made available
+ * under the terms of the License "Eclipse Public License v1.0"
+ * which accompanies this distribution, and is available
+ * at the URL "http://www.eclipse.org/legal/epl-v10.html".
+ *
+ * Initial Contributors:
+ * Symbian Foundation - initial contribution.
+ * Contributors:
+ * Description:
+ * Overview:
+ * Details:
+ * Platforms/Drives/Compatibility:
+ * Assumptions/Requirement/Pre-requisites:
+ * Failures and causes:
+ */
+package org.symbian.tools.wrttools.core.validator;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceVisitor;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IObjectActionDelegate;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+
+import org.symbian.tools.wrttools.Activator;
+import org.symbian.tools.wrttools.core.exception.ReportException;
+import org.symbian.tools.wrttools.core.exception.ValidationException;
+import org.symbian.tools.wrttools.core.marker.MarkerUtil;
+import org.symbian.tools.wrttools.core.packager.WRTPackagerConstants;
+import org.symbian.tools.wrttools.core.report.IMessageListener;
+import org.symbian.tools.wrttools.core.report.Message;
+import org.symbian.tools.wrttools.core.status.IWRTConstants;
+import org.symbian.tools.wrttools.core.status.IWRTStatusListener;
+import org.symbian.tools.wrttools.core.status.WRTStatus;
+import org.symbian.tools.wrttools.core.status.WRTStatus;
+import org.symbian.tools.wrttools.core.validator.Messages;
+public class ValidateAction implements IObjectActionDelegate {
+	
+//	WRTStatusListener statusListener = new WRTStatusListener();
+	private StatusListener statusListener = new StatusListener();
+	public MessageListener messageListener = new MessageListener();
+	private final List<IProject> projectList = new ArrayList<IProject>();
+//	private String widgetProjectPath;
+	IProject projectvalidating  =null;
+	private Shell shell;
+	
+	private boolean validateSucess=false;
+	private boolean initialValidate;	
+	
+	
+	public ValidateAction() {
+		super();
+	}
+
+	public void setActivePart(IAction action, IWorkbenchPart targetPart) {
+	}
+
+	public void run(IAction action) {
+		try{		  
+			PlatformUI.getWorkbench().saveAllEditors(true);
+			PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().showView("org.eclipse.ui.views.ProblemView");
+		}
+		catch(PartInitException e)
+		{
+			Activator.log(IStatus.ERROR, "Problem View  exception", e);
+		}
+		IProject emptyfilesProject = null;
+		initialValidate = false;
+		if (projectList != null && projectList.size() > 0) {
+			for (IProject project : projectList) {
+				if (project != null) {
+					validateSucess=true;
+					validateProject( project);
+					emptyfilesProject = project;					
+				}
+			}
+		}
+		/* if all the mandatory files are missing then display error on the screen*/
+		if (emptyfilesProject != null && ! initialValidate) {
+			WidgetValidator widgetValidator = new WidgetValidator(messageListener, statusListener);
+			try {			
+				widgetValidator.validateWidgetProject(emptyfilesProject.getLocation().toString());
+			} catch (ValidationException e) {
+				Activator.log(IStatus.ERROR, "Validation exception ", e);
+			} catch (ReportException e) {
+				Activator.log(IStatus.ERROR, "Report exception", e);
+			}			
+		}
+	}
+
+	public boolean isValidProject(IProject project) {
+
+		PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
+			
+			public void run() {
+				
+				IWorkbenchWindow dwindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+				IWorkbenchPage page = dwindow.getActivePage();
+				
+				if (page != null) {
+					try {
+						page.showView("org.eclipse.ui.views.ProblemView");
+					}catch (PartInitException pie) {
+					}
+				}
+			}
+		});
+		
+		validateSucess = true;
+		validateProject(project);
+		
+		return validateSucess;
+	}
+	
+	public void validateProject(IProject project) {
+		projectvalidating=project;
+//        statusListener.setStatusSource(IWRTConstants.StatusSourceType.VALIDATOR.name());
+        messageListener.setMessageSource(IWRTConstants.VALIDATOR);
+        WidgetValidator widgetValidator = new WidgetValidator(messageListener, statusListener);
+    	final List<String> filesToPackage = new ArrayList<String>();
+        try {
+			project.accept(new IResourceVisitor() {
+				public boolean visit(IResource resource) throws CoreException {
+					if (resource instanceof IFile) {
+						IFile file = (IFile) resource;
+						boolean add = true;
+						// skip user-excluded and automatically-excluded files
+						String value = file
+								.getPersistentProperty(WRTPackagerConstants.EXCLUDE_PROPERTY);
+						if (value != null) {
+							add = false;
+						}
+						String name = file.getName();
+						// skip Aptana temporarily generated files
+						if (name.startsWith(".tmp_")) {
+							add = false;
+						}
+						// if(name.endsWith(".wgz")){
+						// add = false;
+						// }
+						if (name.equals("Thumbs.db")) {
+							add = false;
+						}
+						if (add) {
+							if (file.getProject().getLocation().toString()
+									.endsWith(file.getProject().getName())) {
+
+								filesToPackage.add(file.getLocation()
+										.toString().substring(
+												file.getProject().getLocation()
+														.toString().length()
+														- file.getProject()
+																.getName()
+																.length()));
+							} else {
+								String projectDir = file.getProject()
+										.getLocation().toString().substring(
+												file.getProject().getLocation()
+														.toString()
+														.lastIndexOf("/") + 1);
+								String fullpath = file.getFullPath().toString();
+								fullpath = fullpath.substring(fullpath
+										.indexOf(file.getProject().getName())
+										+ file.getProject().getName().length());
+								fullpath = projectDir + fullpath;
+								filesToPackage.add(fullpath);
+
+							}
+						}
+					}
+					return true;
+				}
+			});
+		} 
+        catch (CoreException x) {
+			Activator.log(IStatus.ERROR,	"Core Exception ", x);
+		}
+        if (filesToPackage != null && filesToPackage.size() > 0) {
+			widgetValidator.setFilesSelected(filesToPackage);
+	
+			try {
+				MarkerUtil.deleteMarker(project);
+				widgetValidator.validateWidgetProject(project.getLocation().toString());
+				initialValidate = true;
+			} catch (ValidationException e) {
+				Activator.log(IStatus.ERROR, "Validation exception ", e);
+			} catch (ReportException e) {
+				Activator.log(IStatus.ERROR, "Report exception", e);
+			}
+
+			if (validateSucess) {
+//				WRTStatus status = new WRTStatus();
+//				status.setStatusSource(IWRTConstants.StatusSourceType.VALIDATOR.name());
+//				status.setStatusDescription("Validation completed, no errors were found.");
+//				status.setStatusDescription(Messages.getString("widget.validation.complete"));
+//				statusListener.emitStatus(status);
+			}
+		}
+        else {
+	        	if(shell != null)
+	        	MessageDialog.openInformation(shell,"Validate Widget Project","Please Select Files to validate");
+		}
+		
+	}
+
+	public void selectionChanged(IAction action, ISelection selection) {
+		if (selection instanceof IStructuredSelection) {
+			projectList.clear();
+			IStructuredSelection ss = (IStructuredSelection) selection;
+			for (Iterator iter = ss.iterator(); iter.hasNext();) {
+
+				Object obj = iter.next();
+				if (obj instanceof IProject) {
+					projectList.add((IProject) obj);
+
+				}
+			}
+		}
+	}	
+	   
+//	-------------------------------inner class-------------------------------------//
+
+	public class MessageListener implements IMessageListener {
+		private int messageSource;
+		public int getMessageSource() {
+			return 1;
+		}
+		public void setMessageSource(int messageSource) {
+			this.messageSource = messageSource;
+		}
+		public boolean isMessageHandled(Message msg) {
+
+			if (msg.getMessageSource() == (messageSource)) {
+				return true;
+			}
+			return false;
+		}
+		public void receiveMessage(Message msg) {
+			if (IWRTConstants.ERROR.equals(msg.getSeverity())) {
+				validateSucess = false;
+			}
+			MarkerUtil.addMarker(msg, projectvalidating);
+		}
+	}
+	
+	public class StatusListener implements IWRTStatusListener {
+		private String statusSource;
+
+		public String getStatusSource() {
+			return statusSource;
+		}
+
+		public void setStatusSource(String statusSource) {
+			this.statusSource = statusSource;
+		}
+
+		public boolean isStatusHandled(WRTStatus status) {
+//
+//			if (status.getStatusSource().equals(statusSource)) {
+//				return true;
+//			}
+			return false;
+		}
+
+		public void emitStatus(WRTStatus status) {
+			// TODO Auto-generated method stub
+			
+		}
+
+//		public void emitStatus(final WRTStatus status) {
+//			parentShell.getDisplay().asyncExec(new Runnable(){
+//				public void run() {					
+//					setStatusText(status.getStatusDescription().toString());
+//				}
+//			});
+//		}
+	}
+//	-------------------------------inner class-------------------------------------//
+	
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/core/validator/ValidatorPropMessages.java	Wed Jan 27 15:05:37 2010 -0800
@@ -0,0 +1,53 @@
+/**
+ * Copyright (c) 2009 Symbian Foundation and/or its subsidiary(-ies).
+ * All rights reserved.
+ * This component and the accompanying materials are made available
+ * under the terms of the License "Eclipse Public License v1.0"
+ * which accompanies this distribution, and is available
+ * at the URL "http://www.eclipse.org/legal/epl-v10.html".
+ *
+ * Initial Contributors:
+ * Symbian Foundation - initial contribution.
+ * Contributors:
+ * Description:
+ * Overview:
+ * Details:
+ * Platforms/Drives/Compatibility:
+ * Assumptions/Requirement/Pre-requisites:
+ * Failures and causes:
+ */
+
+package org.symbian.tools.wrttools.core.validator;
+
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.symbian.tools.wrttools.util.Util;
+
+public class ValidatorPropMessages {
+	private static final String BUNDLE_NAME = "com.nokia.wrt.core.validator.messages"; //$NON-NLS-1$
+
+	private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle
+			.getBundle(BUNDLE_NAME);
+	private static Logger log = Logger.getLogger("com.nokia.wrt.core.validator.ValidatorPropMessages");
+
+	private ValidatorPropMessages() {
+	}
+
+	public static String getString(String key) {
+		try {
+			return RESOURCE_BUNDLE.getString(key);
+		} catch (MissingResourceException e) {
+			 Util.logEvent(log, Level.INFO, e);				
+			return '!' + key + '!';
+		}
+	}
+	
+	public static void main(String[] args) {
+		
+//		  System.out.println("    "+ ValidatorPropMessages.getString("plist.File.Not.Present"));
+	
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/core/validator/WidgetProjectValidator.java	Wed Jan 27 15:05:37 2010 -0800
@@ -0,0 +1,466 @@
+/**
+ * Copyright (c) 2009 Symbian Foundation and/or its subsidiary(-ies).
+ * All rights reserved.
+ * This component and the accompanying materials are made available
+ * under the terms of the License "Eclipse Public License v1.0"
+ * which accompanies this distribution, and is available
+ * at the URL "http://www.eclipse.org/legal/epl-v10.html".
+ *
+ * Initial Contributors:
+ * Symbian Foundation - initial contribution.
+ * Contributors:
+ * Description:
+ * Overview:
+ * Details:
+ * Platforms/Drives/Compatibility:
+ * Assumptions/Requirement/Pre-requisites:
+ * Failures and causes:
+ */
+
+package org.symbian.tools.wrttools.core.validator;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceVisitor;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.osgi.framework.Bundle;
+
+import org.symbian.tools.wrttools.sdt.utils.DefaultMessageListener;
+import org.symbian.tools.wrttools.sdt.utils.FileUtils;
+import org.symbian.tools.wrttools.sdt.utils.MessageLocation;
+import org.symbian.tools.wrttools.sdt.utils.VariableSubstitutionEngine;
+import org.symbian.tools.wrttools.Activator;
+import org.symbian.tools.wrttools.core.exception.ValidationException;
+import org.symbian.tools.wrttools.core.packager.WRTPackagerConstants;
+import org.symbian.tools.wrttools.core.widgetmodel.WidgetModel;
+import org.symbian.tools.wrttools.previewer.preview.PreviewSupport;
+
+public class WidgetProjectValidator {
+	
+    static final String INFO_PLIST = "info.plist";
+    boolean previewMainCreated = false; 
+    private IProject project;
+    private WidgetModel model = null;
+   
+	public static final String BUILDER_ID = "org.symbian.tools.wrttools.core.validator.widgetProjectValidator";
+
+	public WidgetProjectValidator() {
+		super();
+		ValidateAction validator = new ValidateAction();
+		validator.isValidProject(project);
+		//return null;
+	}
+	void checkResource(IResource resource, IProject project  ) {
+		if (resource instanceof IFile) {
+			try {
+				if(!previewMainCreated )	{
+					//createEmptyPreviewMainHTML();
+					createPreviewFrameHTML(project);
+					
+				}
+				//if info.plist modified
+				if (isInfoPList(resource)) {
+					// did a change to info.plist result in a different main html file?
+					
+					IResource prevMainHTML = null;
+					String mainHtmlName = project.getPersistentProperty(PreviewSupport.MAIN_HTML_PROPERTY);
+					if (mainHtmlName != null) {
+						prevMainHTML = project.findMember(mainHtmlName, false);
+					}
+				     model = null;
+					IFile currMainHTML = getMainHTMLFromModel(project);
+
+					 if ( currMainHTML != null){
+						if(!currMainHTML.equals(prevMainHTML)) {
+								updateHTMLPreview(currMainHTML);
+								
+						}
+					 }
+					else{
+						createEmptyPreviewMainHTML(project);
+						project.setPersistentProperty(PreviewSupport.MAIN_HTML_PROPERTY, null);
+					}
+					
+					
+				}
+				else{		
+					IFile currMainHTML = getMainHTMLFromModel(project);
+				   String mainHtmlPath = project.getPersistentProperty(PreviewSupport.MAIN_HTML_PROPERTY);
+				  if(mainHtmlPath == null){					  
+					  if (currMainHTML != null && !currMainHTML.equals(resource)) {
+					    	updateHTMLPreview(currMainHTML);
+					 }
+				 }
+				else if (mainHtmlPath.equals(resource.getProjectRelativePath().toString())) {					
+					updateHTMLPreview((IFile)resource);
+					
+				  }
+				}
+			} catch (CoreException e) {
+				Activator.log(IStatus.ERROR, "Error building resource:"+resource.getFullPath().toString(), e);
+			} catch (IOException e) {
+				Activator.log(IStatus.ERROR, "Error building resource:"+resource.getFullPath().toString(), e);
+			} catch (URISyntaxException e) {
+				Activator.log(IStatus.ERROR, "Error building resource:"+resource.getFullPath().toString(), e);
+			}
+		}
+	}
+	
+	private void updateHTMLPreview(IFile htmlFile) throws CoreException, IOException, URISyntaxException {
+		createPreviewMainHTML(getMainHTML(project));	
+		//createPreviewFrameHTML();
+
+	}
+
+	protected void updatePreviewFiles(IProject project)
+			throws CoreException {
+		final List<String> filesToPackage = new ArrayList<String>();
+		try {
+			updatePreviewSupportFiles(project);
+			project.accept(new IResourceVisitor() {
+
+				public boolean visit(IResource resource) throws CoreException {
+					if (resource instanceof IFile) {
+						IFile file = (IFile) resource;
+						boolean add = true;
+						// skip user-excluded and automatically-excluded files
+						String value = file
+								.getPersistentProperty(WRTPackagerConstants.EXCLUDE_PROPERTY);
+						if (value != null) {
+							add = false;
+						}
+						String name = file.getName();
+						// skip Aptana temporarily generated files
+						if (name.startsWith(".tmp_")) {
+							add = false;
+						}
+						// if(name.endsWith(".wgz")){
+						// add = false;
+						// }
+						if (name.equals("Thumbs.db")) {
+							add = false;
+						}
+						if (add) {
+							if (file.getProject().getLocation().toString()
+									.endsWith(file.getProject().getName())) {
+
+								filesToPackage.add(file.getLocation()
+										.toString().substring(
+												file.getProject().getLocation()
+														.toString().length()
+														- file.getProject()
+																.getName()
+																.length()));
+							} else {
+								String projectDir = file.getProject()
+										.getLocation().toString().substring(
+												file.getProject().getLocation()
+														.toString()
+														.lastIndexOf("/") + 1);
+								String fullpath = file.getFullPath().toString();
+								fullpath = fullpath.substring(fullpath
+										.indexOf(file.getProject().getName())
+										+ file.getProject().getName().length());
+								fullpath = projectDir + fullpath;
+								filesToPackage.add(fullpath);
+
+							}
+						}
+					}
+					return true;
+				}
+			});
+		} catch (CoreException x) {
+			Activator.log(IStatus.ERROR, "Error updating widget preview", x);
+		}
+	}
+	
+	private boolean isInfoPList(IResource resource) {
+		return INFO_PLIST.equalsIgnoreCase(resource.getProjectRelativePath().toString());
+	}
+	
+	private IFile getMainHTML(IProject project) {
+		IFile result = null;
+		try {
+			String mainHtmlName = project.getPersistentProperty(PreviewSupport.MAIN_HTML_PROPERTY);
+			if (mainHtmlName != null) {
+				IResource resource = project.findMember(mainHtmlName, false);
+				if (resource != null && resource instanceof IFile) {
+					result = (IFile) resource;
+				} else {
+					project.setPersistentProperty(PreviewSupport.MAIN_HTML_PROPERTY, null);
+				}
+			}
+			if (result == null) {
+				result = getMainHTMLFromModel(project);
+			}
+		} catch (CoreException x) {
+			Activator.log(IStatus.ERROR, "error getting main html property", x);
+		}
+		return result;
+	}
+	
+	private IFile getMainHTMLFromModel(IProject project) {
+		IFile result = null;
+		if(model == null)
+			model = getModel(project);
+		String mainHtml = model.getMainHtml();
+		if(mainHtml != null) {
+			IResource resource = project.findMember(mainHtml, false);
+			if (resource != null && resource instanceof IFile) {
+				try {
+					project.setPersistentProperty(PreviewSupport.MAIN_HTML_PROPERTY, mainHtml);
+					result = (IFile) resource;
+				}catch (CoreException x) {
+					Activator.log(IStatus.ERROR, "error setting file persistent property", x);
+				}
+			}else{
+				try {
+					project.setPersistentProperty(PreviewSupport.MAIN_HTML_PROPERTY, null);
+					result = (IFile) resource;
+				}catch (CoreException x) {
+					Activator.log(IStatus.ERROR, "error setting file persistent property", x);
+				}
+			}
+		}
+		return result;
+	}
+	
+	private WidgetModel getModel(IProject project) {
+		WidgetModel model = new WidgetModel();
+		String path = project.getLocation().toString();
+		model.setWidgetDirectory(path);
+		try {
+			model.getWidgetModel(new File(path));
+		} catch (ValidationException x) {
+			Activator.log(IStatus.ERROR, "invalid widget", x);
+		}
+		return model;
+	}
+	
+	private String readFileIntoString(File file) throws CoreException, FileNotFoundException {
+		InputStream is = new FileInputStream(file);
+		return new String(FileUtils.readInputStreamContents(is, "UTF-8"));
+	}
+
+	private void setFileFromString(IFile file, String contents) throws UnsupportedEncodingException, CoreException {
+		ByteArrayInputStream is = new ByteArrayInputStream(contents.getBytes("UTF-8"));
+		if (!file.exists()) {
+			file.create(is, true, new NullProgressMonitor());
+		} else {
+			file.setContents(is, true, false, new NullProgressMonitor());
+		}
+	}
+	
+	private void updatePreviewSupportFiles(IProject project) {
+		try {
+			PreviewSupport ps = new PreviewSupport(project);
+			IFolder previewFolder = ps.getPreviewFolder();
+			IProgressMonitor progressMonitor = new NullProgressMonitor();
+			IProject projects[] = ResourcesPlugin.getWorkspace().getRoot().getProjects();
+			
+			if (previewFolder.exists()) {
+				// Use File-based utility since IFolder.delete doesn't always delete subfolders
+				FileUtils.delTree(previewFolder.getLocation().toFile());
+				previewFolder.refreshLocal(IResource.DEPTH_INFINITE, progressMonitor);
+				for(int u=0; u < projects.length; u++){
+					projects[u].refreshLocal(IResource.DEPTH_INFINITE, progressMonitor);
+				}
+			}
+			if(!previewFolder.isSynchronized(IResource.DEPTH_INFINITE)){
+				for(int u=0; u < projects.length; u++){
+					projects[u].refreshLocal(IResource.DEPTH_INFINITE, progressMonitor);
+				}
+				previewFolder.getProject().refreshLocal(IResource.DEPTH_INFINITE, progressMonitor);
+				previewFolder.getParent().refreshLocal(IResource.DEPTH_INFINITE, progressMonitor);
+				previewFolder.refreshLocal(IResource.DEPTH_INFINITE, progressMonitor);
+			}
+			//No need to delete empty folder, we will reuse the same folder for copying new files and sub folders into this.
+			//previewFolder.delete(IResource.FORCE|IFolder.INCLUDE_TEAM_PRIVATE_MEMBERS|IContainer.INCLUDE_PHANTOMS, progressMonitor);
+			
+			if(!previewFolder.isSynchronized(IResource.DEPTH_INFINITE)){
+				for(int u=0; u < projects.length; u++){
+					projects[u].refreshLocal(IResource.DEPTH_INFINITE, progressMonitor);
+				}
+				previewFolder.getProject().refreshLocal(IResource.DEPTH_INFINITE, progressMonitor);
+				previewFolder.getParent().refreshLocal(IResource.DEPTH_INFINITE, progressMonitor);
+				previewFolder.refreshLocal(IResource.DEPTH_INFINITE, progressMonitor);
+			}
+			// No need to create preview folder as we are using existing empty preview folder and copying into that 
+			//previewFolder.create(true, false, progressMonitor);
+			
+			if(!previewFolder.isSynchronized(IResource.DEPTH_INFINITE)){
+				for(int u=0; u < projects.length; u++){
+					projects[u].refreshLocal(IResource.DEPTH_INFINITE, progressMonitor);
+				}
+				previewFolder.getProject().refreshLocal(IResource.DEPTH_INFINITE, progressMonitor);
+				previewFolder.getParent().refreshLocal(IResource.DEPTH_INFINITE, progressMonitor);
+				previewFolder.refreshLocal(IResource.DEPTH_INFINITE, progressMonitor);
+			}
+			previewFolder.setDerived(true);
+			
+			File destRootDir = previewFolder.getLocation().toFile();
+			copyPreviewFiles("/preview", "/preview", destRootDir);
+			//previewFolder.refreshLocal(IResource.DEPTH_INFINITE, progressMonitor);
+			//previewFolder.setPersistentProperty(WRTPackagerConstants.EXCLUDE_PROPERTY, Boolean.TRUE.toString());
+			if(!previewFolder.isSynchronized(IResource.DEPTH_INFINITE)){
+				for(int u=0; u < projects.length; u++){
+					projects[u].refreshLocal(IResource.DEPTH_INFINITE, progressMonitor);
+				}
+				previewFolder.getProject().refreshLocal(IResource.DEPTH_INFINITE, progressMonitor);
+				previewFolder.getParent().refreshLocal(IResource.DEPTH_INFINITE, progressMonitor);
+				previewFolder.refreshLocal(IResource.DEPTH_INFINITE, progressMonitor);
+			}
+			previewFolder.setPersistentProperty(WRTPackagerConstants.EXCLUDE_PROPERTY, Boolean.TRUE.toString());
+
+			
+			previewFolder.accept(new IResourceVisitor() {
+				public boolean visit(IResource r) {
+					try {
+						// inhibit packaging for preview files
+				 		r.setPersistentProperty(WRTPackagerConstants.EXCLUDE_PROPERTY, Boolean.TRUE.toString());
+				 		// inhibit version control for preview files
+				 		r.setDerived(true);
+					} catch (CoreException x) {
+						Activator.log(IStatus.ERROR, "error setting packager property on "+r.getFullPath().toString(), x);
+					}
+					return true;
+				}
+			});
+		}
+		catch (IOException x) {
+			Activator.log(IStatus.ERROR, "Error updating preview support files", x);
+		} catch (CoreException x) {
+			Activator.log(IStatus.ERROR, "Error updating preview support files", x);
+		}
+	}
+	
+	private void copyPreviewFiles(String sourceRootDir, String topRootDir, File destRootDir) throws IOException, CoreException {
+		Bundle bundle = Activator.getDefault().getBundle();
+		Enumeration e = bundle.getEntryPaths(sourceRootDir);
+		if (e != null) {
+			 while (e.hasMoreElements()) {
+			 	String path = (String) e.nextElement();
+			 	// paths indicating subdirectories end with '/'. 
+			 	if (path.endsWith("/")) {
+			 		// need to trim first component off path, which is the base preview dir
+			 		IPath destPath = new Path(path);
+			 		destPath = destPath.removeFirstSegments(1);
+			 		File newDir = new File(destRootDir, destPath.toString());
+			 		newDir.mkdirs();
+			 		copyPreviewFiles(path, topRootDir, destRootDir);
+			 	} else {
+			 		// skip PREVIEW_HTML_TEMPLATE, we don't copy to preview folder
+			 		IPath destPath = new Path(path);
+			 		destPath = destPath.removeFirstSegments(1);			 	
+			 		File newFile = new File(destRootDir, destPath.toString());
+			 		if (!newFile.getName().equals(PreviewSupport.PREVIEW_HTML_TEMPLATE)) {
+			 			InputStream is = openBundleFile(new Path(path));
+			 			FileUtils.copyFile(is, newFile);
+			 		}
+			 	}
+			 }
+		}
+	}
+	
+	private InputStream openBundleFile(IPath path) throws IOException {
+		InputStream is = FileLocator.openStream(Activator.getDefault().getBundle(),
+				path, false);
+		return is;
+	}
+	
+	private void createPreviewFrameHTML(IProject project) throws IOException, CoreException, URISyntaxException {
+		
+		PreviewSupport ps = new PreviewSupport(project);
+		InputStream templateStream = openBundleFile(ps.getPreviewFrameTemplate());
+		String templateText = new String(FileUtils.readInputStreamContents(templateStream, null));
+
+		Map<String, String> vars = new HashMap<String,String>();
+		String previewBasePath = PreviewSupport.PREVIEW_FOLDER + "/";
+		vars.put("preview_base", previewBasePath);
+		VariableSubstitutionEngine engine = new VariableSubstitutionEngine(
+				new DefaultMessageListener(), 
+				new MessageLocation(ps.getProject(), 0, 0));
+		engine.setVariableToken('(');
+		String resultText = engine.substitute(vars, templateText);
+		
+		IFile previewFrame = ps.getPreviewFrameHtml();
+		boolean updateProperty = !previewFrame.exists();
+		setFileFromString(previewFrame, resultText);
+		if (updateProperty) {
+		previewFrame.setPersistentProperty(WRTPackagerConstants.EXCLUDE_PROPERTY, Boolean.TRUE.toString());
+		}
+		previewFrame.setDerived(true);
+	}
+	
+	private void createEmptyPreviewMainHTML(IProject project) throws CoreException, UnsupportedEncodingException, FileNotFoundException {
+		if(previewMainCreated)
+			return;
+		
+		previewMainCreated = true;
+		PreviewSupport ps = new PreviewSupport(project);
+		
+		IFile previewMainHtml = ps.getPreviewMainHtml();
+		
+		setFileFromString(previewMainHtml, "");
+		previewMainHtml.setPersistentProperty(WRTPackagerConstants.EXCLUDE_PROPERTY, Boolean.TRUE.toString());
+		previewMainHtml.setDerived(true);
+		
+	}
+	
+	private void createPreviewMainHTML(IFile src) throws CoreException, UnsupportedEncodingException, FileNotFoundException {
+		
+		PreviewSupport ps = new PreviewSupport(project);
+		File inputFile = src.getLocation().toFile();
+		String contents = readFileIntoString(inputFile);
+		Pattern headPattern = Pattern.compile("<head\\b[^>]*>", Pattern.CASE_INSENSITIVE|Pattern.MULTILINE);
+		
+		String previewBasePath = PreviewSupport.PREVIEW_FOLDER;
+		StringBuffer buf = new StringBuffer();
+		buf.append("\t<script language=\"JavaScript\" type=\"text/javascript\" src=\"" + previewBasePath + "/script/lib/loader.js\"></script>\n");
+		String previewScripts = buf.toString();
+		
+		Matcher matcher = headPattern.matcher(contents);
+		if (matcher.find()) {
+			String replacement = "<head>\n" + previewScripts;
+			contents = matcher.replaceFirst(replacement);
+		} else {
+			Pattern bodyPattern = Pattern.compile("<body\\b[^>]*>", Pattern.CASE_INSENSITIVE|Pattern.MULTILINE);
+			matcher = bodyPattern.matcher(contents);
+			if (matcher.find()) {
+				String replacement = "\n" + previewScripts + "<body>";
+				contents = matcher.replaceFirst(replacement);
+			}
+		}
+		
+		IFile previewMainHtml = ps.getPreviewMainHtml();
+		setFileFromString(previewMainHtml, contents);
+		previewMainHtml.setPersistentProperty(WRTPackagerConstants.EXCLUDE_PROPERTY, Boolean.TRUE.toString());
+		previewMainHtml.setDerived(true);
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/core/validator/WidgetValidator.java	Wed Jan 27 15:05:37 2010 -0800
@@ -0,0 +1,405 @@
+/**
+ * Copyright (c) 2009 Symbian Foundation and/or its subsidiary(-ies).
+ * All rights reserved.
+ * This component and the accompanying materials are made available
+ * under the terms of the License "Eclipse Public License v1.0"
+ * which accompanies this distribution, and is available
+ * at the URL "http://www.eclipse.org/legal/epl-v10.html".
+ *
+ * Initial Contributors:
+ * Symbian Foundation - initial contribution.
+ * Contributors:
+ * Description:
+ * Overview:
+ * Details:
+ * Platforms/Drives/Compatibility:
+ * Assumptions/Requirement/Pre-requisites:
+ * Failures and causes:
+ */
+package org.symbian.tools.wrttools.core.validator;
+
+import java.io.File;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.symbian.tools.wrttools.core.exception.ReportException;
+import org.symbian.tools.wrttools.core.exception.ValidationException;
+import org.symbian.tools.wrttools.core.report.IMessageListener;
+import org.symbian.tools.wrttools.core.report.MessageHandler;
+import org.symbian.tools.wrttools.core.status.IWRTConstants;
+import org.symbian.tools.wrttools.core.status.IWRTStatusListener;
+import org.symbian.tools.wrttools.core.status.WRTStatus;
+import org.symbian.tools.wrttools.core.status.WRTStatusHandler;
+import org.symbian.tools.wrttools.core.widgetmodel.WidgetModel;
+import org.symbian.tools.wrttools.util.Util;
+
+/**
+ * The primary class for client to invoke various validation functionalities.  This is the only
+ * class user to interact.  It has public methods to validate individual files html, plist, 
+ * The methods of WidgetValidator class returns boolean to the calling class.   
+ *  
+ * The primary mechanism (class )for user/client  to invoke  various validation functionalities.
+ * This is the only class user should interact with. It has Public methods for validating individual 
+ * files (Plist, html ). This class provides method for validating a widget project and 
+ * also a widget projectzipfile.
+ * 
+ * Instantiate widget model class here.  Iterate through the directory to get the file names, (.html, .plist, .css, .javascript)
+ * parse through these files to validate.  
+ * Validate to check if 1. .html, .plist are present or not.  
+ *  
+ * .html - will look for valid Document Type Definition (DTD) declaration. 
+ *        (<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">)
+ *  
+ * .plist -  This file will be parsed to verify for the Nokia specific DTD 
+ *        
+ *            1. <key >DisplayName</key> - display name should exist
+ *            2. <key>Identifier</key>  - value should be of com.nokia. **
+ *            3. <key>MainHTML</key>    - value should be same as the .html file name
+ * 
+ *  
+ * @author      sduvvuri
+ * @version     1.0
+ */
+public class WidgetValidator {
+//	private boolean widgetProjetValidation;
+	private boolean manFileVal;
+	private boolean plistVal;
+	private boolean htmlVal;
+	private MandatoryFilesValidator manFilevalidator;
+	private PlistValidator plistValidator;
+	private HtmlValidator htmlValidator;
+	
+	private MessageHandler messageHandler;
+	private IMessageListener msgListener;
+	private WRTStatusHandler statusHandler;
+	private IWRTStatusListener  wrtStatusListener;
+	
+	public List<String> filesSelected;
+	WidgetModel widgetModel;
+	private Logger log = Logger.getLogger(getClass().getName());
+//	  
+	
+			
+	/**
+	 * Class Constructor the packaging process
+	 */
+	public WidgetValidator(IWRTStatusListener  wrtStatusListener) {
+		statusHandler = new WRTStatusHandler();
+		statusHandler.addListener(wrtStatusListener);
+		this.wrtStatusListener = wrtStatusListener;
+	}
+//	
+	
+	/**
+ * Method will validate a widget project.
+ * Accept Variable widgetProjectDirName (Widget Project directory) and enumerate the files, call Individual validation procedures.
+ * Even one validation is failed method will complete all validation and
+ * add message to the message List.
+ * A dummy List<IMessage> is passed as parameter to which the Rule methods will add
+ * messages when a validation rules is failed.
+ * Boolean variable will be returned to indicate the overall status of validation
+ * even if one procedure is failed boolean false will be returned.
+ * If returned value is false then List<IMessage> messageList size will be greater than zero
+ * if returned value is true the List<IMessage> messageList will be empty
+ * creating a dummy list to pass a parameter to the calling method
+ * this list will be used by the rules method to add the validation messages
+ * if any rules validation is failed
+ * 
+ * Passing List <IMessage> messageList will be removed from here.
+ *  
+ * @param fileName
+ * @return
+ * @throws ReportException 
+ * @throws ValidationException 
+ * 
+ */
+	
+	WRTStatus status ;
+	
+	public WidgetValidator(IMessageListener msgListener,
+			IWRTStatusListener wrtStatusListener)
+
+	{
+		log.finest(" WidgetValidator>>--->>");
+		statusHandler = new WRTStatusHandler();
+		statusHandler.addListener(wrtStatusListener);
+		this.setWrtStatusListener(wrtStatusListener);
+		messageHandler = new MessageHandler();
+		messageHandler.registerListener(msgListener);
+		status = new WRTStatus();
+		status.setStatusSource(IWRTConstants.StatusSourceType.VALIDATOR.name());
+		log.finest(" WidgetValidator<<---<<");
+		
+	}
+
+	
+
+	public boolean validateWidgetProject(File widget) throws ValidationException, ReportException  {
+		
+		// Here call the WidgetModel class to return the  file.
+		log.info(" >>--->> validateWidgetProject");		
+		
+		 widgetModel= new WidgetModel();			
+		File widgetProjFile;
+//		MessageHandler	messageHandler.setFileTypeZip(false);
+		
+		try {
+						
+			widgetModel.setMessageHandler(getMessageHandler());
+			widgetModel.setStatusHandler(statusHandler);
+			widgetModel.setFilesSelected(getFilesSelected());
+			
+			 widgetModel.getWidgetModel(widget);
+			 widgetProjFile=widgetModel.getWidgetModelFile();
+			
+		log.info("widgetProjFile   :"+widgetProjFile.getName());
+			log.info(" calling ValidateMandatoryFiles ");
+		
+		ValidateMandatoryFiles(widgetProjFile);
+		log.info("ValidateMandatoryFiles  is done");
+		validatePlist( widgetProjFile);
+		log.info("Validate plist is done");
+		validateHtml( widgetProjFile);	
+		
+		} catch (ReportException e) {
+			 Util.logEvent(log, Level.INFO, e);	
+			 status.setStatusDescription(ValidatorPropMessages.getString("initialize.messagemanager"));
+			statusHandler.emitStatus(status);
+			throw(e);
+		}
+		log.finest("validateWidgetProject <<---<<");
+		
+		if (manFileVal && plistVal && htmlVal) {
+			return true;
+		} else {
+			return false;
+		}
+	}
+	
+	
+	public boolean validateWidgetProject(String widgetNameFullPath) throws ValidationException, ReportException  {
+		
+		// Here call the WidgetModel class to return the  file.
+		log.finest(" >>--->> validateWidgetProject");		
+		 widgetModel= new WidgetModel();			
+		File widgetProjFile;
+//		messageHandler.setFileTypeZip(false);	
+		try {
+			Util.showData(getFilesSelected(), "selected Files");
+						
+			widgetModel.setMessageHandler(getMessageHandler());
+			widgetModel.setStatusHandler(statusHandler);
+			widgetModel.setFilesSelected(getFilesSelected());
+			 widgetModel.getWidgetModel(widgetNameFullPath);
+			 widgetProjFile=widgetModel.getWidgetModelFile();
+			
+		log.info("widgetProjFile   :"+widgetProjFile.getName());
+		
+		ValidateMandatoryFiles(widgetProjFile);
+		validatePlist( widgetProjFile);
+		log.info("Validate plist is done");
+		validateHtml( widgetProjFile);	
+		
+		} catch (ReportException e) {
+			 Util.logEvent(log, Level.INFO, e);	
+//			 status.setStatusDescription(ValidatorPropMessages.getString("initialize.messagemanager"));
+//			statusHandler.emitStatus(status);
+			emitStatus(ValidatorPropMessages.getString("initialize.messagemanager"));
+			throw(e);
+		}
+		log.finest("validateWidgetProject <<---<<");
+		
+		if (manFileVal && plistVal && htmlVal) {
+			return true;
+		} else {
+			return false;
+		}
+	}
+
+/*
+ * ReportHandler related function
+ */
+	
+	public MessageHandler getMessageHandler() throws ReportException {
+		log.finest(" >>---<<");
+		if (messageHandler != null) {
+			return messageHandler;
+		} else {			
+			throw new ReportException(
+					"Message Manager  must be initialized  ");
+		}
+
+	}
+
+
+
+	// Creating new Message List.
+	private boolean ValidateMandatoryFiles(File widgetProjDir) throws ReportException, ValidationException
+			{
+		
+		log.finest("ValidateMandatoryFiles-->>-->>");
+		emitStatus(ValidatorPropMessages.getString("validate.man.file.started"));
+//		statusHandler.emitStatus(status);
+		manFilevalidator = new MandatoryFilesValidator();
+		manFilevalidator.setWidgetModel(widgetModel);
+		manFilevalidator.setSelectedFileList(filesSelected);
+		manFilevalidator.setMessageHandler(getMessageHandler());
+		manFileVal = manFilevalidator.validate(	widgetProjDir);
+
+		
+		emitStatus(ValidatorPropMessages.getString("validate.man.file.finished"));
+//		statusHandler.emitStatus(status);
+		log.finest("ValidateMandatoryFiles <<---<<");
+			
+		return manFileVal;
+	}
+	private boolean validatePlist(File fileName) throws ReportException, ValidationException{
+		log.finest("validatePlist-->>-->>");
+		emitStatus(ValidatorPropMessages.getString("validate.plist.started"));
+		
+//		statusHandler.emitStatus(status);
+		
+
+		plistValidator = new PlistValidator();
+		plistValidator.setWidgetModel(widgetModel);
+		plistValidator.setMessageHandler(getMessageHandler());
+		if (widgetModel.isPlistPresent()) {
+			plistValidator.setFilesToValidate(filesSelected);
+			plistVal = plistValidator.validate( fileName);
+		}
+		emitStatus(ValidatorPropMessages.getString("validate.plist.finished"));
+//		statusHandler.emitStatus(status);
+		
+		
+		log.finest("validatePlist--<<--<<");
+		return plistVal;
+	}
+	
+	
+	private boolean validateHtml(File fileName) throws ReportException {
+		log.info("validateHtml-->>-->>");
+		try{
+		emitStatus(ValidatorPropMessages.getString("validate.html.started"));
+//		statusHandler.emitStatus(status);		
+		htmlValidator=new HtmlValidator();
+		htmlValidator.setWidgetModel(widgetModel);
+		htmlValidator.setMessageHandler(getMessageHandler());
+		
+		if (widgetModel.isHtmlPresent()) {
+			htmlValidator.setHtmlPlistFileName(widgetModel.getMainHtml());
+			htmlVal = htmlValidator.validate( fileName);
+		}
+		log.info("validateHtml--<<--<<");
+		emitStatus(ValidatorPropMessages.getString("validate.html.finished"));
+//		statusHandler.emitStatus(status);
+		} catch (Exception e) {
+			 Util.logEvent(log, Level.INFO, e);	
+			 status.setStatusDescription("Exception "+e.getMessage());
+				
+		}
+		return htmlVal;
+
+	}
+	
+	protected void emitStatus(String statusDescription) {
+		WRTStatus status = new WRTStatus();
+		status.setStatusSource(IWRTConstants.StatusSourceType.VALIDATOR.name());
+		status.setStatusDescription(statusDescription);		
+		getWrtStatusListener().emitStatus(status);
+	}
+	
+	public IMessageListener getMsgListener() {
+		return msgListener;
+	}
+
+
+	public void setMsgListener(IMessageListener msgListener) {
+		this.msgListener = msgListener;
+	}
+
+
+	public IWRTStatusListener getWrtStatusListener() {
+		return wrtStatusListener;
+	}
+
+
+	public void setWrtStatusListener(IWRTStatusListener wrtStatusListener) {
+		this.wrtStatusListener = wrtStatusListener;
+	}
+
+
+	public List<String> getFilesSelected() {
+		return filesSelected;
+	}
+
+
+	public void setFilesSelected(List<String> filesToValidate) {
+		this.filesSelected = filesToValidate;
+		
+		 if (filesSelected != null && filesSelected.size() > 0) {
+				for (String fileName : filesSelected) {
+					fileName= Util.replaceChar(fileName, '\\', '/');
+				}
+			}
+	}
+
+
+	public WidgetModel getWidgetModel() {
+		return widgetModel;
+	}
+
+
+	public void setWidgetModel(WidgetModel widgetModel) {
+		this.widgetModel = widgetModel;
+	}
+
+
+
+
+
+	public void setMessageHandler(MessageHandler messageHandler) {
+		this.messageHandler = messageHandler;
+	}
+	
+	
+	
+
+	
+	///**
+	// * validateWidgetZip function takes zip file as a parameter.
+	// * Enumerate the files, and parse through the files.
+	// * 
+	// * Input parameter List <IMessage> messageList will be removed from here.
+	// * 
+	// * @param zipfile
+	// * @return
+	// * @throws BaseException 
+	// * @throws BaseException 
+	// * @throws ValidatorException 
+	// */	
+//		private boolean validateWidgetZip(String fileName) throws BaseException, ValidatorException{
+//			// HERE need to call the WidgetModel class to return the  file.
+//			log.finest(" validateWidgetZip >>--->>");
+//			WidgetModel widgetModel= new WidgetModel();			
+//			File widgetProjFile;
+////			messageManager.setMessageList(null);
+//			messageManager.setFileTypeZip(true);
+//			widgetProjFile = widgetModel.getWidgetModelFromZip(fileName, getMessageManager());
+//			log.info("widgetProjFile   :"+widgetProjFile.getName());
+//			ValidateMandatoryFiles(widgetProjFile);
+//			validatePlist( widgetProjFile);
+//			log.info("Validate plist is done");
+//			validateHtml( widgetProjFile);	
+//			FileUtil fileUtil = new FileUtil();		
+//			fileUtil.deleteDirFile(  widgetProjFile);
+//			log.finest("validateWidgetZip <<---<<");
+//			
+//			if (manFileVal && plistVal && htmlVal) {
+//				return true;
+//			} else {
+//				return false;
+//			}
+//		}
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/core/widgetmodel/WidgetModel.java	Wed Jan 27 15:05:37 2010 -0800
@@ -0,0 +1,1320 @@
+/**
+ * Copyright (c) 2009 Symbian Foundation and/or its subsidiary(-ies).
+ * All rights reserved.
+ * This component and the accompanying materials are made available
+ * under the terms of the License "Eclipse Public License v1.0"
+ * which accompanies this distribution, and is available
+ * at the URL "http://www.eclipse.org/legal/epl-v10.html".
+ *
+ * Initial Contributors:
+ * Symbian Foundation - initial contribution.
+ * Contributors:
+ * Description:
+ * Overview:
+ * Details:
+ * Platforms/Drives/Compatibility:
+ * Assumptions/Requirement/Pre-requisites:
+ * Failures and causes:
+ */
+
+package org.symbian.tools.wrttools.core.widgetmodel;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.NodeList;
+import org.w3c.tidy.Tidy;
+
+import org.symbian.tools.wrttools.core.exception.BaseException;
+import org.symbian.tools.wrttools.core.exception.ValidationException;
+import org.symbian.tools.wrttools.core.parser.XMLParser;
+import org.symbian.tools.wrttools.core.parser.XMLPlistParser;
+import org.symbian.tools.wrttools.core.parser.XmlElement;
+import org.symbian.tools.wrttools.core.report.Message;
+import org.symbian.tools.wrttools.core.report.MessageHandler;
+import org.symbian.tools.wrttools.core.status.IWRTConstants;
+import org.symbian.tools.wrttools.core.status.WRTStatusHandler;
+import org.symbian.tools.wrttools.core.validator.ValidatorPropMessages;
+import org.symbian.tools.wrttools.util.FileUtil;
+import org.symbian.tools.wrttools.util.Util;
+
+public class WidgetModel {
+	
+	private Logger log = Logger.getLogger(getClass().getName());
+
+	private List<String> filesSelected;
+	private MessageHandler messageHandler;
+	private WRTStatusHandler statusHandler;
+	private File widgetModelFile ;
+	
+	private XmlElement plistXmlFile;
+	
+	private List<String> referencedHtmlFiles = new ArrayList<String>();
+	private List<String> referencedCssFiles = new ArrayList<String>();
+	private List<String> referencedJavaScriptFiles = new ArrayList<String>();
+	private List<String> referencedImageFiles = new ArrayList<String>();
+	private LinkedList<String> referencedHtmlQueue = new LinkedList<String>();
+	private List<String> allReferencedFiles = new ArrayList<String>();
+	private List<String> referencedIFrameFiles = new ArrayList<String>();
+	private List<String> referencedEmbedFiles = new ArrayList<String>();
+
+	public String widgetDirectory;
+	public String widgetName;
+	
+	private String plistFileName;
+	private String displayname;
+	private String identifier;
+	private String version;
+	private String mainHtml;
+	private boolean allowNetworkAccess;
+	private boolean allowFileAccessOutsideOfWidget;
+	
+	private boolean htmlPresent = false;
+	private boolean plistPresent = false;
+
+	private String currentDir ;
+
+
+	private XMLParser htmlParser;
+	//private XmlElement htmlXmlFile;
+	private File htmlXmlFile;
+	FileUtil fileUtil = new FileUtil();
+	private boolean homeScreenValue;
+
+
+	public boolean validateProject(String projPath)throws BaseException{
+		try{
+		boolean plistPresent = false;
+		boolean htmlPresent = false;
+		File srcFile = new File(projPath);		
+//		a validation not to allow user to add root as a widget project
+		String parent = srcFile.getParent();
+		
+		if(parent == null){
+			return false;
+		}
+		getWidgetModel(projPath);
+		plistPresent=this.isPlistPresent();
+		htmlPresent=this.isHtmlPresent();
+		if(!plistPresent)
+		{
+//			System.out.println("plist is not present widget model.");
+			Message msg = new Message();
+			msg.setMessageSource(IWRTConstants.ADDPROJECT);
+			msg.setMessageKey("widgetmodel.plist.notpresent");
+			msg.setMessage(ValidatorPropMessages.getString("widgetmodel.plist.notpresent"));
+			msg.setSeverity(IWRTConstants.FATAL);
+			// need to set all msg fields
+			getMessageHandler().publishMessage(msg);
+			
+		}
+		if(!htmlPresent)
+		{
+//			System.out.println("html is not present widget model.");
+			Message msg = new Message();
+			msg.setMessageSource(IWRTConstants.ADDPROJECT);
+			msg.setMessageKey("widgetmodel.html.notpresent");
+			msg.setMessage(ValidatorPropMessages
+					.getString("widgetmodel.html.notpresent"));
+			msg.setSeverity(IWRTConstants.FATAL);
+			// need to set all msg fields
+			getMessageHandler().publishMessage(msg);
+			
+		}
+		}catch (Exception ex){
+			log.severe("Html file is not present.  ");
+//			ex.printStackTrace();
+		}
+		return (plistPresent && htmlPresent);
+	}
+	
+
+	
+	public List<String> getWidgetModelFromZip(String widgetZipFile) throws ValidationException {
+		log.finest("getWidgetModelFromZip >>--->>");
+		FileUtil fileUtil = new FileUtil();
+		File newFile = fileUtil.unZip(widgetZipFile);
+		log.finest("getWidgetModelFromZip <<---<<");
+		getMessageHandler().setFileTypeZip(true);
+		return getWidgetModel(newFile);
+	}
+	
+	public List<String> getWidgetModelFromZipForWizard(String widgetZipFile) throws ValidationException {
+		log.finest("getWidgetModelFromZip >>--->>");
+		FileUtil fileUtil = new FileUtil();
+		File newFile = fileUtil.unZip(widgetZipFile);
+		log.finest("getWidgetModelFromZip <<---<<");
+		getMessageHandler().setFileTypeZip(true);
+		return getWidgetModelForWizard(newFile);
+	}
+	
+	public List<String> getWidgetModel(String widgetDirPath) throws ValidationException {
+		
+		File widgetModel = new File(widgetDirPath);
+		return getWidgetModel(widgetModel);
+		}
+	/**
+	 * Accepts a zip file and returns a file object.
+	 * @throws ValidationException 
+	 */
+	
+//--------------------------------------------------------------------------------------->>
+	
+	public List<String> getWidgetModel(File widget) throws ValidationException {
+		log.finest("getWidgetModel >>--->>");
+//		showData("getWidgetModel >>--->>  ");	
+		
+		List<File> dirList;
+		File plist;
+		
+		try{
+		 widgetModelFile = widget;
+		 
+		
+			 
+		if (widgetModelFile.isDirectory() && widgetModelFile != null) {
+			// reset all variables
+			reset();
+		
+			// get the widget name and directory.
+	
+		// some times the parent is the dirve itself like c:\	
+			if (widgetModelFile.getParentFile().toString().endsWith("/") 
+					||widgetModelFile.getParentFile().toString().endsWith("\\")) {
+					widgetDirectory = widgetModelFile.getParentFile().getAbsolutePath();
+				} else {
+					widgetDirectory = widgetModelFile.getParentFile().getAbsolutePath()+ "/";
+				}
+			
+			
+//			System.out.println("----widgetDirectory-------1"+widgetDirectory);		
+			widgetDirectory = Util.replaceChar(widgetDirectory, '\\', '/');
+			widgetName = widgetModelFile.getName();
+			
+			// get the dir list of widget
+			dirList = fileUtil.getCurrDirFiles(widgetModelFile);
+			
+			// find the plist file.
+			plist = getPlistfile(dirList);
+			
+			
+			htmlParser = new XMLParser();
+			XMLPlistParser plistXMLParser= new  XMLPlistParser();
+			htmlXmlFile=null;
+			try {
+				if (plist != null) {
+					plistXmlFile = plistXMLParser.parseXML(plist);
+					setPlistElements(plistXmlFile);
+					setPlistFileName(plist.getName());
+					
+					File mailHtmlfile = new File(widgetDirectory + widgetName	+ "/" + mainHtml);
+					if (mailHtmlfile != null && mailHtmlfile.length() > 0) {
+						//htmlParser = new XMLParser();
+						//htmlXmlFile = htmlParser.parseXML(mailHtmlfile);
+												
+						htmlXmlFile = mailHtmlfile;
+						if(htmlXmlFile!=null) {
+						currentDir="";						
+						callAllreference(htmlXmlFile);
+						while (referencedHtmlQueue != null	&& !referencedHtmlQueue.isEmpty()) {
+							
+							String htmlRef = referencedHtmlQueue.poll();
+							if (htmlRef != null && htmlRef.length() > 0) {
+								File refHtmlfile = new File(widgetDirectory+ widgetName + "/" + htmlRef.trim());
+								if(refHtmlfile.exists()){
+								currentDir=refHtmlfile.getAbsolutePath().substring(0,refHtmlfile.getAbsolutePath().indexOf(refHtmlfile.getName())) ;								htmlParser = new XMLParser();
+								currentDir=Util.replaceChar(currentDir, '\\', '/');
+								currentDir=currentDir.substring(currentDir.indexOf(widgetDirectory + widgetName)+(widgetDirectory + widgetName).length()) ;
+								if(currentDir.trim().equals("/"))currentDir="";
+								//XmlElement refHtmlXmlFile = null;
+								//refHtmlXmlFile = htmlParser.parseXML(refHtmlfile);
+								
+								callAllreference(refHtmlfile);
+								}else{
+									showData("htmlXmlFile is not present");
+									Message msg = new Message();
+									msg.setMessageSource(IWRTConstants.VALIDATOR);
+									msg.setMessageKey("WidgetModel.refrenced.html.missing");
+									msg.setMessage(ValidatorPropMessages
+											.getString("WidgetModel.refrenced.html.missing"));
+									msg.setFileTypeZip(getMessageHandler().isFileTypeZip());
+									msg.setTargetObject(htmlRef);
+									msg.setFullPath(null);
+									msg.setSeverity(IWRTConstants.WARN);
+									// need to set all msg fields
+									getMessageHandler().publishMessage(msg);
+									log.severe("The input file " + widgetModelFile
+											+ " is not a directory or does not exist.  ");
+									
+								}
+								
+							}
+						}					
+						}else {
+							showData(" htmlXmlFile null");
+						}
+					} else {
+						showData("Main Html  File is not present ");
+
+					}// ----end html null
+				} else {
+					
+					showData("Plist   File is not present ");
+
+				}// ---end if plist null
+				displayModel();
+
+			} catch (IOException e) {
+				log.severe("The input file " + widgetModelFile
+						+ " is not a directory or does not exist.  ");
+//				e.printStackTrace();
+			}
+
+			log.finest("getWidgetModel <<---<<");
+			
+			allReferencedFiles.addAll(referencedHtmlFiles);
+			allReferencedFiles.addAll(referencedJavaScriptFiles);
+			allReferencedFiles.addAll(referencedCssFiles);
+			allReferencedFiles.addAll(referencedImageFiles);
+			allReferencedFiles.addAll(referencedIFrameFiles);
+			allReferencedFiles.addAll(referencedEmbedFiles);
+			
+			
+			return allReferencedFiles;
+		} else {
+
+			Message msg = new Message();
+			msg.setMessageSource(IWRTConstants.VALIDATOR);
+			msg.setMessageKey("WidgetModel.File.NotDirectory");
+			msg.setMessage(ValidatorPropMessages
+					.getString("WidgetModel.File.NotDirectory"));
+			msg.setRecommendAction(ValidatorPropMessages
+					.getString("todo.widgetmodel"));
+			msg.setFileTypeZip(getMessageHandler().isFileTypeZip());
+			msg.setTargetObject(widget.getName());
+			msg.setFullPath(null);
+			msg.setSeverity(IWRTConstants.FATAL);
+			// need to set all msg fields
+			getMessageHandler().publishMessage(msg);
+			log.severe("The input file " + widgetModelFile
+					+ " is not a directory or does not exist.  ");
+		
+			throw new ValidationException(
+					"No directory found for the given input file  "
+							+ widget);
+		}
+		}finally{
+
+			 dirList=null;
+			 plist=null;
+			log.finest("getWidgetModel <<---<<");
+			
+		}
+
+	}
+
+
+	public List<String> getWidgetModelForWizard(File widget) throws ValidationException {
+		List<File> dirList;
+		File plist;
+		try{
+		 widgetModelFile = widget;
+		 
+		if (widgetModelFile.isDirectory() && widgetModelFile != null) {
+			// reset all variables
+			reset();
+		
+			// get the widget name and directory.
+	
+			// some times the parent is the dirve itself like c:\	
+			if (widgetModelFile.getParentFile().toString().endsWith("/") 
+					||widgetModelFile.getParentFile().toString().endsWith("\\")) {
+					widgetDirectory = widgetModelFile.getParentFile().getAbsolutePath();
+				} else {
+					widgetDirectory = widgetModelFile.getParentFile().getAbsolutePath()+ "/";
+				}
+			
+			
+			widgetDirectory = Util.replaceChar(widgetDirectory, '\\', '/');
+			widgetName = widgetModelFile.getName();
+			
+			// get the dir list of widget
+			dirList = fileUtil.getCurrDirFiles(widgetModelFile);
+			
+			// find the plist file.
+			plist = getPlistfile(dirList);
+			
+			
+			htmlParser = new XMLParser();
+			XMLPlistParser plistXMLParser= new  XMLPlistParser();
+			try {
+				if (plist != null) {
+					plistXmlFile = plistXMLParser.parseXML(plist);
+					setPlistElements(plistXmlFile);
+					setPlistFileName(plist.getName());
+
+				} else {
+					
+					showData("Plist   File is not present ");
+
+				}// ---end if plist null
+			displayModel();
+
+			} catch (IOException e) {
+				log.severe("The input file " + widgetModelFile
+						+ " is not a directory or does not exist.  ");
+			}
+			return allReferencedFiles;
+		} else {
+
+			Message msg = new Message();
+			msg.setMessageSource(IWRTConstants.VALIDATOR);
+			msg.setMessageKey("WidgetModel.File.NotDirectory");
+			msg.setMessage(ValidatorPropMessages
+					.getString("WidgetModel.File.NotDirectory"));
+			msg.setRecommendAction(ValidatorPropMessages
+					.getString("todo.widgetmodel"));
+			msg.setFileTypeZip(getMessageHandler().isFileTypeZip());
+			msg.setTargetObject(widget.getName());
+			msg.setFullPath(null);
+			msg.setSeverity(IWRTConstants.FATAL);
+			// need to set all msg fields
+			getMessageHandler().publishMessage(msg);
+			log.severe("The input file " + widgetModelFile
+					+ " is not a directory or does not exist.  ");
+		
+			throw new ValidationException(
+					"No directory found for the given input file  "
+							+ widget);
+		}
+		}finally{
+
+			 dirList=null;
+			 plist=null;
+			log.finest("getWidgetModel <<---<<");
+			
+		}
+
+	}
+
+
+	
+	private File getPlistfile(List <File>dirList){
+		String  selectedFileName=null;	
+		log.finest("getPlistfile >>-->>  ");
+//		showData("getPlistfile >>--->>  ");
+//		showData("projDirParenPath  :" + projDirParenPath);
+//		showData("projDirName  :" + projDirName);
+//		filesSelected = fileUtil.getCurrDirFileFullNames(widgetModelFile);
+		List<String> files;
+
+		if(filesSelected!=null&&filesSelected.size()>0){
+			 files=filesSelected;
+			
+		}else{
+			files=fileUtil.getCurrDirFileFullNames(widgetModelFile);	
+		}		
+			for (String fileName : files) {	
+				
+				if (fileName.trim().startsWith(widgetDirectory )) {
+					fileName = fileName.substring((fileName.indexOf( widgetDirectory+widgetName	+ "/")+widgetDirectory.length()+widgetName.length()	+ 1));
+				}
+				if (fileName.trim().startsWith(widgetName+"/")) {
+					fileName = fileName.substring((fileName.indexOf(widgetName	+ "/")+ widgetName.length() + 1));
+				}				
+				if (fileName.contains("\\")||fileName.contains("/")) {
+					continue;
+				}
+				if (fileName.trim().equalsIgnoreCase("info.plist")) {
+					selectedFileName=fileName;
+					return new File (widgetDirectory+widgetName+"/"+fileName);
+				}
+
+			}	
+//		return  fileUtil.getFile(dirList, selectedFileName);
+			return null;
+		
+		}
+	
+	
+	private void setPlistElements(XmlElement rootXml) throws ValidationException {
+			
+		if (rootXml!=null&&rootXml.getChildList()!=null&&rootXml.getChildList().size() == 1) {
+			XmlElement dict = rootXml.getChildList().get(0);
+			XmlElement key = null;
+			boolean miniViewEnable = false;
+			if (dict.getChildList().size() > 1) {
+				for (XmlElement elm : dict.getChildList()) {	
+						
+					if (elm.getName().trim().equalsIgnoreCase("String")) {
+						if (key != null && key.getValue() != null) {												        
+							if (key.getValue().trim().equalsIgnoreCase(	"DisplayName")) {
+								displayname = elm.getValue();
+							}
+							if (key.getValue().trim().equalsIgnoreCase(	"Identifier")) {
+								identifier = elm.getValue();
+							}
+							if (key.getValue().trim().equalsIgnoreCase("Version")) {
+									version = elm.getValue();
+							}
+							if (key.getValue().trim().equalsIgnoreCase(	"MainHTML")) {
+								mainHtml = elm.getValue();
+							}
+							if (key.getValue().trim().equalsIgnoreCase(	"AllowNetworkAccess")) {
+									allowNetworkAccess = new Boolean(elm.getValue());
+							}
+							if (key.getValue().trim().equalsIgnoreCase(	"AllowFileAccessOutsideOfWidget")) {
+								allowFileAccessOutsideOfWidget = new Boolean(elm.getValue());
+							}							
+							if (key.getValue().trim().equalsIgnoreCase(	"MiniViewEnabled")) {
+								homeScreenValue = new Boolean(elm.getValue());
+							}
+							key = null;
+						}
+					} 
+					else if (elm.getName().trim().equalsIgnoreCase("key")) {
+						key = elm;
+						if(key.getName().contains("CFBundle")){
+							key.setName(key.getName().substring(key.getName().indexOf("CFBundle")+8));
+						}
+						if (key.getValue().trim().equalsIgnoreCase(	"MiniViewEnabled")) {
+							miniViewEnable = true;							
+						}
+					}
+					else{
+						if(miniViewEnable){
+							homeScreenValue = new Boolean(elm.getName());
+						}
+					}
+				}
+			}
+			if((mainHtml!=null&&mainHtml.trim().length()==0)||mainHtml==null) {
+                
+                Message msg = new Message();
+                msg.setMessageSource(IWRTConstants.ADDPROJECT);
+                msg.setMessageKey("plist.parsing.error.mainHtmlkey.missing");
+                msg.setMessage(ValidatorPropMessages.getString("plist.parsing.error.mainHtmlkey.missing"));
+                msg.setFileTypeZip(getMessageHandler().isFileTypeZip());                        
+                msg.setSeverity(IWRTConstants.FATAL);
+                // need to set all msg fields
+                getMessageHandler().publishMessage(msg);
+                }
+		}
+	}	
+	
+	
+	private void getHtmlJavaScriptReference(Document doc) {
+		String previousKey=null;
+		String previousValue=null;
+		//Get all elements:
+		//NodeList list = doc.getChildNodes();
+		NodeList list = doc.getElementsByTagName("script");
+		
+		//Get the number of elements:
+		int attrSize = list.getLength();
+		
+		//Loop through all the elements:
+		for (int j = 0; j < attrSize; j++) {
+		    org.w3c.dom.Node attr = list.item(j);
+		    NamedNodeMap arrList = attr.getAttributes();
+		    int len = arrList.getLength();
+		    for(int i  = 0; i <len; i++ ){
+		    	org.w3c.dom.Node curAttr = arrList.item(i);
+				if (curAttr.getNodeName().trim().equalsIgnoreCase("src")){
+					previousKey=curAttr.getNodeName().trim();
+					previousValue=curAttr.getNodeValue().trim();
+				}
+				if (curAttr.getNodeName().trim().equalsIgnoreCase("type")&& (curAttr.getNodeValue().trim().equalsIgnoreCase("text/javascript"))){
+					if(i<len-1 && previousKey!="src"){
+						i++;
+						curAttr = arrList.item(i);
+						if (curAttr.getNodeName().trim().equalsIgnoreCase("src")) {
+							if(!referencedJavaScriptFiles.contains(currentDir+curAttr.getNodeValue().trim())){
+							referencedJavaScriptFiles.add(currentDir+curAttr.getNodeValue().trim());						
+							}
+							previousKey=null;
+							previousValue=null;
+						}
+						}else if(previousKey!=null&&previousKey.equalsIgnoreCase("src")){
+							if(!referencedJavaScriptFiles.contains(currentDir+previousValue.trim())){							
+							referencedJavaScriptFiles.add(currentDir+previousValue.trim());}
+							previousKey=null;
+							previousValue=null;
+						}
+					}
+				}
+			}		
+	}
+	
+	private void getHtmlCssReference(Document doc) {
+		
+			String previousKey=null;
+			String previousValue=null;
+			boolean cssTypeSet=false;
+			boolean cssRefSet=false;
+			String typeKey=null;
+			String typeValue=null;
+			
+			//Get all elements:
+			NodeList list = doc.getElementsByTagName("style");
+			//Get the number of elements:
+			int attrSize = list.getLength();				
+			
+			//Loop through all the elements:
+			for (int i = 0; i < attrSize; i++) {
+			    org.w3c.dom.Node attr = list.item(i);
+			    NamedNodeMap arrList = attr.getAttributes();
+			    int len = arrList.getLength();
+			    for(int j  = len-1; j >= 0; j--){
+			    	org.w3c.dom.Node curAttr = arrList.item(j);
+			    	if (curAttr.getNodeName().trim().equalsIgnoreCase("href")) {					
+						previousKey=attr.getAttributes().getNamedItem("href").getNodeName().trim();
+						previousValue=attr.getAttributes().getNamedItem("href").getNodeValue().trim();
+						cssRefSet=true;
+					}
+				    if (curAttr.getNodeName().trim().equalsIgnoreCase("type")
+							&& curAttr.getNodeValue().trim().equalsIgnoreCase("text/css")) {
+						typeKey=curAttr.getNodeName().trim();
+						typeValue=curAttr.getNodeValue().trim();
+						cssTypeSet=true;
+//							showData("cssTypeSet=true;" + cssTypeSet);
+						if(j<len-1 && previousKey!="href"){
+							j++;
+							curAttr = arrList.item(j);
+							if (curAttr != null && curAttr.getNodeName().trim().equalsIgnoreCase("href")) {
+								if(!curAttr.getNodeValue().startsWith("http://") && !referencedCssFiles.contains(currentDir+curAttr.getNodeValue().trim())){											
+									referencedCssFiles.add(currentDir+curAttr.getNodeValue().trim());
+								}
+								previousKey=null;
+								previousValue=null;
+								cssRefSet=true;
+							}
+							j--;
+						}else if(previousKey!=null&&previousKey.equalsIgnoreCase("src")){
+								
+							if(!curAttr.getNodeValue().startsWith("http://") && !referencedCssFiles.contains(currentDir+previousValue.trim())){							
+							referencedCssFiles.add(currentDir+previousValue.trim());
+							}
+							
+							previousKey=null;
+							previousValue=null;
+							cssRefSet=true;
+						}
+							}
+					}
+			    if(cssTypeSet && !cssRefSet && attr.getNodeValue()!=null&& attr.getFirstChild()!=null && attr.getFirstChild().getNodeValue().contains("import")){
+//						showData("cssTypeSet   :"+ cssTypeSet+ "cssRefSet"+cssRefSet);
+					parseImportString(attr.getFirstChild().getNodeValue());
+				}
+			    getHtmlCssReferenceLinkNode(doc);
+   }
+
+	}
+	
+	private void getHtmlCssReferenceLinkNode(Document doc) {
+		
+		String previousKey=null;
+		String previousValue=null;
+		boolean cssTypeSet=false;
+		boolean cssRefSet=false;
+		String typeKey=null;
+		String typeValue=null;
+		
+		//Get all elements:
+		NodeList list = doc.getElementsByTagName("link");
+		//Get the number of elements:
+		int attrSize = list.getLength();				
+		
+		//Loop through all the elements:
+		for (int i = 0; i < attrSize; i++) {
+		    org.w3c.dom.Node attr = list.item(i);
+		    NamedNodeMap arrList = attr.getAttributes();
+		    int len = arrList.getLength();
+		    for(int j  = len-1; j >= 0; j-- ){
+		    	org.w3c.dom.Node curAttr = arrList.item(j);
+		    	if (curAttr.getNodeName().trim().equalsIgnoreCase("href")) {					
+					previousKey=attr.getAttributes().getNamedItem("href").getNodeName().trim();
+					previousValue=attr.getAttributes().getNamedItem("href").getNodeValue().trim();
+					cssRefSet=true;
+				}
+			    if (curAttr.getNodeName().trim().equalsIgnoreCase("type")
+						&& curAttr.getNodeValue().trim().equalsIgnoreCase("text/css")) {
+					typeKey=curAttr.getNodeName().trim();
+					typeValue=curAttr.getNodeValue().trim();
+					cssTypeSet=true;
+//						showData("cssTypeSet=true;" + cssTypeSet);
+					if(j<len-1 && previousKey!="href"){
+						j++;
+						curAttr = arrList.item(j);
+						if (curAttr.getNodeName().trim().equalsIgnoreCase("href")) {
+							if(!curAttr.getNodeValue().startsWith("http://") && !referencedCssFiles.contains(currentDir+curAttr.getNodeValue().trim())){										
+								referencedCssFiles.add(currentDir+curAttr.getNodeValue().trim());
+							}
+							previousKey=null;
+							previousValue=null;
+							cssRefSet=true;
+						}
+						j--;
+						}else if(previousKey!=null&&previousKey.equalsIgnoreCase("src")){
+							
+							if(!curAttr.getNodeValue().startsWith("http://") && !referencedCssFiles.contains(currentDir+previousValue.trim())){							
+							referencedCssFiles.add(currentDir+previousValue.trim());
+							}
+							
+							previousKey=null;
+							previousValue=null;
+							cssRefSet=true;
+						}
+						}
+				}
+		    if(cssTypeSet && !cssRefSet && attr.getNodeValue()!=null&& attr.getFirstChild()!=null && attr.getFirstChild().getNodeValue().contains("import")){
+//					showData("cssTypeSet   :"+ cssTypeSet+ "cssRefSet"+cssRefSet);
+				parseImportString(attr.getFirstChild().getNodeValue());
+			}
+   }
+
+}
+
+	
+	private void getHtmlImageReference(Document doc) {
+		//Get all elements:
+		NodeList list = doc.getElementsByTagName("img");
+		
+		//Get the number of elements:
+		int attrSize = list.getLength();
+		
+		//Loop through all the elements:
+		for (int i = 0; i < attrSize; i++) {
+		    org.w3c.dom.Node attr = list.item(i);
+		    NamedNodeMap arrList = attr.getAttributes();
+		    for(int j  = 0; j < arrList.getLength(); j++ ){
+		    	if (attr.getNodeName().trim().equalsIgnoreCase("img") && arrList.item(j).getNodeName().equalsIgnoreCase("src")) {					
+		    		if (!referencedImageFiles.contains(currentDir+arrList.item(j).getNodeValue().trim())) {
+						referencedImageFiles.add(currentDir+arrList.item(j).getNodeValue().trim());
+					}
+		    		else if (arrList.item(j).getNodeName().trim().equalsIgnoreCase("background")) {
+						if (!referencedImageFiles.contains(currentDir+arrList.item(j).getNodeValue().trim())) {
+							this.referencedImageFiles.add(currentDir+arrList.item(j).getNodeValue().trim());
+						}
+		    		}
+		    	}
+		    }
+		}
+		    NodeList list1 = doc.getElementsByTagName("style");
+			
+			//Get the number of elements:
+			int attrSize1 = list1.getLength();
+			
+			//Loop through all the elements:
+			for (int i = 0; i < attrSize1; i++) {
+				if(!list1.item(i).getNodeValue().contains(IWRTConstants.IMAGE_REF)){
+					continue;
+				}
+			    org.w3c.dom.Node attr = list1.item(i);
+			    NamedNodeMap arrList = attr.getAttributes();
+			    for(int j  = 0; j < arrList.getLength(); j++ ){
+					String refblock = attr.getNodeValue().trim();
+					refblock = refblock.replace(IWRTConstants.IMAGE_REF, "");
+					while (refblock != null && refblock.trim().length() > 0) {
+						if (refblock.contains("|")) {
+							String block = refblock.substring(0, refblock.indexOf("|"));
+//								showData("Java Image Reference 2     :" + block + ":");
+							if (!referencedImageFiles.contains(currentDir+block.trim())) {
+								referencedImageFiles.add(currentDir+block.trim());
+							}
+							
+							refblock = refblock.substring(refblock.indexOf("|") + 1);
+
+						} else {
+							refblock = null;
+
+						}
+					}// end while.
+		    }
+		}
+	}
+	private void getHtmlIFrameReference(Document doc) {
+		//Get all elements:
+		NodeList list = doc.getElementsByTagName("iframe");
+		
+		//Get the number of elements:
+		int attrSize = list.getLength();
+		
+		//Loop through all the elements:
+		for (int i = 0; i < attrSize; i++) {
+		    org.w3c.dom.Node attr = list.item(i);
+		    NamedNodeMap arrList = attr.getAttributes();
+		    for(int j  = 0; j < arrList.getLength(); j++ ){
+		    	if (attr.getNodeName().trim().equalsIgnoreCase("iframe") && arrList.item(j).getNodeName().equalsIgnoreCase("src")) {					
+		    		if (!referencedIFrameFiles.contains(currentDir+arrList.item(j).getNodeValue().trim())) {
+		    			referencedIFrameFiles.add(currentDir+arrList.item(j).getNodeValue().trim());
+					}
+		    		else if (arrList.item(j).getNodeName().trim().equalsIgnoreCase("background")) {
+						if (!referencedIFrameFiles.contains(currentDir+arrList.item(j).getNodeValue().trim())) {
+							this.referencedIFrameFiles.add(currentDir+arrList.item(j).getNodeValue().trim());
+						}
+		    		}
+		    	}
+		    }
+		}
+	}
+	
+	private void getHtmlEmbedReference(Document doc) {
+		//Get all elements:
+		NodeList list = doc.getElementsByTagName("embed");
+		
+		//Get the number of elements:
+		int attrSize = list.getLength();
+		
+		//Loop through all the elements:
+		for (int i = 0; i < attrSize; i++) {
+		    org.w3c.dom.Node attr = list.item(i);
+		    NamedNodeMap arrList = attr.getAttributes();
+		    for(int j  = 0; j < arrList.getLength(); j++ ){
+		    	if (attr.getNodeName().trim().equalsIgnoreCase("embed") && arrList.item(j).getNodeName().equalsIgnoreCase("src")) {					
+		    		if (!referencedEmbedFiles.contains(currentDir+arrList.item(j).getNodeValue().trim())) {
+		    			referencedEmbedFiles.add(currentDir+arrList.item(j).getNodeValue().trim());
+					}
+		    		else if (arrList.item(j).getNodeName().trim().equalsIgnoreCase("background")) {
+						if (!referencedEmbedFiles.contains(currentDir+arrList.item(j).getNodeValue().trim())) {
+							this.referencedEmbedFiles.add(currentDir+arrList.item(j).getNodeValue().trim());
+						}
+		    		}
+		    	}
+		    }
+		}
+	}
+	
+	/**
+	 * 
+	 * @param rootXmlElement
+	 */
+	
+
+	private void getHtmlReference(Document doc) {
+		
+		
+		//Get all "a" elements:
+		NodeList list = doc.getElementsByTagName("a");
+		
+		//Get the number of elements:
+		int attrSize = list.getLength();
+		
+		//Loop through all the "a" elements:
+		for (int i = 0; i < attrSize; i++) {
+			if(list.item(i).getParentNode().getNodeName().equalsIgnoreCase("script") && list.item(i).getParentNode().getNodeValue() == null){
+				continue;
+			}
+			String href = null;
+			org.w3c.dom.Node attr = list.item(i);
+		    NamedNodeMap arrList = attr.getAttributes();
+		    for(int j  = 0; j < arrList.getLength(); j++ ){
+		    	if (arrList.item(j).getNodeName().equalsIgnoreCase("href")) {
+				//Get the "href" attribute from the current "a" element:
+		    		href = arrList.item(j).getNodeValue();
+					if ((href.toLowerCase().contains(".htm")|| href.toLowerCase().contains(".html")) &&
+						!(href.toLowerCase().startsWith("http://")|| href.toLowerCase().startsWith("https://"))) {
+						String attrValue = arrList.item(j).getNodeValue().trim();
+						if (!referencedHtmlFiles.contains(currentDir+attrValue.toLowerCase())) {
+							referencedHtmlFiles.add(currentDir+attrValue.toLowerCase());
+							referencedHtmlQueue.add(attrValue);
+						}
+					}
+		    	}
+			}
+		}
+	}
+		
+		/**
+		 * call the methods for parsing the references.
+		 * @param refXmlParsedElementFile
+		 */
+	
+	private void callAllreference(File refXmlParsedElementFile){
+		//Stuff needed by Tidy:
+		Tidy tidy = new Tidy();
+		
+		//Get the org.w3c.dom.Document from Tidy:
+		Document doc = null;
+		FileInputStream fis;
+		try {
+			fis = new FileInputStream(refXmlParsedElementFile);
+			doc = tidy.parseDOM(fis, null);
+		} catch (FileNotFoundException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		
+		if(doc != null){
+			//	showData("getHtmlReference ");
+		
+			getHtmlReference(doc);
+			//	showData("getHtmlJavaScriptReference ");
+		
+			getHtmlJavaScriptReference(doc);
+			//	showData("getHtmlCssReference ");
+		
+			getHtmlCssReference(doc);
+			//	showData("getHtmlImageReference ");
+		
+			getHtmlImageReference(doc);
+			//	showData("getHtmlReference ");
+			getHtmlIFrameReference(doc);
+			getHtmlEmbedReference(doc);
+		}
+
+	}
+/**
+ * 
+ * @param importString
+ */
+private void parseImportString(String importString) {
+	
+		while (importString != null && importString.trim().length() > 0) {
+			String block = null;
+			if (importString.contains("@import")) {
+				block = importString.substring(0, importString.indexOf(';'));
+				importString = importString
+						.substring(importString.indexOf(';') + 1);
+			}
+
+			if (block != null && block.contains("@import")) {
+				block = block.replace("@import", "");
+				block = block.replaceAll("\"", "");
+				block = block.replaceAll(";", "");				
+				if (block.trim().endsWith(".css")){
+					if (!referencedCssFiles.contains(currentDir+block.trim())) {
+						referencedCssFiles.add(currentDir+block.trim());
+					}
+				}
+				else if(block.contains("(")){
+					block = block.substring(block.lastIndexOf("(")+1, block.length()-1);
+					if (block.trim().endsWith(".css")){
+						if (!referencedCssFiles.contains(currentDir+block.trim())) {
+							referencedCssFiles.add(currentDir+block.trim());
+						}
+					}
+				}
+			}
+			else{
+				break;
+			}
+			
+			}// end while.
+	}
+		  
+	/**
+	 * 
+	 * @param functionString
+	 */	
+
+private void parseScriptForhtmlRef(String functionString) {
+	
+		while (functionString != null && functionString.trim().length() > 0) {
+			String block = null;
+			if (functionString.toLowerCase().contains(".htm")) {
+				if (functionString.toLowerCase().contains(".html")) {
+					block = functionString.substring(0, functionString
+							.indexOf(".html") + 5);
+				} else {
+					block = functionString.substring(0, functionString
+							.indexOf(".htm") + 4);
+				}
+				functionString = functionString.substring(block.length());
+
+				block = block.trim();
+				if (block.contains("=")) {
+					block = block.substring(block.indexOf('=') + 1);
+					block = block.replaceAll("\"", "");
+					block = block.replaceAll("'", "");
+					// showData("referencedFilesHtml :"+block+":");
+					if (!referencedHtmlFiles.contains(block.trim().toLowerCase())) {
+						referencedHtmlFiles.add(currentDir+block.trim().toLowerCase());
+						referencedHtmlQueue.add(block.trim());
+					}
+				}
+
+			} else {
+				functionString = null;
+			}
+
+		}// end while.
+
+	}// end parceScriptForhtmlRef()
+		
+
+
+public MessageHandler getMessageHandler() throws ValidationException {
+	if(messageHandler==null){
+		messageHandler= new MessageHandler();
+		//throw new ValidationException("Massagehandler is not Set");		
+	}
+		
+		
+	return messageHandler;
+}
+
+
+
+public void setMessageHandler(MessageHandler messageHandler) {
+	this.messageHandler = messageHandler;
+}
+
+
+
+public WRTStatusHandler getStatusHandler() throws ValidationException {
+	if(statusHandler==null){
+//		statusHandler= new WRTStatusHandler();
+	throw new ValidationException("StatusHandler is not Set");	
+	}
+
+	return statusHandler;
+}
+
+
+
+public void setStatusHandler(WRTStatusHandler statusHandler) {
+	this.statusHandler = statusHandler;
+}
+
+
+
+public List<String> getFilesSelected() {
+	return filesSelected;
+}
+
+
+
+public void setFilesSelected(List<String> filesSelected) {
+	this.filesSelected = filesSelected;
+}
+
+		
+		
+
+public String getPlistFileName() {
+	return plistFileName;
+}
+
+
+
+public void setPlistFileName(String plistFileName) {
+	this.plistFileName = plistFileName;
+}
+
+
+
+public String getWidgetDirectory() {
+	return widgetDirectory;
+}
+
+
+
+public void setWidgetDirectory(String widgetDirectory) {
+	this.widgetDirectory = widgetDirectory;
+}
+
+
+
+public String getWidgetName() {
+	return widgetName;
+}
+
+
+
+	public void setWidgetName(String widgetName) {
+		this.widgetName = widgetName;
+	}
+
+	public boolean getHomeScreenValue() {
+		return homeScreenValue;
+	}
+
+	public String getDisplayname() {
+		return displayname;
+	}
+
+	public void setDisplayname(String displayname) {
+		this.displayname = displayname;
+	}
+
+	public void setHomeScreenValue(boolean homeScreenValue) {
+		this.homeScreenValue = homeScreenValue;
+	}
+	
+	public String getIdentifier() {
+		return identifier;
+	}
+
+	public void setIdentifier(String identifier) {
+		this.identifier = identifier;
+	}
+
+	public String getVersion() {
+		return version;
+	}
+
+	public void setVersion(String version) {
+		this.version = version;
+	}
+
+	public String getMainHtml() {
+		return mainHtml;
+	}
+
+	public void setMainHtml(String mainHtml) {
+		this.mainHtml = mainHtml;
+	}
+
+	public boolean isAllowNetworkAccess() {
+		return allowNetworkAccess;
+	}
+
+	public void setAllowNetworkAccess(boolean allowNetworkAccess) {
+		this.allowNetworkAccess = allowNetworkAccess;
+	}
+
+	public boolean isAllowFileAccessOutsideOfWidget() {
+		return allowFileAccessOutsideOfWidget;
+	}
+
+	public void setAllowFileAccessOutsideOfWidget(
+			boolean allowFileAccessOutsideOfWidget) {
+		this.allowFileAccessOutsideOfWidget = allowFileAccessOutsideOfWidget;
+	}
+	
+	
+	public boolean isHtmlPresent() {
+        htmlPresent= false;
+        if(getMainHtml()!=null &&getMainHtml().length()>0){        
+                
+                File mailHtmlfile = new File(widgetDirectory + widgetName        + "/" + mainHtml);
+                if (mailHtmlfile != null && mailHtmlfile.length() > 0) {
+                        htmlPresent= true;
+                }                        
+                mailHtmlfile=null;
+        }                
+        return htmlPresent;
+}
+
+
+	public void setHtmlPresent(boolean htmlPresent) {
+		this.htmlPresent = htmlPresent;
+	}
+
+	public boolean isPlistPresent() {
+		if(getPlistFileName()!=null &&getPlistFileName().length()>0){
+			plistPresent= true;
+		}	else{			
+			plistPresent= false;
+		}	
+		
+		return plistPresent;
+	}
+
+	public void setPlistPresent(boolean plistPresent) {
+		this.plistPresent = plistPresent;
+	}
+	
+
+	public File getWidgetModelFile() {
+		return widgetModelFile;
+	}
+
+	public void setWidgetModelFile(File widgetModelFile) {
+		this.widgetModelFile = widgetModelFile;
+	}
+
+	public List<String> getReferencedHtmlFiles() {
+		return referencedHtmlFiles;
+	}
+
+	public void setReferencedHtmlFiles(List<String> referencedHtmlFiles) {
+		this.referencedHtmlFiles = referencedHtmlFiles;
+	}
+
+	public List<String> getReferencedCssFiles() {
+		return referencedCssFiles;
+	}
+
+	public void setReferencedCssFiles(List<String> referencedCssFiles) {
+		this.referencedCssFiles = referencedCssFiles;
+	}
+
+	public List<String> getReferencedJavaScriptFiles() {
+		return referencedJavaScriptFiles;
+	}
+
+	public void setReferencedJavaScriptFiles(List<String> referencedJavaScriptFiles) {
+		this.referencedJavaScriptFiles = referencedJavaScriptFiles;
+	}
+
+	public List<String> getReferencedImageFiles() {
+		return referencedImageFiles;
+	}
+
+	public void setReferencedImageFiles(List<String> referencedImageFiles) {
+		this.referencedImageFiles = referencedImageFiles;
+	}
+
+	public List<String> getReferencedIFrameFiles() {
+		return referencedIFrameFiles;
+	}
+
+	public void setReferencedIFrameFiles(List<String> referencedIFrameFiles) {
+		this.referencedIFrameFiles = referencedIFrameFiles;
+	}
+	
+	public List<String> getReferencedEmbedFiles() {
+		return referencedEmbedFiles;
+	}
+
+	public void setReferencedEmbedFiles(List<String> referencedEmbedFiles) {
+		this.referencedEmbedFiles = referencedEmbedFiles;
+	}
+	
+	public List<String> getAllReferencedFiles() {
+		return allReferencedFiles;
+	}
+
+	public void setAllReferencedFiles(List<String> allReferencedFiles) {
+		this.allReferencedFiles = allReferencedFiles;
+	}
+
+	public XmlElement getPlistXmlFile() {
+		return plistXmlFile;
+	}
+
+	public void setPlistXmlFile(XmlElement plistXmlFile) {
+		this.plistXmlFile = plistXmlFile;
+	}
+
+	private void reset() {
+		referencedHtmlFiles = new ArrayList<String>();
+		referencedCssFiles = new ArrayList<String>();
+		referencedJavaScriptFiles = new ArrayList<String>();
+		referencedImageFiles = new ArrayList<String>();
+		referencedIFrameFiles = new ArrayList<String>();
+		referencedEmbedFiles = new ArrayList<String>();
+		referencedHtmlQueue = new LinkedList<String>();
+		displayname = null;		
+		identifier = null;
+		version = null;
+		mainHtml = null;
+		allowNetworkAccess = false;
+		allowFileAccessOutsideOfWidget = false;
+		htmlPresent = false;
+		plistPresent = false;
+
+	}
+	
+	private void displayModel() {
+		
+		showData("widgetDirectory                 : "+widgetDirectory);	
+		showData("widgetName                      : "+widgetName);	
+	
+		showData("Plist Filename                  : "+plistFileName);	
+		showData("displayname                     : "+displayname);	
+		showData("identifier                      : "+identifier);
+		showData("version                         : "+version);
+		showData("Main Html  File Name            : "+mainHtml);
+		showData("allowNetworkAccess              : "+allowNetworkAccess);
+		showData("Reference html File              ");
+		for(String refname: referencedHtmlFiles)
+		{	
+			showData("	: "+refname);	
+		}
+		showData("Reference Java Script File ");
+		showData("--------------------------");	
+		for(String refname: referencedJavaScriptFiles)
+		{	
+			showData("	: "+refname);					
+		}	
+		showData("Reference CSS File");	
+		showData("--------------------------");	
+		
+		for(String refname: referencedCssFiles)
+		{	
+			showData("	: "+refname);				
+		}
+		showData("Reference Image  File ");	
+		showData("--------------------------");	
+		for(String refname: this.referencedImageFiles)
+		{	
+		showData("	: "+refname);	
+		}
+			
+		showData("getPlistXmlFile	: "+this.getPlistXmlFile());	
+		//showData("htmlXmlFile	: "+this.getHtmlXmlFile());
+		
+		
+	}
+	
+	
+	  private static void showData(String s) {
+//		System.out.println(s);
+	}
+
+	  public static void main(String[] args)  {
+		  WidgetModel model= new WidgetModel();
+		  try {
+				showData(" ############################################################################################################################# ");
+				model.getWidgetModel( "C:/ModelTest/Flickr");	
+//			model.getWidgetModel( "C:/ModelTest/HelloWorld");
+//			  model.getWidgetModel( "C:/ModelTest/mFootyAmazonPedia.wdgt");
+			  
+//			  model.getWidgetModel( "C:/ModelTest/mFooty");
+//			  model.getWidgetModel( "C:/ModelTest/NokiaRSS");
+//			  model.getWidgetModel( "C:/ModelTest/Widgets/bmi");
+//			  model.getWidgetModel( "C:/ModelTest/blink");
+//			  model.getWidgetModel( "C:/ModelTest/Gmail");			  
+//			  model.getWidgetModel( "C:/ModelTest/MOSH");
+//			  model.getWidgetModel( "C:/ModelTest/AmazonPedia.wdgt");
+//			  model.getWidgetModel( "C:/ModelTest/UniversalDecider");
+//			  model.getWidgetModel( "d:/ModelTest/Beep");
+//				  model.getWidgetModel( "C:/ModelTest/blankPlist");
+//				 model.getWidgetModel( "C:/ModelTest/AmazonPedia.wdgt");
+			  /**
+				List<String> fileNames=null;	
+				FileUtil filehelper = new FileUtil();
+						fileNames=	  filehelper.getCurrDirFileFullNames(new File("C:/ModelTest"));
+				
+						for (String fileName : fileNames) {	
+//							showData("----- Project name -----------"+fileName);
+							
+							if (new File(fileName).isDirectory()) {
+								
+								showData(" ############################################################################################################################# "+fileName);
+								showData(" fileName : "+fileName);								
+								 model.getWidgetModel( fileName);
+									showData("------------------------------------------------------------------------------------------------------------------------------");
+									
+							}
+							
+						}
+						*/
+			  
+			  
+		} catch (ValidationException e) {
+//			e.printStackTrace();
+		}
+		  
+	  }
+
+	  public File getHtmlXmlFile() {
+			return htmlXmlFile;
+		}
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/core/widgetmodel/plist-1.0.dtd	Wed Jan 27 15:05:37 2010 -0800
@@ -0,0 +1,19 @@
+<!ENTITY % plo "(array | data | date | dict | real | integer | string | true | false )" >
+<!ELEMENT plist %plo;>
+<!ATTLIST plist version CDATA "1.0" >
+
+
+<!ELEMENT array (%plo;)*>
+<!ELEMENT dict (key, %plo;)*>
+<!ELEMENT key (#PCDATA)>
+
+
+<!ELEMENT string (#PCDATA)>
+<!ELEMENT data (#PCDATA)>
+<!ELEMENT date (#PCDATA)>
+
+
+<!ELEMENT true EMPTY>
+<!ELEMENT false EMPTY>
+<!ELEMENT real (#PCDATA)>
+<!ELEMENT integer (#PCDATA)>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/previewer/preview/PreviewSupport.java	Wed Jan 27 15:05:37 2010 -0800
@@ -0,0 +1,129 @@
+/**
+ * Copyright (c) 2009 Symbian Foundation and/or its subsidiary(-ies).
+ * All rights reserved.
+ * This component and the accompanying materials are made available
+ * under the terms of the License "Eclipse Public License v1.0"
+ * which accompanies this distribution, and is available
+ * at the URL "http://www.eclipse.org/legal/epl-v10.html".
+ *
+ * Initial Contributors:
+ * Symbian Foundation - initial contribution.
+ * Contributors:
+ * Description:
+ * Overview:
+ * Details:
+ * Platforms/Drives/Compatibility:
+ * Assumptions/Requirement/Pre-requisites:
+ * Failures and causes:
+ */
+
+package org.symbian.tools.wrttools.previewer.preview;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.QualifiedName;
+
+import org.symbian.tools.wrttools.sdt.utils.Check;
+import org.symbian.tools.wrttools.sdt.utils.TrackedResource;
+
+	/**
+	 * This class encapsulates the creation and naming 
+	 * of the preview folder and support files
+	 * @author dpodwall
+	 *
+	 */
+public class PreviewSupport {
+	
+	public static final String PREVIEW_FOLDER = "preview";
+	public static final String PREVIEW_MAIN_HTML = "wrt_preview_main.html";
+	public static final String PREVIEW_FRAME_HTML = "wrt_preview_frame.html";
+	public static final String PREVIEW_HTML_TEMPLATE = "wrt_preview.html";
+	public static final QualifiedName MAIN_HTML_PROPERTY = new QualifiedName("org.symbian.tools.wrttools", "mainHTML");
+	//public static final String PREVIEW_BROWSER_NAME1 = "WRT Widget (S60)";
+	public static final String PREVIEW_BROWSER_NAME =  "Web Runtime (WRT)";
+	
+	private TrackedResource projectTracker;
+	
+	public PreviewSupport(IProject project) {
+		Check.checkArg(project);
+		this.projectTracker = new TrackedResource(project);
+	}
+	
+	public void dispose() {
+		if (projectTracker != null) {
+			projectTracker.dispose();
+		}
+	}
+	
+	public IProject getProject() {
+		return projectTracker.getProject();
+	}
+	
+	/**
+	 * Returns the folder containing preview support files, creating it
+	 * if needed.
+	 * @throws CoreException
+	 */
+	public IFolder getPreviewFolder() throws CoreException {
+		IFolder result = getProject().getFolder(PREVIEW_FOLDER);
+		if (!result.exists()) {
+			result.create(true, true, new NullProgressMonitor());
+		}
+		return result;
+	}
+	
+	/**
+	 * Returns the main file, which is a copy of the user's main html
+	 * file. The copy is modified to include the widget preview environment
+	 * JavaScript files.
+	 * The returned IFile may not exist yet
+	 * @throws CoreException
+	 */
+	public IFile getPreviewMainHtml() throws CoreException {
+		IFile result = getProject().getFile(PREVIEW_MAIN_HTML);
+		return result;
+	}
+	
+	/**
+	 * Returns the preview file, which is the outermost html
+	 * file of the preview environment. It includes the main
+	 * file in an iframe.
+	 * The returned IFile may not exist yet
+	 * @throws CoreException
+	 */
+	public IFile getPreviewFrameHtml() throws CoreException {
+		IFile result = getProject().getFile(PREVIEW_FRAME_HTML);
+		return result;
+	}
+	public IFile getMainHtml() throws CoreException {
+		IFile result = null;
+		String mainFilePath = getProject().getPersistentProperty(MAIN_HTML_PROPERTY);
+		if (mainFilePath != null) {
+			IResource resource = getProject().findMember(mainFilePath);
+			if (resource instanceof IFile) {
+				result = (IFile) resource;
+			}
+		}
+		return result;
+	}
+	
+	/**
+	 * Returns the base path for preview support files
+	 * in the plugin
+	 * @return
+	 */
+	public IPath getPreviewPluginBase() {
+		return new Path("preview");
+	}
+	
+	public IPath getPreviewFrameTemplate() {
+		return getPreviewPluginBase().append(PREVIEW_HTML_TEMPLATE);
+	}
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/sdt/utils/Check.java	Wed Jan 27 15:05:37 2010 -0800
@@ -0,0 +1,129 @@
+/**
+ * Copyright (c) 2009 Symbian Foundation and/or its subsidiary(-ies).
+ * All rights reserved.
+ * This component and the accompanying materials are made available
+ * under the terms of the License "Eclipse Public License v1.0"
+ * which accompanies this distribution, and is available
+ * at the URL "http://www.eclipse.org/legal/epl-v10.html".
+ *
+ * Initial Contributors:
+ * Symbian Foundation - initial contribution.
+ * Contributors:
+ * Description:
+ * Overview:
+ * Details:
+ * Platforms/Drives/Compatibility:
+ * Assumptions/Requirement/Pre-requisites:
+ * Failures and causes:
+ */
+package org.symbian.tools.wrttools.sdt.utils;
+
+import org.symbian.tools.wrttools.sdt.utils.noexport.Messages;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+
+
+/**
+ * Utilities for runtime checking of correctness.
+ * 
+ * @author eswartz
+ *
+ */
+public class Check {
+    /**
+     * Report a failure.  This logs the failure and reports a dialog in debug mode.
+     * 
+     * @param message human-readable message
+     * @param thr the exception to report 
+     */
+    public static void reportFailure(String message, Throwable thr) {
+        try {
+            IStatus status = Logging.newSimpleStatus(1 /* our caller */, 
+                    IStatus.ERROR, 
+                    message,
+                    thr);
+            Logging.log(UtilsPlugin.getDefault(), status);
+            if (Platform.isRunning() && Platform.inDebugMode())
+                Logging.showErrorDialog(Messages.getString("Check.RuntimeError"), null, status); //$NON-NLS-1$
+        } catch (Throwable e) {
+            // ignore: don't recursively fail
+        }
+    }
+    
+    /**
+     * Verify an argument is not null else throw a runtime exception
+     * 
+     * It's not necessary to use this unless you're storing the object 
+     * away for later use -- otherwise just deference it and let the runtime
+     * throw for you!
+     * 
+     * @param obj
+     * @throws NullPointerException
+     */
+    static public void checkArg(Object obj) {
+        if (obj == null) {
+            RuntimeException thr = new NullPointerException();
+            reportFailure(Messages.getString("Check.ArgumentIsNull"), thr); //$NON-NLS-1$
+            throw thr;
+        }
+    }
+
+
+    /**
+     * Verify an argument satisfies a condition else throw a runtime exception
+     * 
+     * @param condition test which must return true
+     * @throws IllegalArgumentException
+     */
+    static public void checkArg(boolean condition) {
+        if (!condition) {
+            RuntimeException thr = new IllegalArgumentException();
+            reportFailure(Messages.getString("Check.ArgumentIsInvalid"), thr); //$NON-NLS-1$
+            throw thr;
+        }
+    }
+    
+    /**
+     * Verify an invariant of object state holds else throw a runtime exception.
+     * This is typically used to verify an object is internally consistent.
+     * 
+     * @param condition test which must return true
+     * @throws IllegalStateException
+     */
+    static public void checkState(boolean condition) {
+        if (!condition) {
+            RuntimeException thr = new IllegalStateException();
+            reportFailure(Messages.getString("Check.ObjectIsInconsistent"), thr); //$NON-NLS-1$
+            throw thr;
+        }
+    }
+
+    /**
+     * Verify an invariant related to promised behavior holds else throw a runtime exception
+     * This is typically used to ensure a client API works as expected.
+     *  
+     * @param condition test which must return true
+     * @throws AssertionError
+     */
+    static public void checkContract(boolean condition) {
+        if (!condition) {
+            AssertionError thr = new AssertionError();
+            reportFailure(Messages.getString("Check.ApiAssertionFailed"), thr); //$NON-NLS-1$
+            throw thr;
+        }
+    }
+
+    /**
+     * Throw a runtime exception to indicate a test on an argument
+     * failed due to another exception.
+     * 
+     * @param thr the throwable that resulted from an argument test
+     * @throws IllegalArgumentException
+     */
+    public static void failedArg(Throwable thr) {
+        IllegalArgumentException exc = new IllegalArgumentException();
+        exc.initCause(thr);
+        throw exc;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/sdt/utils/DefaultMessageListener.java	Wed Jan 27 15:05:37 2010 -0800
@@ -0,0 +1,49 @@
+/**
+ * Copyright (c) 2009 Symbian Foundation and/or its subsidiary(-ies).
+ * All rights reserved.
+ * This component and the accompanying materials are made available
+ * under the terms of the License "Eclipse Public License v1.0"
+ * which accompanies this distribution, and is available
+ * at the URL "http://www.eclipse.org/legal/epl-v10.html".
+ *
+ * Initial Contributors:
+ * Symbian Foundation - initial contribution.
+ * Contributors:
+ * Description:
+ * Overview:
+ * Details:
+ * Platforms/Drives/Compatibility:
+ * Assumptions/Requirement/Pre-requisites:
+ * Failures and causes:
+ */
+package org.symbian.tools.wrttools.sdt.utils;
+
+/**
+ * This provides a default message listener for any routines
+ * that take IMessageListener and forwards its messages directly
+ * to MessageReporting.  So, never register this as a listener to
+ * that class!
+ * @author eswartz
+ *
+ */
+public class DefaultMessageListener implements IMessageListener {
+
+	static final public DefaultMessageListener INSTANCE = new DefaultMessageListener();
+	
+	
+	/* (non-Javadoc)
+	 * @see com.nokia.sdt.utils.IMessageListener#isHandlingMessage(com.nokia.sdt.utils.IMessage)
+	 */
+	public boolean isHandlingMessage(IMessage msg) {
+		// in case this gets added as a MessageReporting listener
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see com.nokia.sdt.utils.IMessageListener#emitMessage(com.nokia.sdt.utils.IMessage)
+	 */
+	public void emitMessage(IMessage msg) {
+		MessageReporting.emitMessage(msg);
+	}
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/sdt/utils/FileUtils.java	Wed Jan 27 15:05:37 2010 -0800
@@ -0,0 +1,851 @@
+/**
+ * Copyright (c) 2009 Symbian Foundation and/or its subsidiary(-ies).
+ * All rights reserved.
+ * This component and the accompanying materials are made available
+ * under the terms of the License "Eclipse Public License v1.0"
+ * which accompanies this distribution, and is available
+ * at the URL "http://www.eclipse.org/legal/epl-v10.html".
+ *
+ * Initial Contributors:
+ * Symbian Foundation - initial contribution.
+ * Contributors:
+ * Description:
+ * Overview:
+ * Details:
+ * Platforms/Drives/Compatibility:
+ * Assumptions/Requirement/Pre-requisites:
+ * Failures and causes:
+ */
+package org.symbian.tools.wrttools.sdt.utils;
+
+import org.eclipse.core.resources.*;
+import org.eclipse.core.runtime.*;
+import org.eclipse.swt.widgets.Shell;
+import org.osgi.framework.Bundle;
+
+import java.io.*;
+import java.net.*;
+import java.util.*;
+
+/**
+ * @author eswartz
+ *
+ */
+public class FileUtils {
+	
+	// special IStatus code for file modified during validateEdit
+	public static final int MODIFIED_FILES_STATUS = 1000;
+	
+    /** Copy files or directories from 'from' to 'to'.  
+     * 
+     * Recursively descends if 'from' is a directory.  
+     * Creates 'from' tail directory in 'to', e.g.:
+     * from = c:/foo/bar
+     * to = c:/temp
+     * 
+     * -->
+     * 
+     * c:/temp/bar
+     * 
+     * @param from
+     * @param to
+     * @param filter the filename filter, or null
+     */
+    public static void copyTree(File from, File to, FileFilter filter) throws IOException {
+        File[] children;
+        
+    	if (!from.exists()) {
+    		throw new IOException ("Source of copy \'" + from.getName() + "\' doesn't exist");
+    	}
+    	
+    	if (to.getCanonicalPath().equals(from.getCanonicalPath())) {
+    		throw new IOException ("\'" + from.getName() + "\' cannot copy to itself");
+    	}
+
+        if (from.isDirectory()) {
+            children = from.listFiles(filter);
+            // just like cp command, if target exist, make a new folder into
+            // the target, copy content into the target folder
+            if (to.exists()) {
+            	if (to.isFile()) {
+            		throw new IOException("Cannot overwrite non-directory \'" + to.getName() + "\' with directory " + from.getName());
+            	}
+            	// copy into new directory name grafted after the existing one
+            	to = new File(to, from.getName());
+            	copyTree(from, to, filter);
+            	return;
+            } else {
+            	// copy into new directory name
+            	to.mkdir();            	
+                for (int i = 0; i < children.length; i++) {
+                    File curto = new File(to, children[i].getName());
+         
+                    copyTree(children[i], curto, filter);
+                }
+                return;
+            }
+        }
+        else {
+        	if (to.isDirectory()) {
+        		to = new File (to, from.getName());
+        	}
+            copyFile(from, to);
+            return;
+        }
+        
+    }
+
+    /** Copy files or directories from 'from' to 'to'.  
+     * 
+     * Recursively descends if 'from' is a directory.  
+     * Does not create 'from' tail directory in 'to', e.g.:
+     * from = c:/foo/bar contains a,b,c
+     * to = c:/temp
+     * 
+     * -->
+     * 
+     * c:/temp/a
+     * c:/temp/b
+     * c:/temp/c
+     * 
+     * @param from
+     * @param to
+     * @param filter the filename filter, or null
+     */
+    public static void copyTreeNoParent(File from, File to, FileFilter filter) throws IOException {
+        File[] files;
+        
+        Check.checkArg(from.isDirectory());
+        
+        files = from.listFiles(filter);
+        to.mkdirs();
+        
+        for (int i = 0; i < files.length; i++) {
+            if (files[i].isDirectory()) {
+                //File curto = new File(to, files[i].getName());
+                //curto.mkdirs();
+                copyTree(files[i], to, filter);
+            }
+            else {
+                File curto = new File(to, files[i].getName());
+                copyFile(files[i], curto);
+            }
+        }
+        
+    }
+    
+    /**
+     * Copy from an input stream to a file
+     * 
+     * @param in
+     * @param to
+     * @throws IOException
+     */
+    public static void copyFile(InputStream in, File to) throws IOException {
+        FileOutputStream out = new FileOutputStream(to);
+        int len;
+        byte[] buffer = new byte[4096];
+        while ((len = in.read(buffer)) != -1) {
+            out.write(buffer, 0, len);
+        }
+        out.close();
+        in.close();
+    }
+
+    /** Copy a single file from 'from' to 'to'
+     * 
+     * @param from
+     * @param to
+     * @throws IOException
+     */
+    public static void copyFile(File from, File to) throws IOException {
+        FileInputStream in = new FileInputStream(from);
+        copyFile(in, to);
+    }
+
+    /** Delete a directory tree recursively.
+     * <p> 
+     * Does not delete file.
+     * @param file start point for deletion -- not itself deleted
+     */
+    public static void delTree(File file) {
+        File[] files = file.listFiles();
+        if (files != null) { 
+            for (int i = 0; i < files.length; i++) {
+                if (files[i].isDirectory()) {
+                    delTree(files[i]);
+                }
+            }
+        }
+        files = file.listFiles();
+        if (files != null) {
+            for (int i = 0; i < files.length; i++) {
+                files[i].delete();
+            }
+        }
+    }
+
+	public static File pluginRelativeFile(Plugin plugin, String file) throws IOException {
+        Check.checkArg(plugin);
+        Bundle bundle = plugin.getBundle();
+        if (bundle == null)
+            return null;
+        URL url = FileLocator.find(bundle, new Path("."), null); //$NON-NLS-1$
+        if (url == null)
+            return null;
+        url = FileLocator.resolve(url);
+        return new File(url.getPath(), file);
+    }
+
+    /** 
+     * Convert the path to a path relative to the base, if possible.
+     * @param rootPath full path to base
+     * @param cpath full path to resource
+     * @return new path (base-relative) or null if not resolvable to base
+     */
+    static public IPath removePrefixFromPath(IPath rootPath, IPath cpath) {
+        if (matchingFirstSegments(rootPath, cpath) == rootPath.segmentCount()) {
+        	IPath suffix = cpath.removeFirstSegments(rootPath.segmentCount());
+        	return suffix.setDevice(null);
+        }
+        return null;
+    }
+
+    /** 
+     * Convert the path to a path in the workspace, if possible.
+     * Either the path comes in as a path pointing inside the
+     * workspace, or we can find a linked resource which aliases
+     * to the same location.
+     * @param cpath full filesystem path to resource
+     * @return new path (workspace-relative) or null if not resolvable to workspace
+     */
+    static public IPath convertToWorkspacePath(IPath cpath) {
+    	return convertToWorkspacePath(cpath, false);
+    }
+    
+    /** 
+     * Convert the path to a path in the workspace, if possible.
+     * Either the path comes in as a path pointing inside the
+     * workspace, or we can find a linked resource which aliases
+     * to the same location.
+     * @param cpath full filesystem path to resource
+     * @param makeCanonical if true, work from the canonical path if possible
+     * (recommended)
+     * @return new path (workspace-relative) or null if not resolvable to workspace
+     */
+    static public IPath convertToWorkspacePath(IPath cpath, boolean makeCanonical) {
+    	return convertToWorkspacePath(cpath, makeCanonical, true);
+    }
+    /** 
+     * Convert the path to a path in the workspace, if possible.
+     * Either the path comes in as a path pointing inside the
+     * workspace, or we can find a linked resource which aliases
+     * to the same location.
+     * @param cpath full filesystem path to resource
+     * @param makeCanonical if true, work from the canonical path if possible
+     * (recommended)
+     * @param resolveLinks if true, look for project paths which reference files outside
+     * the workspace via links (very slow)
+     * @return new path (workspace-relative) or null if not resolvable to workspace
+     */
+    static public IPath convertToWorkspacePath(IPath cpath, boolean makeCanonical, boolean resolveLinks) {
+        if (!Platform.isRunning() || cpath == null)
+            return null;
+        
+        if (makeCanonical) {
+			try {
+				// Since we have a filesystem path, try using the filesystem
+				// and Java's smarter APIs to fix the caps early. 
+				// Watch out for the device being set incorrectly, though.
+				String device = cpath.getDevice();
+				cpath = new Path(cpath.toFile().getCanonicalPath()).setDevice(device);
+			} catch (IOException e) {
+				// Something's wrong with the path; just use it as-is
+			}
+        }
+        
+        IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); 
+        IFile file = root.getFileForLocation(cpath);
+        if (file != null) {
+        	return file.getFullPath().setDevice(null);
+        }
+        
+        if (resolveLinks) {
+	        // try to see if a linked resource points to this
+	        IFile[] files = root.findFilesForLocation(cpath);
+	        IPath newPath = null;
+	        if (files.length > 0)
+	            newPath = files[0].getFullPath().setDevice(null);
+	        else {
+	            IContainer[] folders = root.findContainersForLocation(cpath);
+	            if (folders.length > 0)
+	                newPath = folders[0].getFullPath().setDevice(null);
+	        }
+	        return newPath;
+        }
+        
+        return null;
+    }
+
+    /** 
+     * Convert the full path to a full path inside the workspace, if possible.
+     * (E.g. change a linked resource to the real full path.)
+     * <p>
+     * Either the path comes in as a path pointing inside the
+     * workspace, or we can find a linked resource which aliases
+     * to the same location.
+     * @param cpath full filesystem path
+     * @return same cpath, new path, or null if not resolvable to workspace
+     */
+    static public IPath convertToWorkspaceLocation(IPath cpath) {
+        if (!Platform.isRunning())
+            return null;
+        
+        IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); 
+        IPath rootPath = root.getLocation();
+        IPath newPath = convertToWorkspacePath(cpath);
+        if (newPath == null)
+            return null;
+        
+        // convert to full path
+        return rootPath.append(newPath);
+    }
+
+    /** 
+     * Variant of routine that works with case-insensitive matching.
+     * @see IPath#matchingFirstSegments(IPath) 
+     */
+    public static int matchingFirstSegments(IPath my, IPath anotherPath) {
+    	if (my == null || anotherPath == null)
+    		return 0;
+        int anotherPathLen = anotherPath.segmentCount();
+        int max = Math.min(my.segmentCount(), anotherPathLen);
+        int count = 0;
+        for (int i = 0; i < max; i++) {
+            if (!my.segment(i).equalsIgnoreCase(anotherPath.segment(i))) {
+                return count;
+            }
+            count++;
+        }
+        return count;
+    }
+
+    /**
+     * Map the given file to a path in the current workspace.
+     * @param file
+     * @return the IFile for the file
+     * @deprecated this function is broken since it doesn't resolve linked resources.
+     */
+    public static IFile convertFileToIFile(IContainer container, File file) {
+        IPath path = new Path(file.getAbsolutePath());
+        IPath rootPath = container.getLocation();
+        
+        // this is BUGGY!  Case sensitive for some dumb reason
+        //int match = path.matchingFirstSegments(rootPath);
+        int match = matchingFirstSegments(path, rootPath);
+        Check.checkState(match >= rootPath.segmentCount()); 
+            
+        path = path.removeFirstSegments(match);
+        IFile wsFile = container.getFile(path);
+        return wsFile;
+    }
+    
+    /**
+     * Map the given file to a path in the current workspace.
+     * @param file
+     * @return the IFile for the file, or null if the file is not in the workspace
+     */
+    public static IFile convertFileToIFile(File file) {
+       IPath path = new Path(file.getAbsolutePath());
+        
+        IPath wsPath = convertToWorkspacePath(path, true);
+        if (wsPath != null)
+        	return ResourcesPlugin.getWorkspace().getRoot().getFile(wsPath);
+        
+        return null;
+        
+        /*
+        IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+		IPath rootPath = root.getRawLocation();
+        
+        // this is BUGGY!  Case sensitive for some dumb reason
+        //int match = path.matchingFirstSegments(rootPath);
+        int match = matchingFirstSegments(path, rootPath);
+        if (match < rootPath.segmentCount())
+        	return null;
+            
+        path = path.removeFirstSegments(match);
+        IFile wsFile = root.getFile(path);
+        
+        return wsFile;
+        */
+    }
+    
+    /**
+     * Map the given file to a resource in the current workspace.  This only handles
+     * files that map to known workspace resources.
+     * @param file
+     * @return the IResource for the file, or null if the file is not in the workspace or doesn't
+     * exist.
+     */
+    public static IResource convertFileToExistingResource(File file) {
+       IPath path = new Path(file.getAbsolutePath());
+        
+       IPath wsPath = convertToWorkspacePath(path, true);
+       if (wsPath != null)
+    	   return ResourcesPlugin.getWorkspace().getRoot().findMember(wsPath);
+        
+       return null;
+    }
+    
+    /**
+     * Return the project for the given workspace-relative path.
+     */
+    public static IProject projectForPath(IPath path) {
+    	IProject result = null;
+    	if (path != null) {
+    		IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+    		result = root.getProject(path.segment(0));
+    	}
+    	return result;
+    }
+
+	/**
+	 * Read contents of a file into an array
+	 * @param file
+	 * @param encoding (null = system default)
+	 * @return array of text
+	 * @throws CoreException wrapping java.io.FileException
+	 */
+	public static char[] readFileContents(File file, String encoding) throws CoreException {
+		Check.checkArg(file);
+		FileInputStream fis;
+        try {
+        	fis = new FileInputStream(file);
+        	return readInputStreamContents(fis, encoding);
+        } catch (IOException e) {
+            throw new CoreException(Logging.newStatus(UtilsPlugin.getDefault(), e));
+        }
+	}
+
+	/**
+	 * Read contents of a file into an array
+	 * @param is input stream
+	 * @param encoding (null is system default)
+	 * @return array of text
+	 * @throws CoreException wrapping java.io.FileException
+	 */
+	public static char[] readInputStreamContents(InputStream is, String encoding) throws CoreException {
+		Check.checkArg(is);
+
+		Reader reader;
+		try {
+	    	if (encoding != null)
+	    		reader = new InputStreamReader(is, encoding);
+	    	else
+	    		reader = new InputStreamReader(is);
+	
+	        return readReaderContents(reader);
+		} catch (UnsupportedEncodingException e) {
+            throw new CoreException(Logging.newStatus(UtilsPlugin.getDefault(), e));
+        }
+	}
+	
+	/**
+	 * Read contents of a file into an array
+	 * @param file
+	 * @param encoding (null = system default)
+	 * @return array of text
+	 * @throws CoreException wrapping java.io.FileException
+	 */
+	public static char[] readReaderContents(Reader reader) throws CoreException {
+		Check.checkArg(reader);
+        try {
+            char[] buf = new char[1024];
+            StringBuffer sb = new StringBuffer();
+            int len;
+            while ((len = reader.read(buf)) > 0) {
+                sb.append(buf, 0, len);
+            }
+            reader.close();
+            return sb.toString().toCharArray();
+        } catch (UnsupportedEncodingException e) {
+            throw new CoreException(Logging.newStatus(UtilsPlugin.getDefault(), e));
+        } catch (IOException e) {
+            throw new CoreException(Logging.newStatus(UtilsPlugin.getDefault(), e));
+        }
+	}
+
+	/**
+	 * Write contents of a file from an array
+	 * @param file
+	 * @param encoding (null = system default)
+	 * @throws CoreException wrapping java.io.FileException
+	 */
+	public static void writeFileContents(File file, char[] text, String encoding) throws CoreException {
+		Check.checkArg(file);
+		FileOutputStream fos;
+        try {
+        	fos = new FileOutputStream(file);
+        	writeOutputStreamContents(fos, text, encoding);
+        } catch (IOException e) {
+            throw new CoreException(Logging.newStatus(UtilsPlugin.getDefault(), e));
+        }
+	}
+
+	/**
+	 * Write contents on array to an output stream
+	 * @param os output stream
+	 * @param encoding (null is system default)
+	 * @return array of text
+	 * @throws CoreException wrapping java.io.FileException
+	 */
+	public static void writeOutputStreamContents(OutputStream os, char[] text, String encoding) throws CoreException {
+		Check.checkArg(os);
+
+		Writer writer;
+		try {
+	    	if (encoding != null)
+	    		writer = new OutputStreamWriter(os, encoding);
+	    	else
+	    		writer = new OutputStreamWriter(os);
+	
+	        writeWriterContents(writer, text);
+		} catch (UnsupportedEncodingException e) {
+            throw new CoreException(Logging.newStatus(UtilsPlugin.getDefault(), e));
+        }
+	}
+
+	/**
+	 * Write contents of an array to a file
+	 * @param file
+	 * @param encoding (null = system default)
+	 * @throws CoreException wrapping java.io.FileException
+	 */
+	public static void writeWriterContents(Writer writer, char[] text) throws CoreException {
+		Check.checkArg(writer);
+        try {
+        	try {
+        		writer.write(text, 0, text.length);
+        	} finally {
+        		writer.close();
+        	}
+        } catch (UnsupportedEncodingException e) {
+            throw new CoreException(Logging.newStatus(UtilsPlugin.getDefault(), e));
+        } catch (IOException e) {
+            throw new CoreException(Logging.newStatus(UtilsPlugin.getDefault(), e));
+        }
+	}
+
+
+	/**
+	 * Returns whether pathSegment is a valid part of a path in a Carbide project.
+	 * This checks for file name validity and 
+	 * name only contains alpha-numeric -or- hyphen -or- underscrore -or- dot characters
+	 * 
+	 * @param pathSegment the segment (file or folder name)
+	 * @return true if valid
+	 */
+	public static boolean isValidCarbideProjectPathSegment(String pathSegment) {
+		IWorkspace workspace = ResourcesPlugin.getWorkspace();
+		int typeMask = IResource.FILE | IResource.FOLDER;
+		boolean valid = pathSegment.length() == 0 || 
+			workspace.validateName(pathSegment, typeMask).isOK();
+		if (valid) {
+			for (int i = 0; i < pathSegment.length(); i++) {
+				char c = pathSegment.charAt(i);
+				valid = Character.isLetterOrDigit(c) || (c == '-') || (c == '_');
+				if (!valid)
+					break;
+			}
+		}
+		
+		return valid;
+	}
+	
+	/**
+	 * Resolve a workspace-relative path to correct any problems in
+	 * capitalization.
+	 * @param projectName
+	 * @param wsPath workspace-relative path
+	 * @return resolved path, as far as actual resources exist (the suffix
+	 * may be unchanged if an intervening folder is missing) 
+	 */
+	public static IPath getCanonicalWorkspacePath(IPath wsPath) {
+		IPath resolvedPath = new Path(""); //$NON-NLS-1$
+		IContainer container = ResourcesPlugin.getWorkspace().getRoot();
+		// flag to consume the rest of the path without lookup
+		boolean failed = false;
+		for (String segment : wsPath.segments()) {
+			if (failed || container == null) {
+				resolvedPath = resolvedPath.append(segment);
+				continue;
+			}
+			
+			IResource child = container.findMember(segment);
+			if (child != null) {
+				// found, so correct caps
+				resolvedPath = resolvedPath.append(segment);
+				if (child instanceof IContainer) {
+					container = (IContainer) child;
+				} else {
+					container = null;
+				}
+			} else {
+				// not found: manually search
+				boolean found = false;
+				try {
+					for (IResource member : container.members()) {
+						if (member.getName().equalsIgnoreCase(segment)) {
+							resolvedPath = resolvedPath.append(member.getName());
+							found = true;
+							if (member instanceof IContainer) {
+								container = (IContainer) member;
+							} else {
+								container = null;
+							}
+							break;
+						}
+					}
+				} catch (CoreException e) {
+					// just fail
+				}
+				if (!found) {
+					failed = true;
+					resolvedPath = resolvedPath.append(segment);
+				}
+			}
+		}
+		return resolvedPath;
+	}
+	
+	/**
+	 * This is an analogue to new Path(String) but avoids some bugs in
+	 * the implementation when pathString is a relative path.
+	 * @param pathString
+	 * @return new Path
+	 */
+	public static IPath createPossiblyRelativePath(String pathString) {
+		// canonicalize slashes
+		char[] pathChars = pathString.toCharArray();
+		int offset = 0;
+		for (int i = 0; i < pathChars.length; i++) {
+			if (pathChars[i] == '\\')
+				pathChars[i] = '/';
+		}
+		
+		// The bug is, if "./" appears, then "../"'s after it are dropped,
+		// so get rid of "./" early.  The result will still be relative.
+		while (offset + 2 <= pathChars.length) { 
+			if (pathChars[offset] == '.' && pathChars[offset+1] == '/') {
+				offset += 2;
+			} else {
+				break;
+			}
+		}
+		
+		return new Path(new String(pathChars, offset, pathChars.length - offset));
+	}
+
+	/**
+	 * Tell if the given path refers to a parent directory (e.g.
+	 * contains ".." entries)
+	 * @param path
+	 * @return true if resolved path contains ".."
+	 */
+	public static boolean isPathInParent(IPath path) {
+		// first see if any segments are ".." at all
+		for (int i = 0; i < path.segmentCount(); i++) {
+			if (path.segment(i).equals("..")) { //$NON-NLS-1$
+				// comprehensive check, canonicalizing
+				path = new Path(path.toString());
+				if (path.segmentCount() > 0 && path.segment(0).equals("..")) { //$NON-NLS-1$
+					return true;
+				} else {
+					return false;
+				}
+			}
+		}
+		return false;
+	}
+
+	/**
+	 * Recurse the directory, returning files that match the given filter.
+	 * The directories "." and ".." are filtered out before the filter sees them.
+	 * The filter is passed files and directories, and a directory must
+	 * pass the filter to be recursed.
+	 * @param dir
+	 * @param filter
+	 * @param recordDirectories if true, accepted directories are added to the returned list;
+	 * otherwise, directories are not added to the file list.
+	 * @return array of matching files , never null
+	 */
+	public static File[] listFilesInTree(File dir, FileFilter filter, boolean recordDirectories) {
+		List<File> files = new ArrayList<File>();
+		listFilesInTreeHelper(files, dir, filter, recordDirectories);
+		return (File[]) files.toArray(new File[files.size()]);
+	}
+
+	private static void listFilesInTreeHelper(List<File> files, File dir, FileFilter filter, boolean recordDirectories) {
+		if (recordDirectories)
+			files.add(dir);
+		
+		File[] allEntries = dir.listFiles();
+		if (allEntries == null)
+			return;
+		
+		for (File fileOrDir : allEntries) {
+			if (fileOrDir.getName().equals(".") || fileOrDir.getName().equals("..")) { //$NON-NLS-1$ //$NON-NLS-2$
+				// ignore
+			} else if (fileOrDir.isDirectory()) {
+				if (filter.accept(fileOrDir)) {
+					listFilesInTreeHelper(files, fileOrDir, filter, recordDirectories);
+				}
+			} else if (filter.accept(fileOrDir)) {
+				files.add(fileOrDir);
+			}
+		}
+	}
+	
+	public static URL getParentPathURL(URL url) throws CoreException {
+		URL result;
+		try {
+			String string = url.toString();
+			int loc = string.lastIndexOf('/');
+			result = new URL(string.substring(0, loc + 1));
+		} catch (Exception e) {
+            throw new CoreException(Logging.newStatus(UtilsPlugin.getDefault(), e));
+		}
+		
+		return result;
+	}
+	
+	/**
+	 * Wrapper around {@link FileUtils#validateEdit(IFile[], Shell)} 
+	 * taking a single file. If a modified files multistatus is generated
+	 * the single entry for the single file is retrieved and returned.
+	 */
+	public static IStatus validateEdit(IFile file, Shell context) {
+		IStatus status = validateEdit(new IFile[] {file}, context);
+		if (!status.isOK()) {
+			if (status.isMultiStatus()) {
+				IStatus[] children = status.getChildren();
+				if (children != null && children.length == 1 &&
+					children[0].getSeverity() == IStatus.WARNING &&
+					children[0].getCode() == MODIFIED_FILES_STATUS) {
+					status = children[0];
+				}
+			}
+		}
+		return status;
+	}
+	
+	/**
+	 * Wrapper around {@link IWorkspace#validateEdit(IFile[], Object)}
+	 * Checks if any of the files have been modified by the validate
+	 * operations. If so a MultiStatus is returned with WARNING severity. 
+	 * The code for the multistatus and each child is MODIFIED_FILES_STATUS
+	 * and for each child the message fields is the full workspace
+	 * path to the modified file.
+	 * @param files
+	 * @param context a Shell if UI interaction is allowed
+	 * @return OK status, non-OK status from validateEdit, or a
+	 * MultiStatus with one child for each modified file.
+	 */
+	public static IStatus validateEdit(IFile[] files, Shell context) {
+		List<IFile> readOnly = new ArrayList<IFile>();
+		Map<IFile, Long> timeStamps = new HashMap<IFile, Long>();
+		for (IFile file : files) {
+			if (file.isReadOnly()) {
+				readOnly.add(file);
+				timeStamps.put(file, file.getModificationStamp());
+			}
+		}
+	
+		if (readOnly.isEmpty()) {
+			return Status.OK_STATUS;
+		}
+			
+		IStatus status = ResourcesPlugin.getWorkspace().validateEdit(
+				readOnly.toArray(new IFile[readOnly.size()]), context);
+		if (!status.isOK())
+			return status;
+			
+		List<IFile> modified = new ArrayList<IFile>();
+		for (Map.Entry<IFile, Long> entry : timeStamps.entrySet()) {
+			Long newTimeStamp = entry.getKey().getModificationStamp();
+			if (!newTimeStamp.equals(entry.getValue())) {
+				modified.add(entry.getKey());
+			}
+		}
+		
+		if (modified.size() > 0) {
+			String pluginID = UtilsPlugin.getDefault().getBundle().getSymbolicName();
+			MultiStatus ms = new MultiStatus(pluginID, MODIFIED_FILES_STATUS, "modified files", null);
+			for (IFile file : modified) {
+				String path = file.getFullPath().toString();
+				ms.add(new Status(IStatus.WARNING, pluginID, MODIFIED_FILES_STATUS, path, null));
+			}
+			status = ms;
+		}
+		
+		return status;
+	}
+	
+	/**
+	 * Get the directory used for temporary files.
+	 * @return absolute directory for temporary files, which may be the current directory
+	 */
+	public static File getTemporaryDirectory() {
+		File dir = new File(System.getProperty("java.io.tmpdir", //$NON-NLS-1$
+				System.getProperty("user.dir", "."))); //$NON-NLS-1$ //$NON-NLS-2$
+		try {
+			return dir.getCanonicalFile();
+		} catch (IOException e) {
+			return dir;
+		}
+	}
+	
+	/**
+	 * Get the path in a form amenable to comparing with another path.
+	 * On Win32 hosts, this lowercases the path.  On other hosts, the path is unmodified.
+	 * @param path incoming path or <code>null</code>
+	 * @return path converted to comparison-friendly format, or <code>null</code>
+	 */
+	public static IPath getComparablePath(IPath path) {
+		if (path == null)
+			return null;
+		
+		if (Platform.getOS().equals(Platform.OS_WIN32)) {
+			return new Path(path.toOSString().toLowerCase());
+		}
+		
+		return path;
+	}
+
+	/**
+	 * Get the file extension from path, guaranteed not to return null
+	 * @param path IPath
+	 * @return String non-null
+	 */
+	public static String getSafeFileExtension(IPath path) {
+		String fileExtension = ""; //$NON-NLS-1$
+		if (path != null) {
+			String temp = path.getFileExtension();
+			if (temp != null)
+				fileExtension = temp;
+		}
+		
+		return fileExtension;
+	}
+	
+	/**
+	 * Uses java.io semantics to test existence, because eclipse resources are always case-sensitive, 
+	 * regardless of the file system.
+	 * @param resource {@link IResource}
+	 * @return <code>boolean</code>
+	 */
+	public static boolean exists(IResource resource) {
+		return resource.getLocation().toFile().exists();
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/sdt/utils/IDisposable.java	Wed Jan 27 15:05:37 2010 -0800
@@ -0,0 +1,14 @@
+package org.symbian.tools.wrttools.sdt.utils;
+
+	/**
+	 * Generic interface for disposable objects
+	 *
+	 */
+public interface IDisposable {
+
+	/**
+	 * Disposes of any resources held by the object.
+	 * The object should not be used after dispose has been called.
+	 */
+	void dispose();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/sdt/utils/IMessage.java	Wed Jan 27 15:05:37 2010 -0800
@@ -0,0 +1,71 @@
+/**
+ * Copyright (c) 2009 Symbian Foundation and/or its subsidiary(-ies).
+ * All rights reserved.
+ * This component and the accompanying materials are made available
+ * under the terms of the License "Eclipse Public License v1.0"
+ * which accompanies this distribution, and is available
+ * at the URL "http://www.eclipse.org/legal/epl-v10.html".
+ *
+ * Initial Contributors:
+ * Symbian Foundation - initial contribution.
+ * Contributors:
+ * Description:
+ * Overview:
+ * Details:
+ * Platforms/Drives/Compatibility:
+ * Assumptions/Requirement/Pre-requisites:
+ * Failures and causes:
+ */
+package org.symbian.tools.wrttools.sdt.utils;
+
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IStatus;
+
+/**
+ * This encapsulates generic information about a message
+ * that can be reported to multiple sources (problems view,
+ * etc).
+ * 
+ * @author eswartz
+ *
+ */
+public interface IMessage {
+    static public final int INFO = IStatus.INFO;
+    static public final int WARNING = IStatus.WARNING;
+    static public final int ERROR = IStatus.ERROR;
+    
+    /** Get the severity
+     * @see #INFO
+     * @see #WARNING
+     * @see #ERROR 
+     */
+    int getSeverity();
+    
+    /** Get the message location */
+    MessageLocation getMessageLocation();
+    
+    /** Get the offending file (full path) or null */
+    IPath getLocation();
+    
+    /** Get the offending file (workspace path) or null */
+    IPath getPath();
+    
+    /** Get the line number */
+    int getLineNumber();
+    
+    /** Get the column number */
+    int getColumnNumber();
+    
+    /** Get the message (localized) */
+    String getMessage();
+
+    /** Get the message key, i.e. the non-localized identifier for the message,
+     * for use in testing */
+    String getMessageKey();
+
+    /** Create (and attach) a problem marker */
+    IMarker createMarker(IResource resource, String modelMarkerType);
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/sdt/utils/IMessageListener.java	Wed Jan 27 15:05:37 2010 -0800
@@ -0,0 +1,44 @@
+/**
+ * Copyright (c) 2009 Symbian Foundation and/or its subsidiary(-ies).
+ * All rights reserved.
+ * This component and the accompanying materials are made available
+ * under the terms of the License "Eclipse Public License v1.0"
+ * which accompanies this distribution, and is available
+ * at the URL "http://www.eclipse.org/legal/epl-v10.html".
+ *
+ * Initial Contributors:
+ * Symbian Foundation - initial contribution.
+ * Contributors:
+ * Description:
+ * Overview:
+ * Details:
+ * Platforms/Drives/Compatibility:
+ * Assumptions/Requirement/Pre-requisites:
+ * Failures and causes:
+ */
+package org.symbian.tools.wrttools.sdt.utils;
+
+/**
+ * This interface listens to messages reported from various
+ * parts of Sedona (sourcegen, scripting, ...) which should
+ * be shown to the user.
+ * 
+ * @author eswartz
+ *
+ */
+public interface IMessageListener {
+	/**
+	 * Tell if the message should be emitted by this listener,
+	 * usually true for a solitary listener.  It would return false,
+	 * e.g., if several listeners are attached and each has a particular 
+	 * resource scope for messages, and the given message doesn't match
+	 * this listener's scope. 
+	 */
+	public boolean isHandlingMessage(IMessage msg);
+	
+    /**
+     * Emit a message if #isHandlingMessage() returned true.
+     * @param msg
+     */
+    public void emitMessage(IMessage msg);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/sdt/utils/ITimedTask.java	Wed Jan 27 15:05:37 2010 -0800
@@ -0,0 +1,33 @@
+/**
+ * Copyright (c) 2009 Symbian Foundation and/or its subsidiary(-ies).
+ * All rights reserved.
+ * This component and the accompanying materials are made available
+ * under the terms of the License "Eclipse Public License v1.0"
+ * which accompanies this distribution, and is available
+ * at the URL "http://www.eclipse.org/legal/epl-v10.html".
+ *
+ * Initial Contributors:
+ * Symbian Foundation - initial contribution.
+ * Contributors:
+ * Description:
+ * Overview:
+ * Details:
+ * Platforms/Drives/Compatibility:
+ * Assumptions/Requirement/Pre-requisites:
+ * Failures and causes:
+ */
+package org.symbian.tools.wrttools.sdt.utils; 
+
+/**
+ * Interface for use with Logging.timeTask()
+ * @author eswartz
+ *
+ */
+public interface ITimedTask {
+    /** Get label for logging task */
+    public String getLabel();
+    
+    /** Run the task */
+    public void run();
+    
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/sdt/utils/ListenerList.java	Wed Jan 27 15:05:37 2010 -0800
@@ -0,0 +1,63 @@
+package org.symbian.tools.wrttools.sdt.utils;
+
+import java.util.*;
+
+/**
+ * Utility class for listeners. Implemented with the assumption that
+ * iteration is much more common than adding or removing listeners.
+ *
+ * @param <E> a listener interface
+ */
+public class ListenerList<E>  implements Iterable<E> {
+
+	private ArrayList<E> listeners;
+	
+	public void add(E listener) {
+		if (listeners == null || !listeners.contains(listener)) {
+			ArrayList<E> newList = new ArrayList();
+			if (listeners != null)
+				newList.addAll(listeners);
+			newList.add(listener);
+			listeners = newList;
+		}
+	}
+	
+	public void remove(E listener) {
+		if (listeners == null)
+			return;
+		ArrayList<E> newList = new ArrayList(listeners);
+		newList.remove(listener);
+		listeners = newList;
+	}
+
+	public Iterator<E> iterator() {
+		Iterator<E> result;
+		if (listeners != null) {
+			result = listeners.iterator();
+		}
+		else {
+			// would be nice if this could be a static, but it can't
+			result = new EmptyIterator<E>();
+		}
+		return result;
+	}
+	
+	public int size() {
+		return listeners != null? listeners.size() : 0;
+	}
+	
+	static class EmptyIterator<E> implements Iterator<E> {
+
+		public boolean hasNext() {
+			return false;
+		}
+
+		public E next() {
+			throw new NoSuchElementException();
+		}
+
+		public void remove() {
+			throw new IllegalStateException();
+		}
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/sdt/utils/Logging.java	Wed Jan 27 15:05:37 2010 -0800
@@ -0,0 +1,456 @@
+/**
+ * Copyright (c) 2009 Symbian Foundation and/or its subsidiary(-ies).
+ * All rights reserved.
+ * This component and the accompanying materials are made available
+ * under the terms of the License "Eclipse Public License v1.0"
+ * which accompanies this distribution, and is available
+ * at the URL "http://www.eclipse.org/legal/epl-v10.html".
+ *
+ * Initial Contributors:
+ * Symbian Foundation - initial contribution.
+ * Contributors:
+ * Description:
+ * Overview:
+ * Details:
+ * Platforms/Drives/Compatibility:
+ * Assumptions/Requirement/Pre-requisites:
+ * Failures and causes:
+ */
+package org.symbian.tools.wrttools.sdt.utils;
+
+import org.symbian.tools.wrttools.sdt.utils.noexport.Messages;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.osgi.framework.Bundle;
+
+import java.io.PrintStream;
+import java.util.*;
+
+/**
+ * Utilities for plugins.
+ * 
+ * All of these take a Plugin parameter, which usually requires a call in the
+ * form:
+ * <p>
+ * <code>
+ * Logging.<i>method</i>(MyPlugin.getDefault(), ...);
+ * </code>
+ * </p>
+ * 
+ * If this becomes unwieldly, implement a wrapper method in your plugin class to
+ * access these methods natively:
+ * <p>
+ * 
+ * <pre>
+ * 
+ *  class MyPlugin extends Plugin {
+ *  ...
+ *    void &lt;i&gt;method&lt;/i&gt;(...) {
+ *       Logging.&lt;i&gt;method&lt;/i&gt;(getDefault(), ...);
+ *    }
+ *  ...
+ *  }
+ *  
+ * </pre>
+ * 
+ * </p>
+ * <p>
+ * Then call as:
+ * 
+ * <pre>
+ * 
+ *  MyPlugin.&lt;i&gt;method&lt;/i&gt;(...); 
+ *  
+ * </pre>
+ * 
+ * </p>
+ * 
+ * @author eswartz
+ * 
+ */
+public class Logging {
+
+    /** Tell whether Logging.timeStart() / Logging.timeEnd() / Logging.timeTask() show results
+     *  Can't be final because it's modified from unit tests. */
+    static public boolean SHOW_TIMINGS = false;
+    
+    /** List of ILogListener */
+    static private List listeners = new ArrayList(0);
+    
+    /** Target for log messages when platform is not running
+        This can't be final, it's set from tests */
+    static public PrintStream consoleLog = System.err;
+    /** Always dump log messages to console?  If false, only log when platform not running.
+     * Can't be final because it's modified from unit tests. */
+    static public boolean alwaysLogToConsole = false;
+    
+    static public void addListener(ILogListener listener) {
+        listeners.add(listener);
+    }
+    
+    static public void removeListener(ILogListener listener) {
+        listeners.remove(listener);
+    }
+    
+    /**
+     * Create an IStatus instance eminating from the given plugin
+     * which includes detailed info about the plugin vendor, version, etc.
+     * Every IStatus generated by this class includes this information.
+     * 
+     * Adapted from Java Developer's Guide to Eclipse, Ch. 28
+     * 
+     * @param plugin
+     *            the offending plugin
+     * @param severity
+     *            the severity (IStatus.ERROR, IStatus.WARNING, IStatus.INFO)
+     * @param message
+     *            the localized error string, or null to use
+     *            thr.getLocalizedMessage()
+     * @param thr
+     *            the throwable, or null
+     * @return new IStatus object
+     */
+    static public IStatus newStatus(Plugin plugin, int severity,
+            String message, Throwable thr) {
+        if (message == null) {
+			if (thr != null) {
+				message = thr.getLocalizedMessage();
+			}
+			if (message == null) {
+				message = thr.getClass().getName();
+			}
+        }
+            
+        MultiStatus vitalInfoStatus;
+        
+        if (plugin == null || plugin.getBundle() == null) {
+            return new Status(severity, "???", 0,
+                    message, thr);
+        }
+        
+        Bundle bundle = plugin.getBundle();
+        String symbolicName = bundle.getSymbolicName();
+        String bundleName = "" + bundle.getHeaders().get("Bundle-Name"); //$NON-NLS-1$
+        String bundleVendor = "" + bundle.getHeaders().get("Bundle-Vendor"); //$NON-NLS-1$
+        String bundleVersion = "" + bundle.getHeaders().get("Bundle-Version"); //$NON-NLS-1$
+
+        vitalInfoStatus = new MultiStatus(symbolicName, severity,
+                message, thr);
+
+        // Put new info in separate status containers to force newlines in
+        // dialog
+        vitalInfoStatus.add(new Status(severity, symbolicName, 0, 
+                "Plug-in Vendor: " + bundleVendor, null)); //$NON-NLS-1$
+        vitalInfoStatus.add(new Status(severity, symbolicName, 0,
+                "Plug-in Name: " + bundleName, null)); //$NON-NLS-1$
+        vitalInfoStatus.add(new Status(severity, symbolicName, 0,
+                "Plug-in ID: "  + symbolicName, null)); //$NON-NLS-1$
+        vitalInfoStatus.add(new Status(severity, symbolicName, 0,
+                "Plug-in Version: " + bundleVersion, null)); //$NON-NLS-1$
+
+        return vitalInfoStatus;
+    }
+
+    /**
+     * Create an IStatus instance eminating from the given plugin.
+     * 
+     * @param plugin
+     *            the offending plugin
+     * @param severity
+     *            the severity (IStatus.ERROR,WARNING,INFO)
+     * @param message
+     *            the localized error string
+     * @return new IStatus object
+     */
+    static public IStatus newStatus(Plugin plugin, int severity, String message) {
+        if (message == null)
+            message = ""; //$NON-NLS-1$
+
+        return newStatus(plugin, severity, message, null);
+    }
+
+    
+    /**
+     * Create an IStatus instance wrapping an unwanted exception eminating from
+     * the given plugin.
+     * 
+     * @param plugin
+     *            the offending plugin
+     * @param thr
+     *            the throwable, or null
+     * @return new IStatus object
+     */
+    static public IStatus newStatus(Plugin plugin, Throwable thr) {
+        return newStatus(plugin, IStatus.ERROR, thr.getLocalizedMessage(), thr);
+    }
+
+    /**
+     * Create an IStatus instance without plugin context information
+     * (e.g. for logging) 
+     * 
+     * @param plugin
+     *            the plugin
+     * @param severity
+     *            the severity (IStatus.ERROR,WARNING,INFO)
+     * @param message
+     *            the localized error string
+     * @param thr
+     *            the throwable, or null
+     * 
+     * @return new IStatus object
+     */
+    static public IStatus newSimpleStatus(Plugin plugin, int severity, String message, Throwable thr) {
+        return new Status(severity, plugin.getBundle().getSymbolicName(), 
+                0, message, thr);
+    }
+
+    /**
+     * Create an IStatus instance occurring presumably a number of steps up the
+     * call chain (e.g. library code, for which the current plugin is not
+     * known). We report the class name from the stack trace stored in the
+     * exception.  (Eclipse doesn't have a mechanism for looking up the plugin
+     * from a class (multiple plugins can have the same class).)
+     * 
+     * @param depth
+     *            stack depth relative to thr(0 = caller that created thr, 1 =
+     *            caller's caller...)
+     * @param severity
+     *            the severity (IStatus.ERROR,WARNING,INFO)
+     * @param message
+     *            the localized error string
+     * @param thr
+     *            the throwable (if null, assume depth refers to caller)
+     * 
+     * @return new IStatus object
+     */
+    static public IStatus newSimpleStatus(int depth, int severity, String message, Throwable thr) {
+        StackTraceElement els[];
+        if (thr != null)
+            els = thr.getStackTrace();
+        else {
+            els = new Exception().getStackTrace();
+            depth++;
+        }
+        
+        if (depth >= els.length)
+            depth = els.length - 1;
+
+        String klass = els[depth].getClassName();
+        return new Status(severity, klass, 0, message, thr);
+    }
+
+    /**
+     * Create an IStatus instance occurring presumably a number of steps up the
+     * call chain (e.g. library code, for which the current plugin is not
+     * known). We report the class name from the stack trace stored in the
+     * exception.  (Eclipse doesn't have a mechanism for looking up the plugin
+     * from a class (multiple plugins can have the same class).)
+     * 
+     * @param depth
+     *            stack depth relative to thr(0 = caller that created thr, 1 =
+     *            caller's caller...)
+     * @param thr
+     *            the throwable, or null
+     * 
+     * @return new IStatus object
+     */
+    static public IStatus newSimpleStatus(int depth, Throwable thr) {
+        return newSimpleStatus(depth, IStatus.ERROR, thr.getLocalizedMessage(), thr);
+    }
+
+    /**
+     * Tell if plugin configured for debugging and a debug option is enabled
+     * 
+     * @param plugin
+     *            the offending plugin
+     * @param option
+     *            The debug option to test. The plugin's symbolic name is
+     *            prepended to the option name, e.g.
+     *            "com.nokia.myplugin"+"/"+option
+     * @return true if debugging enabled and option enabled (e.g. defined and
+     *         set to "true")
+     */
+    static public boolean isDebugOptionEnabled(Plugin plugin, String option) {
+        if (plugin == null || !plugin.isDebugging())
+            return false;
+        String filter = Platform.getDebugOption(plugin.getBundle()
+                .getSymbolicName()
+                + "/" + option); //$NON-NLS-1$
+        return (filter != null && "true".equalsIgnoreCase(filter)); //$NON-NLS-1$
+    }
+
+    /**
+     * Send a message to the Error Log or stdout if plugin
+     * not defined or not loaded.
+     * 
+     * @param plugin
+     *            the calling plugin
+     * @param status
+     *            the status object
+     *            
+     */
+    static public void log(Plugin plugin, IStatus status) {
+
+        for (Iterator iter = listeners.iterator(); iter.hasNext();) {
+            ILogListener listener = (ILogListener) iter.next();
+            listener.logging(status, plugin != null ? plugin.getBundle().getSymbolicName() : null);
+        } 
+        
+        boolean logToConsole = alwaysLogToConsole;
+        if (plugin != null && plugin.getLog() != null) {
+            plugin.getLog().log(status);
+        } else {
+            logToConsole = true;
+        }
+        
+        if (consoleLog != null && logToConsole) {
+            consoleLog.println(status.getMessage());
+            if (status.getPlugin() != null)
+                consoleLog.println(Messages.getString("Logging.FromPlugin")+status.getPlugin()); //$NON-NLS-1$
+            if (status.getException() != null) {
+                consoleLog.println(Messages.getString("Logging.DueToException")); //$NON-NLS-1$
+                status.getException().printStackTrace();
+            }
+        }
+    }
+
+    /**
+     * Send a message to the Error Log or stdout 
+     * if a given debug option is enabled.
+     * 
+     * @param plugin
+     *            the calling plugin, or null
+     * @param option
+     *            the debug option to test. The plugin name is prepended to the
+     *            option name, e.g. "com.nokia.myplugin"+"/"+option
+     * @param status
+     *            the status object
+     * @see Logging#isDebugOptionEnabled(Plugin, String)
+     */
+    static public void logIf(Plugin plugin, String option, IStatus status) {
+        if (!isDebugOptionEnabled(plugin, option))
+            return;
+        log(plugin, status);
+    }
+
+    /**
+     * Utility to display an error dialog reporting an IStatus.
+     * 
+     * @param title
+     *          title of dialog (if null, use "Error")
+     * @param message
+     *            concise error message (if null, use status message or status'
+     *            wrapped exception message)
+     * @param status
+     *            the offending status
+     */
+    static public void showErrorDialog(String title, String message, final IStatus status) {
+    	showErrorDialog(null, title, message, status);
+    }
+    
+    /**
+     * Utility to display an error dialog reporting an IStatus.
+     * 
+     * @param shell the parent shell
+     * @param title
+     *          title of dialog (if null, use "Error")
+     * @param message
+     *            concise error message (if null, use status message or status'
+     *            wrapped exception message)
+     * @param status
+     *            the offending status
+     */
+    static public void showErrorDialog(final Shell shell, String title, String message, final IStatus status) {
+    	if (!Platform.isRunning())
+    		return;
+    	
+        if (title == null)
+            title = Messages.getString("Logging.ErrorTitle"); //$NON-NLS-1$
+        
+        if (message == null) {
+            // this leads to a lot of redundant text
+            /*if (status != null) {
+                message = status.getMessage();
+                if (message == null) {
+                    if (status.getException() != null) {
+                        message = status.getException().getLocalizedMessage();
+                        if (message == null)
+                            message = Messages.getString("Logging.NoMessage"); //$NON-NLS-1$
+                    }
+                }
+            }*/
+            message = Messages.getString("Logging.GenericErrorMessage"); //$NON-NLS-1$
+        }
+
+        final String title_ = title;
+        final String message_ = message;
+        
+        // yes, syncExec(): this is presumably an important error
+        // that shouldn't wait for cascading failures to complete
+        Display.getDefault().syncExec(new Runnable() {
+            public void run() {
+                ErrorDialog.openError(shell, title_, message_, status);
+            }
+        });
+    }
+    // stack of start times (n.b.: Stack is a Vector and is synchronized)
+    private static Stack<Long> timeStack = new Stack<Long>();
+    // stack of end times (n.b.: Stack is a Vector and is synchronized)
+    private static Stack<String> timeLabelStack = new Stack<String>();
+    
+    private static long lastTime;
+    
+    /**
+     * Start timing a task, reported to console if Logging#SHOW_TIMINGS is set.
+     * Up to 16 timed tasks can be nested at time.
+     * @param label
+     */
+    public synchronized static void timeStart(String label) {
+    	long currentTime = System.currentTimeMillis(); 
+        if (SHOW_TIMINGS) {
+        	if (currentTime > lastTime + 333 && lastTime != 0) {
+                IStatus status = newSimpleStatus(1, IStatus.INFO, "missing time: " + (currentTime - lastTime) + " ms", null); //$NON-NLS-1$
+                log(UtilsPlugin.getDefault(), status);
+        	}
+            IStatus status = newSimpleStatus(1, IStatus.INFO, label + " start...", null); //$NON-NLS-1$
+            log(UtilsPlugin.getDefault(), status);
+        }
+        timeLabelStack.push(label);
+        timeStack.push(currentTime);
+    	lastTime = currentTime;
+    }
+
+    /**
+     * Stop timing a task, reporting results to console if Logging#SHOW_TIMINGS is set
+     * @return time elapsed in ms
+     */
+    public synchronized static long timeEnd() {
+    	lastTime = System.currentTimeMillis();
+        long elapsed = lastTime - timeStack.pop();
+        String label = timeLabelStack.pop();
+        if (SHOW_TIMINGS) {
+            IStatus status = newSimpleStatus(1, IStatus.INFO, label + " end: " + elapsed + " ms", null); //$NON-NLS-1$ //$NON-NLS-2$
+            log(UtilsPlugin.getDefault(), status);
+        }
+        return elapsed;
+    }
+    
+    /**
+     * Time a task and report results if Logging#SHOW_TIMINGS is set.
+     * @param task
+     * @return elapsed time in milliseconds
+     */
+    public synchronized static long timeTask(ITimedTask task) {
+        timeStart(task.getLabel());
+        long elapsed = 0;
+        try {
+            task.run();
+        } finally {
+            elapsed = timeEnd();
+        }
+        return elapsed;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/sdt/utils/Message.java	Wed Jan 27 15:05:37 2010 -0800
@@ -0,0 +1,250 @@
+/**
+ * Copyright (c) 2009 Symbian Foundation and/or its subsidiary(-ies).
+ * All rights reserved.
+ * This component and the accompanying materials are made available
+ * under the terms of the License "Eclipse Public License v1.0"
+ * which accompanies this distribution, and is available
+ * at the URL "http://www.eclipse.org/legal/epl-v10.html".
+ *
+ * Initial Contributors:
+ * Symbian Foundation - initial contribution.
+ * Contributors:
+ * Description:
+ * Overview:
+ * Details:
+ * Platforms/Drives/Compatibility:
+ * Assumptions/Requirement/Pre-requisites:
+ * Failures and causes:
+ */
+package org.symbian.tools.wrttools.sdt.utils;
+
+import org.symbian.tools.wrttools.sdt.utils.noexport.Messages;
+
+import org.eclipse.core.resources.*;
+import org.eclipse.core.runtime.*;
+
+import java.text.MessageFormat;
+
+
+/**
+ * A message.
+ * <p>
+ * A message is identified by a key, a location,
+ * and a severity.
+ * <p>
+ * When constructing a message, the key is the name of a
+ * property (in this plugin's messages.properties file),
+ * which is used to format a string with the optional arguments.
+ * <p>
+ * The key is retained to identify the message later (e.g.
+ * for unit tests).
+ * 
+ * @author eswartz
+ *
+ */
+public class Message implements IMessage {
+
+    /** Message severity (INFO, WARNING, ERROR) */
+    public int severity;
+    /** Location associated with message */
+    public MessageLocation ref;
+    /** Message key */
+    public String key;
+    /** Expanded and formatted message */
+    public String text;
+    
+    /**
+     * Create a message
+     * @param severity (Message.xxx)
+     * @param ref
+     * @param key message key
+     * @param locMsg localized string (unformatted)
+     * @param args
+     */
+    public Message(int severity, MessageLocation ref, String key, String locMsg, Object[] args) {
+        Check.checkArg(key);
+        Check.checkArg(locMsg);
+        Check.checkArg(ref);
+        this.severity = severity;
+        this.ref = ref;
+        this.key = key;
+        this.text = MessageFormat.format(locMsg, args);
+    }
+
+    /**
+     * Create a message
+     * @param severity (Message.xxx)
+     * @param ref
+     * @param key message key
+     * @param locMsg localized string (unformatted)
+     * @param arg
+     */
+    public Message(int severity, MessageLocation ref, String key, String locMsg, Object arg) {
+        Check.checkArg(key);
+        Check.checkArg(locMsg);
+        Check.checkArg(ref);
+        this.severity = severity;
+        this.ref = ref;
+        this.key = key;
+        if (arg == null)
+            arg = ""; //$NON-NLS-1$
+        this.text = MessageFormat.format(locMsg, new Object[] { arg });
+    }
+
+    /**
+     * Create a message
+     * @param severity (Message.xxx)
+     * @param ref
+     * @param key message key
+     * @param locMsg localized string (unformatted)
+     */
+    public Message(int severity, MessageLocation ref, String key, String locMsg) {
+        Check.checkArg(key);
+        Check.checkArg(locMsg);
+        Check.checkArg(ref);
+        this.severity = severity;
+        this.ref = ref;
+        this.key = key;
+        this.text = locMsg;
+    }
+
+    public String getSeverityString() {
+        if (severity == INFO) return ""; //$NON-NLS-1$
+        else if (severity == WARNING) return Messages.getString("Message.Warning"); //$NON-NLS-1$
+        else return Messages.getString("Message.Error"); //$NON-NLS-1$
+    }
+    
+    /* (non-Javadoc)
+     * @see java.lang.Object#equals(java.lang.Object)
+     */
+    public boolean equals(Object obj) {
+        if (!(obj instanceof Message))
+            return false;
+        Message other = (Message) obj;
+        return other.severity == severity
+            && ((ref == null && other.ref == null)
+                || (ref != null && other.ref != null && other.ref.equals(ref)))
+            && key.equals(other.key)
+            && text.equals(other.text);
+    }
+    
+    /* (non-Javadoc)
+     * @see java.lang.Object#hashCode()
+     */
+    public int hashCode() {
+        return (severity << 20)
+             ^ (ref != null ? ref.hashCode() : 0)
+             ^ key.hashCode()
+             ^ text.hashCode()
+             ^ 0x49482721;
+    }
+    
+    public String toString() {
+        return (ref != null ? ref + ": " : "")  //$NON-NLS-1$ //$NON-NLS-2$
+            + getSeverityString() 
+            + text;
+    }
+
+    /* (non-Javadoc)
+     * @see com.nokia.sdt.component.sourcegen.ISourceGenProblem#getSeverity()
+     */
+    public int getSeverity() {
+        return severity;
+    }
+
+    /* (non-Javadoc)
+     * @see com.nokia.sdt.utils.IMessage#getMessageLocation()
+     */
+    public MessageLocation getMessageLocation() {
+        return ref;
+    }
+    
+    /* (non-Javadoc)
+     * @see com.nokia.sdt.utils.IMessage#getLocation()
+     */
+    public IPath getLocation() {
+        return ref != null ? ref.getLocation() : null;
+    }
+    
+    /* (non-Javadoc)
+     * @see com.nokia.sdt.utils.IMessage#getPath()
+     */
+    public IPath getPath() {
+        return ref != null ? ref.getPath() : null;
+    }
+    
+    /* (non-Javadoc)
+     * @see com.nokia.sdt.component.sourcegen.ISourceGenProblem#getLineNumber()
+     */
+    public int getLineNumber() {
+        return ref != null ? ref.lineNumber : -1;
+    }
+
+    /* (non-Javadoc)
+     * @see com.nokia.sdt.sourcegen.ISourceGenMessage#getColumnNumber()
+     */
+    public int getColumnNumber() {
+        return ref != null ? ref.columnNumber : -1;
+    }
+    
+    /* (non-Javadoc)
+     * @see com.nokia.sdt.component.sourcegen.ISourceGenProblem#getMessage()
+     */
+    public String getMessage() {
+        return text;
+    }
+
+    /* (non-Javadoc)
+     * @see com.nokia.sdt.component.sourcegen.ISourceGenProblem#getMessageKey()
+     */
+    public String getMessageKey() {
+        return key;
+    }
+    
+    /**
+     * Create a problem marker for the message.
+     * @return
+     */
+    public IMarker createMarker(IResource resource, String modelMarkerType) {
+    	try {
+			IMarker marker = resource.createMarker(modelMarkerType);
+			
+			marker.setAttribute(IMarker.PRIORITY, IMarker.PRIORITY_NORMAL);
+			switch (getSeverity()) {
+			case IStatus.ERROR:
+				marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR);
+				break;
+			case IStatus.WARNING:
+				marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_WARNING);
+				break;
+			case IStatus.INFO:
+				marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_INFO);
+				break;
+			}
+			
+			MessageLocation location = getMessageLocation();
+			
+			// remove superfluous tabs and newlines that might be in the message (bug 3152)
+			String message = getMessage().replaceAll("[\t\r\n]+", " "); //$NON-NLS-1$ //$NON-NLS-2$
+			
+			// no resource was located in the workspace, but perhaps
+			// there is info available
+			if (resource == ResourcesPlugin.getWorkspace().getRoot() && location != null && getLineNumber() != 0) {
+				marker.setAttribute(IMarker.MESSAGE, 
+						"(" + location.toShortString() +") " + message); //$NON-NLS-1$ //$NON-NLS-2$
+			}
+			else
+				marker.setAttribute(IMarker.MESSAGE, message);
+	
+			if (getLineNumber() != 0)
+				marker.setAttribute(IMarker.LINE_NUMBER, getLineNumber());
+	    	
+			return marker;
+		} catch (CoreException e) {
+			Logging.log(UtilsPlugin.getDefault(),
+					Logging.newStatus(UtilsPlugin.getDefault(), e));
+			return null;
+		}
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/sdt/utils/MessageLocation.java	Wed Jan 27 15:05:37 2010 -0800
@@ -0,0 +1,152 @@
+/**
+ * Copyright (c) 2009 Symbian Foundation and/or its subsidiary(-ies).
+ * All rights reserved.
+ * This component and the accompanying materials are made available
+ * under the terms of the License "Eclipse Public License v1.0"
+ * which accompanies this distribution, and is available
+ * at the URL "http://www.eclipse.org/legal/epl-v10.html".
+ *
+ * Initial Contributors:
+ * Symbian Foundation - initial contribution.
+ * Contributors:
+ * Description:
+ * Overview:
+ * Details:
+ * Platforms/Drives/Compatibility:
+ * Assumptions/Requirement/Pre-requisites:
+ * Failures and causes:
+ */
+package org.symbian.tools.wrttools.sdt.utils;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.IPath;
+
+import java.io.File;
+
+/**
+ * A reference to a location in a file.  It contains a source,
+ * a line, and a column (the latter both 1-based).
+ * <p>
+ * The source is presumably a file, but you can use
+ * whatever is needed.  The source should implement
+ * toString() in an appropriate manner for reporting
+ * the source reference as a string. 
+ * 
+ * @author eswartz
+ *
+ */
+public class MessageLocation {
+    /** The full path of the offending resource */
+    IPath fullPath;
+    /** The line number where this node starts (1-based) */
+    int lineNumber;
+    /** The character offset of the column where the node starts (1-based) */ 
+    int columnNumber;
+
+    /**
+     * Create a new source reference
+     * @param project the project (may not be null)
+     * @param line line (1-based)
+     * @param column column (1-based)
+     */
+    public MessageLocation(IProject project, int line, int column) {
+        Check.checkArg(project);
+        Check.checkArg(project.getLocation() != null);
+        this.fullPath = project.getLocation();
+        lineNumber = line;
+        columnNumber = column;
+    }
+    
+    /**
+     * Create a new source reference
+     * @param fullpath the full filesystem path to the offending resource (may not be null)
+     * @param line line (1-based)
+     * @param column column (1-based)
+     */
+    public MessageLocation(IPath fullpath, int line, int column) {
+        Check.checkArg(fullpath);
+        this.fullPath = fullpath;
+        lineNumber = line;
+        columnNumber = column;
+    }
+    
+    /**
+     * @param path the full filesystem path to the offending resource (may not be null)
+    */
+    public MessageLocation(IPath path) {
+        this(path, 0, 0);
+    }
+
+    /* (non-Javadoc)
+     * @see java.lang.Object#equals(java.lang.Object)
+     */
+    public boolean equals(Object obj) {
+        if (!(obj instanceof MessageLocation))
+            return false;
+        MessageLocation other = (MessageLocation) obj;
+        return fullPath.equals(other.fullPath)
+        && lineNumber == other.lineNumber
+        && columnNumber == other.columnNumber;
+    }
+    
+    /* (non-Javadoc)
+     * @see java.lang.Object#hashCode()
+     */
+    public int hashCode() {
+        return fullPath.hashCode()
+        ^ (lineNumber << 16)
+        ^ (columnNumber << 8)
+        ^ 0x18283782;
+    }
+     
+    public int getColumnNumber() {
+        return columnNumber;
+    }
+    
+    public int getLineNumber() {
+        return lineNumber;
+    }
+    
+    /** 
+     * Return full path in filesystem 
+     */
+    public IPath getLocation() {
+        return fullPath;
+    }
+    
+    /**
+     * Map the given full path to a path in the current workspace.
+     * @param path
+     * @return the workspace-relative file
+     */
+    private IPath pathToWorkspace(IPath path) {
+    	return FileUtils.convertToWorkspacePath(path);
+    }
+
+    /**
+     * Get the workspace-relative path, or null if
+     * not resolvable to the workspace
+     */
+    public IPath getPath() {
+        return pathToWorkspace(fullPath);
+    }
+    
+    public String toString() {
+    	IPath path = getPath();
+    	if (path == null)
+    		path = fullPath;
+        return path+":"+lineNumber+":"+columnNumber;     //$NON-NLS-1$ //$NON-NLS-2$
+    }
+    
+    public String toShortString() {
+        return new File(fullPath.toOSString()).getName()+":"+lineNumber;     //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    /**
+     * Set the full path
+     */
+    public void setLocation(IPath newPath) {
+        this.fullPath = newPath;
+    }
+    
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/sdt/utils/MessageReporting.java	Wed Jan 27 15:05:37 2010 -0800
@@ -0,0 +1,86 @@
+/**
+ * Copyright (c) 2009 Symbian Foundation and/or its subsidiary(-ies).
+ * All rights reserved.
+ * This component and the accompanying materials are made available
+ * under the terms of the License "Eclipse Public License v1.0"
+ * which accompanies this distribution, and is available
+ * at the URL "http://www.eclipse.org/legal/epl-v10.html".
+ *
+ * Initial Contributors:
+ * Symbian Foundation - initial contribution.
+ * Contributors:
+ * Description:
+ * Overview:
+ * Details:
+ * Platforms/Drives/Compatibility:
+ * Assumptions/Requirement/Pre-requisites:
+ * Failures and causes:
+ */
+package org.symbian.tools.wrttools.sdt.utils;
+
+import org.eclipse.core.runtime.IStatus;
+
+import java.util.*;
+
+/**
+ * This class provides a means for reporting user-visible
+ * messages (such as script errors, component errors, etc.)
+ * by indirecting them through a set of listeners.
+ * This is opposed to Logging which is intended for developer-
+ * related issues.
+ * 
+ * @author eswartz
+ *
+ */
+public class MessageReporting {
+
+    static List listeners = new ArrayList();
+    
+    private MessageReporting() {
+    }
+
+    public static void addListener(IMessageListener handler) {
+        listeners.add(handler);
+    }
+    
+    public static void removeListener(IMessageListener handler) {
+        listeners.remove(handler);
+    }
+        
+    /**
+     * @param msg
+     */
+    public static void emitMessage(IMessage msg) {
+    	boolean handled = false;
+       for (Iterator iter = listeners.iterator(); iter.hasNext();) {
+           IMessageListener handler = (IMessageListener) iter.next();
+           if (handler.isHandlingMessage(msg)) {
+        	   handler.emitMessage(msg);
+        	   handled = true;
+           }
+       }
+       if (!handled) {
+    	   Logging.log(UtilsPlugin.getDefault(),
+    			   Logging.newStatus(UtilsPlugin.getDefault(), msg.getSeverity(), msg.getMessage()));
+       }
+    }
+    
+    public static void emit(int severity, MessageLocation loc, String key, String locMsg, Object[] args) {
+        IMessage msg = new Message(severity, loc,
+                key, locMsg, args);
+        emitMessage(msg);
+    }
+
+    public static void emit(MessageLocation loc, String key, String locMsg, IStatus status) {
+        IMessage msg = new Message(status.getSeverity(), loc,
+                key, locMsg);
+        emitMessage(msg);
+    }
+
+    /**
+     * 
+     */
+    public static void reset() {
+        listeners.clear();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/sdt/utils/TrackedResource.java	Wed Jan 27 15:05:37 2010 -0800
@@ -0,0 +1,261 @@
+/**
+ * Copyright (c) 2009 Symbian Foundation and/or its subsidiary(-ies).
+ * All rights reserved.
+ * This component and the accompanying materials are made available
+ * under the terms of the License "Eclipse Public License v1.0"
+ * which accompanies this distribution, and is available
+ * at the URL "http://www.eclipse.org/legal/epl-v10.html".
+ *
+ * Initial Contributors:
+ * Symbian Foundation - initial contribution.
+ * Contributors:
+ * Description:
+ * Overview:
+ * Details:
+ * Platforms/Drives/Compatibility:
+ * Assumptions/Requirement/Pre-requisites:
+ * Failures and causes:
+ */
+package org.symbian.tools.wrttools.sdt.utils;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceChangeEvent;
+import org.eclipse.core.resources.IResourceChangeListener;
+import org.eclipse.core.resources.IResourceDelta;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+
+/**
+ * Helper class to track changes to a resource handle. To the extent
+ * that Eclipse provides the necessary notification, moves and
+ * renames will be tracked and getResource() will return a
+ * reference to the resource.
+ * A listener interface is provided to give notifications of
+ * moves, content changes, and deletions.
+ * Upon deletion, since this object can no longer provide any
+ * useful servce, the dispose method is automatically called
+ * @author dpodwall
+ *
+ */
+public class TrackedResource implements IDisposable {
+	
+	private IResource resource;
+	private long modificationStamp;
+	private IPath resourcePath;
+	private Class resourceClass;
+	private ListenerList<IListener> listeners = new ListenerList<IListener>();
+	private ResourceHandler handler;
+	
+	public interface IListener {
+		void resourceChanged(TrackedResource resource);
+		/**
+		 * Called after a resource has been moved and the
+		 * TrackedResource has been updated.
+		 * @param oldPath the previous location of the resource
+		 */
+		void resourceMoved(TrackedResource resource, IPath oldPath);
+		void resourceDeleted(TrackedResource resource);
+	}
+		
+	/**
+	 * Initialize with the desired resource and being
+	 * listening for changes. Once initialized the initial
+	 * IResource shouldn't be kept, call getResource as
+	 * needed to get the valid resource handle.
+	 */
+	public TrackedResource(IResource resource) {
+		Check.checkArg(resource);
+		this.resource = resource;
+		this.resourceClass = resource.getClass();
+		this.resourcePath = resource.getFullPath();
+		Check.checkState(resourcePath != null);
+		enableTracking(true);
+	}
+
+	/**
+	 * Dispose must be called in order to unregister the workspace listener.
+	 * It is automatically called if the resource is deleted.
+	 */
+	public void dispose() {
+		if (handler != null) {
+			enableTracking(false);
+			resourcePath = null;
+		}
+	}
+	
+	/**
+	 * Set the tracking status to the desired status and return the
+	 * previous state.
+	 */
+	public synchronized boolean enableTracking(boolean enable) {
+		boolean wasEnabled = handler != null;
+		if (enable == wasEnabled) {
+			return wasEnabled;
+		}
+		
+		if (enable) {
+			if (handler == null) {
+				handler = new ResourceHandler();
+				ResourcesPlugin.getWorkspace().addResourceChangeListener(handler);
+				modificationStamp = resource.getModificationStamp();
+			}
+			
+		} else if (handler != null){
+			ResourcesPlugin.getWorkspace().removeResourceChangeListener(handler);
+			handler = null;
+		}
+		return wasEnabled;
+	}
+
+	/**
+	 * Get the current resource handle. It will differ from 
+	 * the constructor argument if the resource moved.
+	 * Can return null if the resource was deleted
+	 * 
+	 * If non-null, the value will be compatible with
+	 * the original resource. In other words if an IFile
+	 * was originally used, this will return an IFile (or subclass)
+	 * or null.
+	 */
+	public IResource getResource() {
+		return resource;
+	}
+	
+	/**
+	 * Returns the last seen modification stamp.
+	 */
+	public long getLastModificationStamp() {
+		return modificationStamp;
+	}
+	
+	/**
+	 * Force an update of the cached modification stamp to
+	 * the lastest value. This will inhibit notifications for
+	 * the same modification stamp value.
+	 */
+	public void updateModificationStamp() {
+		try {
+			resource.refreshLocal(0, null);
+		} catch (CoreException x) {
+			UtilsPlugin.log(x);
+		}
+		modificationStamp = resource.getModificationStamp();
+	}
+	
+	/**
+	 * Convenience routine to return as IFile
+	 */
+	public IFile getFile() {
+		IFile result = null;
+		if (resource instanceof IFile) {
+			result = (IFile) resource;
+		}
+		return result;
+	}
+	
+	/**
+	 * Convenience routine to return resource's project.
+	 * If the resource is a project it will return that resource,
+	 * otherwise the containing project.
+	 */
+	public IProject getProject() {
+		IProject result = null;
+		if (resource != null) {
+			result = resource.getProject();
+		}
+		return result;
+	}
+	
+	/**
+	 * Listener for change events on the tracked resource.
+	 * Note that these events may be delivered on
+	 * threads other than the UI thread.
+	 */
+	public void addListener(IListener listener) {
+		listeners.add(listener);
+	}
+	
+	public void removeListener(IListener listener) {
+		listeners.remove(listener);
+	}
+	
+	private void fireResourceChanged() {
+		for (IListener l : listeners) {
+			l.resourceChanged(this);
+		}
+	}
+	
+	private void fireResourceMoved(IPath oldPath) {
+		for (IListener l : listeners) {
+			l.resourceMoved(this, oldPath);
+		}
+	}
+	
+	private void fireResourceDeleted() {
+		for (IListener l : listeners) {
+			l.resourceDeleted(this);
+		}
+	}
+	
+	private void handleDeletion() {
+		fireResourceDeleted();
+		dispose();
+	}
+	
+	private void handleMove(IResourceDelta delta) {
+		IPath movedToPath = delta.getMovedToPath();
+		if (movedToPath != null) {
+			IResource newResource = ResourcesPlugin.getWorkspace().getRoot().findMember(movedToPath);
+			if (newResource != null) {
+				// the new resource should be compatible with the previous, e.g.
+				// if we started with an IFile the new one should be an IFile
+				Check.checkState(resourceClass.isInstance(newResource));
+				resource = newResource;
+				modificationStamp = resource.getModificationStamp();
+				IPath oldPath = resourcePath;
+				resourcePath = movedToPath;
+				fireResourceMoved(oldPath);
+			}
+		}
+	}
+	
+	private void resourceChanged(IResourceChangeEvent event) {
+		IResourceDelta delta = event.getDelta();
+		if (delta != null && resourcePath != null) {
+			delta = delta.findMember(resourcePath);
+			if (delta != null) {
+				int kind = delta.getKind();
+				switch (kind) {
+				case IResourceDelta.CHANGED:
+					if ((IResourceDelta.CONTENT & delta.getFlags()) != 0) {
+						long currStamp = delta.getResource().getModificationStamp();
+						if (currStamp != modificationStamp) {
+							modificationStamp = currStamp;
+							fireResourceChanged();
+						}
+					}
+					break;
+					
+				case IResourceDelta.REMOVED:
+					if ((IResourceDelta.MOVED_TO & delta.getFlags()) != 0) {
+						handleMove(delta);
+					}
+					else {
+						handleDeletion();
+					}
+					break;
+				}
+			}
+		}
+	}
+	
+	private class ResourceHandler implements IResourceChangeListener {
+
+		public void resourceChanged(IResourceChangeEvent event) {
+			TrackedResource.this.resourceChanged(event);			
+		}
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/sdt/utils/UtilsPlugin.java	Wed Jan 27 15:05:37 2010 -0800
@@ -0,0 +1,106 @@
+/**
+ * Copyright (c) 2009 Symbian Foundation and/or its subsidiary(-ies).
+ * All rights reserved.
+ * This component and the accompanying materials are made available
+ * under the terms of the License "Eclipse Public License v1.0"
+ * which accompanies this distribution, and is available
+ * at the URL "http://www.eclipse.org/legal/epl-v10.html".
+ *
+ * Initial Contributors:
+ * Symbian Foundation - initial contribution.
+ * Contributors:
+ * Description:
+ * Overview:
+ * Details:
+ * Platforms/Drives/Compatibility:
+ * Assumptions/Requirement/Pre-requisites:
+ * Failures and causes:
+ */
+package org.symbian.tools.wrttools.sdt.utils;
+
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Plugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The main plugin class to be used in the desktop.
+ */
+public class UtilsPlugin extends Plugin {
+	//The shared instance.
+	private static UtilsPlugin plugin;
+	//Resource bundle.
+	private ResourceBundle resourceBundle;
+	
+	/**
+	 * The constructor.
+	 */
+	public UtilsPlugin() {
+		super();
+		plugin = this;
+	}
+
+	/**
+	 * This method is called upon plug-in activation
+	 */
+	public void start(BundleContext context) throws Exception {
+		super.start(context);
+	}
+
+	/**
+	 * This method is called when the plug-in is stopped
+	 */
+	public void stop(BundleContext context) throws Exception {
+		super.stop(context);
+		plugin = null;
+		resourceBundle = null;
+	}
+
+	/**
+	 * Returns the shared instance.
+	 */
+	public static UtilsPlugin getDefault() {
+		return plugin;
+	}
+
+	/**
+	 * Returns the string from the plugin's resource bundle,
+	 * or 'key' if not found.
+	 */
+	public static String getResourceString(String key) {
+		ResourceBundle bundle = UtilsPlugin.getDefault().getResourceBundle();
+		try {
+			return (bundle != null) ? bundle.getString(key) : key;
+		} catch (MissingResourceException e) {
+			return key;
+		}
+	}
+
+	/**
+	 * Returns the plugin's resource bundle,
+	 */
+	public ResourceBundle getResourceBundle() {
+		try {
+			if (resourceBundle == null)
+				resourceBundle = ResourceBundle.getBundle("com.nokia.sdt.utils.UtilsPluginResources"); //$NON-NLS-1$
+		} catch (MissingResourceException x) {
+			resourceBundle = null;
+		}
+		return resourceBundle;
+	}
+
+	static public void log(IStatus status) {
+		Logging.log(plugin, status);
+	}
+	
+	static public void log(Throwable thr) {
+		Logging.log(plugin, Logging.newStatus(plugin, thr));
+	}
+	
+	static public void log(Throwable thr, String msg) {
+		Logging.log(plugin, Logging.newStatus(plugin, IStatus.ERROR, msg, thr));
+	}
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/sdt/utils/VariableSubstitutionEngine.java	Wed Jan 27 15:05:37 2010 -0800
@@ -0,0 +1,166 @@
+/**
+ * Copyright (c) 2009 Symbian Foundation and/or its subsidiary(-ies).
+ * All rights reserved.
+ * This component and the accompanying materials are made available
+ * under the terms of the License "Eclipse Public License v1.0"
+ * which accompanies this distribution, and is available
+ * at the URL "http://www.eclipse.org/legal/epl-v10.html".
+ *
+ * Initial Contributors:
+ * Symbian Foundation - initial contribution.
+ * Contributors:
+ * Description:
+ * Overview:
+ * Details:
+ * Platforms/Drives/Compatibility:
+ * Assumptions/Requirement/Pre-requisites:
+ * Failures and causes:
+ */
+package org.symbian.tools.wrttools.sdt.utils;
+
+import org.symbian.tools.wrttools.sdt.utils.noexport.Messages;
+
+import java.text.MessageFormat;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Simple utility to replace variables in the form "${varname}"
+ * or "$(varname)" in a string from a map of replacements, with
+ * support for fallbacks for unknown variables.  
+ * @author eswartz
+ *
+ */
+public class VariableSubstitutionEngine {
+
+	public interface IVariableLookupCallback {
+		/** Get an unknown variable's value.   */
+		public Object getValue(String var);
+	}
+	
+	private IMessageListener msgListener;
+	private MessageLocation location;
+	private boolean recursive;
+	private Pattern thePattern = curlyBraces;
+	private static final Pattern curlyBraces = Pattern.compile("(\\$\\{([^}]+)\\})");
+	private static final Pattern parentheses = Pattern.compile("(\\$\\(([^)]+)\\))");
+	
+	/**
+	 * Create an engine which will report any errors against
+	 * the given location to the given listener.
+	 * @param msgListener
+	 * @param location
+	 */
+	public VariableSubstitutionEngine(IMessageListener msgListener, MessageLocation location) {
+		this.msgListener = msgListener;
+		this.location = location;
+		this.thePattern = curlyBraces;
+	}
+	
+	/**
+	 * Set the token delimiting variables (either '{' or '(')
+	 * @param token
+	 */
+	public void setVariableToken(char token) {
+		if (token == '{')
+			thePattern = curlyBraces;
+		else if (token == '(')
+			thePattern = parentheses;
+		else
+			Check.checkArg(false);
+	}
+
+	/**
+	 * Substitute all instances of "${varname}" or "$(varname)"
+	 * with values using the callback.
+	 * 
+	 * @param variables
+	 * @param expr
+	 * @return
+	 * @see #setVariableToken(char)
+	 */
+	public String substitute(IVariableLookupCallback variableLookupCallback, String expr) {
+		if (expr == null)
+			return null;
+		Check.checkArg(variableLookupCallback);
+		StringBuffer buffer;
+		boolean replaced;
+		do {
+			buffer = new StringBuffer();
+			replaced = false;
+			Matcher matcher = thePattern.matcher(expr);
+			int startPosition = 0;
+			int prevPosition = 0;
+			while (startPosition < expr.length() && matcher.find(startPosition)) {
+				String key = matcher.group(2);
+				Object value = variableLookupCallback.getValue(key);
+				if (value == null) {
+					if (msgListener != null)
+						msgListener.emitMessage(new Message(IMessage.ERROR,
+							location,
+							"SimpleSubstitutionEngine.UnknownVariable", //$NON-NLS-1$
+							MessageFormat.format(
+									Messages.getString("SimpleSubstitutionEngine.UnknownVariable"), //$NON-NLS-1$
+									new Object[] { key })));
+					startPosition = matcher.end();
+					buffer.append(expr.substring(prevPosition, matcher.end()));
+					prevPosition = matcher.end();
+				} else {
+					String valueString = value.toString();
+					if (!recursive && thePattern.matcher(valueString).find()) {
+						if (msgListener != null)
+							msgListener.emitMessage(new Message(IMessage.ERROR,
+								location,
+								"SimpleSubstitutionEngine.InvalidSubstitution", //$NON-NLS-1$
+								MessageFormat.format(
+										Messages.getString("SimpleSubstitutionEngine.InvalidSubstitution"), //$NON-NLS-1$
+										new Object[] { key, value })));
+						return expr;
+					}
+					
+					buffer.append(expr.substring(prevPosition, matcher.start()));
+					buffer.append(valueString);
+					prevPosition = matcher.end();
+					replaced = true;
+					
+					// don't replace anymore
+					int lastCharacterMatched = matcher.end();
+					startPosition = lastCharacterMatched;
+				}
+			}
+			buffer.append(expr.substring(prevPosition));
+			expr = buffer.toString();
+		} while (recursive && replaced);
+		return expr;
+	}
+
+	/**
+	 * Substitute all instances of "${varname}" or "$(varname)" 
+	 * with values from the map.
+	 * 
+	 * @param variables
+	 * @param expr
+	 * @return
+	 * @see #setVariableToken(char)
+	 */
+	public String substitute(final Map variables, String expr) {
+		return substitute(new IVariableLookupCallback() {
+			public Object getValue(String var) {
+				return variables.get(var);
+			}
+		}, expr);
+	}
+
+	
+	/**
+	 * Allow recursive substitution of variables with values that
+	 * contain ${...}
+	 * @param enable
+	 */
+	public void allowRecursion(boolean enable) {
+		this.recursive = enable;
+	}
+	
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/sdt/utils/noexport/Messages.java	Wed Jan 27 15:05:37 2010 -0800
@@ -0,0 +1,45 @@
+/**
+ * Copyright (c) 2009 Symbian Foundation and/or its subsidiary(-ies).
+ * All rights reserved.
+ * This component and the accompanying materials are made available
+ * under the terms of the License "Eclipse Public License v1.0"
+ * which accompanies this distribution, and is available
+ * at the URL "http://www.eclipse.org/legal/epl-v10.html".
+ *
+ * Initial Contributors:
+ * Symbian Foundation - initial contribution.
+ * Contributors:
+ * Description:
+ * Overview:
+ * Details:
+ * Platforms/Drives/Compatibility:
+ * Assumptions/Requirement/Pre-requisites:
+ * Failures and causes:
+ */
+
+package org.symbian.tools.wrttools.sdt.utils.noexport;
+
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+/**
+ * @author eswartz
+ *
+ */
+public class Messages {
+    private static final String BUNDLE_NAME = "com.nokia.sdt.utils.noexport.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 + '!';
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/sdt/utils/noexport/messages.properties	Wed Jan 27 15:05:37 2010 -0800
@@ -0,0 +1,23 @@
+Check.RuntimeError=Runtime Error
+Check.ArgumentIsNull=argument is null
+Check.ArgumentIsInvalid=argument is invalid
+Check.ObjectIsInconsistent=object state is inconsistent
+Check.ApiAssertionFailed=assertion on API contract failed
+Logging.ErrorTitle=Error
+Logging.FromPlugin=plugin: 
+Logging.DueToException=exception: 
+Logging.NoMessage=???
+Logging.GenericErrorMessage=An error has occurred.\nPlease see the Error Log for more details.
+Message.Error=error: 
+Message.Warning=warning: 
+QueryWithBooleanPrefDialog.1=Don't ask again
+TextUtils.Conjunctions=(in|to|of|and|or|but|if|as)
+SimpleSubstitutionEngine.UnknownVariable=unknown variable ''{0}''
+SimpleSubstitutionEngine.InvalidSubstitution=invalid substitution of variable ''{0}'' with value ''{1}''
+NotifyWithBooleanPrefDialog.DoNotNotifyAgain=Do not &notify me again
+FormEditorEditingContext.cantShowUndo=Unable to show undo location.
+EditingContextOperation.cantShowCommandLocation=Unable to display the location for the '{0}' command.
+EditingContextOperation.errorDialogTitle=Error
+ProjectFolderSelectionDialog.SelectFolderDescriptionLabel=Select a folder:
+ProjectFolderSelectionDialog.SelectFolderTitle=Select a folder
+DirectorySelectorWithHistory.BrowseLabel=Browse...
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/util/FileUtil.java	Wed Jan 27 15:05:37 2010 -0800
@@ -0,0 +1,550 @@
+/**
+ * Copyright (c) 2009 Symbian Foundation and/or its subsidiary(-ies).
+ * All rights reserved.
+ * This component and the accompanying materials are made available
+ * under the terms of the License "Eclipse Public License v1.0"
+ * which accompanies this distribution, and is available
+ * at the URL "http://www.eclipse.org/legal/epl-v10.html".
+ *
+ * Initial Contributors:
+ * Symbian Foundation - initial contribution.
+ * Contributors:
+ * Description:
+ * Overview:
+ * Details:
+ * Platforms/Drives/Compatibility:
+ * Assumptions/Requirement/Pre-requisites:
+ * Failures and causes:
+ */
+
+package org.symbian.tools.wrttools.util;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+public class FileUtil {
+	private Logger log = Logger.getLogger(getClass().getName());
+	private List fileList = new ArrayList();
+	private List dirList = new ArrayList();
+	private List<File> widgetFileList = new ArrayList<File>();
+/**
+ * 
+ * @param fileName
+ * @return
+ */
+	public File unZip(String fileName) {
+		log.finest("unZip  >>--->>");
+		String unzipFilePath = System.getProperty("java.io.tmpdir");
+		Unzip unZip = new Unzip(true);
+		unZip.extract(fileName, unzipFilePath);
+		int indexOfName1 = fileName.lastIndexOf('/');
+		int indexOfName2 = fileName.lastIndexOf('\\');
+		int actIndex = indexOfName2;
+		if (indexOfName1 > indexOfName2) {
+			actIndex = indexOfName1;
+		}
+		String zipfilename = fileName.substring(actIndex + 1, fileName
+				.lastIndexOf('.'));
+
+		File widgetModelFile = new File(unzipFilePath + "/" + zipfilename);
+		log.finest("unZip  <<---<<");
+		return widgetModelFile;
+	}
+	
+	public File unZip(String fileName,String unzipFilePath) {
+		log.finest("unZip  >>--->>");
+		System.out.println("in unzip class fileName ***:"+fileName);
+		System.out.println("in unzip class unzipFilePath ***:"+unzipFilePath);
+//		String unzipFilePath = System.getProperty("java.io.tmpdir");
+		Unzip unZip = new Unzip(true);
+		unZip.extract(fileName, unzipFilePath);
+		int indexOfName1 = fileName.lastIndexOf('/');
+		int indexOfName2 = fileName.lastIndexOf('\\');
+		int actIndex = indexOfName2;
+		if (indexOfName1 > indexOfName2) {
+			actIndex = indexOfName1;
+		}
+		String zipfilename = fileName.substring(actIndex + 1, fileName
+				.lastIndexOf('.'));
+
+		File widgetModelFile = new File(unzipFilePath + "/" + zipfilename);
+		log.finest("unZip  <<---<<");
+		return widgetModelFile;
+	}
+	
+	public File deleteParentEmptydir(String fileName,String unzipFilePath) {
+		
+		log.finest("unZip  >>--->>");
+//		String unzipFilePath = System.getProperty("java.io.tmpdir");
+		
+		File unzipFile = new File( fileName);
+		List curList=	getCurrDirAllFiles(unzipFile);
+		String name=null;
+//		for (int i = 0; i < curList.size(); i++) {
+////			Util.showData("---- unZipParentEmptydir file name ---------------:"+((File)curList.get(i)).getAbsolutePath());
+//			
+//	
+//	}
+		if(curList.size()==1){
+		File newfile=	((File)curList.get(0))	;
+		try {
+			name=newfile.getName();
+			copyDirectory( newfile , new File (unzipFilePath+"/"+name));
+			this.deleteDirFile(unzipFile);
+			return new File(unzipFilePath+"/"+name);
+		} catch (IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		}else{
+			return unzipFile;
+		}
+		
+		log.finest("unZip  <<---<<");
+		return null;
+	}
+	
+/**
+ * 
+ * @param file
+ * @return
+ */
+	private String getFileName(File file) {
+		return file.getName();
+
+	}
+
+	/**
+	 * 
+	 * @param dir
+	 * @return
+	 */
+	public List getDirFileNames(File dir) {
+		log.finest("getDirFileNames  >>--->>");
+			fileList.add(getFileName(dir));
+		if (dir.isDirectory()) {
+			String[] children = dir.list();
+			for (int i = 0; i < children.length; i++) {
+				getDirFileNames(new File(dir, children[i]));
+			}
+		}
+		log.finest("getDirFileNames  <<---<<");
+		return fileList;
+	}
+	
+	/**
+	 * 
+	 * @param file
+	 * @return
+	 */
+	
+	private String getFileFullName(File file) {
+		return Util.replaceChar(file.getAbsolutePath(), '\\', '/');
+		
+
+	}
+
+	/**
+	 * 
+	 * @param dir
+	 * @return
+	 */
+	public List getDirFileFullNames(File dir) {
+		log.finest("getDirFileNames  >>--->>");
+//			fileList.add(getFileFullName(dir));
+		if (dir.isDirectory()) {
+			String[] children = dir.list();
+			for (int i = 0; i < children.length; i++) {
+				getDirFileFullNames(new File(dir, children[i]));
+			}
+		}
+		else {
+			fileList.add(getFileFullName(dir));
+		}
+		log.finest("getDirFileNames  <<---<<");
+
+		return fileList;
+	}
+
+	
+	
+	/**
+	 * 
+	 * @param dir
+	 * @return
+	 */
+	
+	//	 Return the files which are in the directory exclude the recursive process.
+	public List<String> getCurrDirFileNames(File dir) {
+		log.finest("getCurrDirFileNames  >>--->>");
+		List<String> fileNameList = new ArrayList();
+		try 
+		{
+			File[] widgetFileArray = dir.listFiles();
+			if (widgetFileArray.length > 0 && widgetFileArray != null) {
+				int len = widgetFileArray.length;
+				for (int i = 0; i < len; i++) {
+					String path =Util.replaceChar(widgetFileArray[i].getPath(), '\\', '/');
+					fileNameList.add(path);
+				}
+
+			}
+		} 
+		catch (Exception e) {
+			 Util.logEvent(log, Level.INFO, e);				
+				
+		}
+		log.finest("getCurrDirFileNames  <<---<<");
+		return fileNameList;
+	}
+
+	/**
+	 * 
+	 * @param dir
+	 * @return
+	 */
+	//	 Return the files which are in the directory exclude the recursive process.
+	public List<String> getCurrDirFileFullNames(File dir) {
+		
+		log.finest("getCurrDirFileNames  >>--->>");
+		List<String> fileNameList = new ArrayList();
+		try 
+		{
+			File[] widgetFileArray = dir.listFiles();
+			if (widgetFileArray.length > 0 && widgetFileArray != null) {
+				int len = widgetFileArray.length;
+				for (int i = 0; i < len; i++) {
+					String path =Util.replaceChar(widgetFileArray[i].getPath(), '\\', '/');
+					fileNameList.add(path);
+				}
+
+			}
+		} 
+		catch (Exception e) {
+			 Util.logEvent(log, Level.INFO, e);				
+				
+		}
+		log.finest("getCurrDirFileNames  <<---<<");
+		return fileNameList;
+	}
+	/**
+	 * 
+	 * @param dir
+	 * @return
+	 */
+	//	 Return the files which are in the directory exclude the recursive process and return a File.
+	public List<File> getCurrDirFiles(File dir) {
+		log.finest("getCurrDirFiles  >>--->>");
+		List<File> fileList = new ArrayList<File>();
+		try {
+			File[] widgetFileArray = dir.listFiles();
+			if (widgetFileArray.length > 0 && widgetFileArray != null) {
+				int len = widgetFileArray.length;
+				for (int i = 0; i < len; i++) {
+					
+					if (!widgetFileArray[i].isDirectory()) {
+						fileList.add(widgetFileArray[i]);
+					}
+				}
+
+			}
+		} catch (Exception e) {
+			 Util.logEvent(log, Level.INFO, e);				
+				}
+		log.finest("getCurrDirFiles  <<---<<");
+		return fileList;
+	}
+	
+	public List<File> getCurrDirAllFiles(File dir) {
+		log.finest("getCurrDirAllFiles  >>--->>");
+		List<File> fileList = new ArrayList<File>();
+		try {
+			File[] widgetFileArray = dir.listFiles();
+			if (widgetFileArray.length > 0 && widgetFileArray != null) {
+				int len = widgetFileArray.length;
+				for (int i = 0; i < len; i++) {
+					
+						fileList.add(widgetFileArray[i]);
+				
+				}
+
+			}
+		} catch (Exception e) {
+			 Util.logEvent(log, Level.INFO, e);				
+				}
+		log.finest("getCurrDirAllFiles  <<---<<");
+		return fileList;
+	}
+	
+/**
+ * 
+ * @param path
+ * @return
+ */
+	//	 Returns the list of directories and files for the specified path. 
+	public List getDirFileNames(String path) {
+		log.finest("getDirFileNames  >>--->>");
+		getDirFileNames(new File(path));
+//		for (int i = 0; i < fileList.size(); i++) {
+//		}
+		log.finest("getDirFileNames  <<---<<");
+		return fileList;
+	}
+/**
+ * 
+ * @param widgetDir
+ * @return
+ */
+	//	  File getWidgetModel(String widgetDirPath){
+
+	public List<File> getDirectoryFileList(File widgetDir) {
+		log.finest("getDirectoryFileList  >>--->>");
+		try {
+			File[] widgetFileArray = widgetDir.listFiles();
+			if (widgetFileArray.length > 0 && widgetFileArray != null) {
+				int len = widgetFileArray.length;
+				for (int i = 0; i < len; i++) {
+					widgetFileList.add(widgetFileArray[i]);
+					if (widgetFileArray[i].isDirectory()) {
+						getDirectoryFileList(widgetFileArray[i]);
+					}
+
+				}
+
+			}
+		} catch (Exception e) {
+			 Util.logEvent(log, Level.INFO, e);	;
+		}
+
+		//		      zippy = new ZipFile(fileName);
+		log.finest("getDirectoryFileList  <<---<<");
+		return widgetFileList;
+	}
+/**
+ * 
+ * @param widgetDir
+ * @return
+ */
+	public List<File> getDirectoryFileList(String widgetDir) {
+
+		return getDirectoryFileList(new File(widgetDir));
+	}
+/**
+ * 
+ * @param files
+ * @param fileName1
+ * @param fileName2
+ * @return
+ */
+	public File getFile(List<File> files, String fileName1, String fileName2) {
+		log.finest("getFile  >>--->>");
+
+		for (File file : files) {
+			if (file.getName().endsWith(fileName1)
+					|| file.getName().endsWith(fileName2)) {
+				return file;
+			}
+		}
+		log.finest("getFile  <<---<<");
+		return null;
+	}
+	/**
+	 * 
+	 * @param files
+	 * @param fileName
+	 * @return
+	 */
+
+	  public File getFile(List<File>  files,String fileName){
+		  log.finest("getFile  >>--->>");
+		  if(fileName!=null &&files!=null &&files.size()>0){
+	        for(File file:  files){
+	        	if(file.getName().trim().equalsIgnoreCase(fileName)){            	
+	            return file;            
+	        }
+	      }
+		  }
+			log.finest("getFile  <<---<<");
+	      return null;  
+	    }
+	  
+	  public void deleteDirFile( File deleteFile)
+	  {
+		  log.finest("deleteDirFile  >>--->>");
+			if(deleteFile.isDirectory()){
+			List<File> unzipDirList = getDirectoryFileList(deleteFile);
+			for (File file : unzipDirList) {
+				if (!file.isDirectory()) 
+				{
+					log.finest("delete Dir file  :"+file.getName());
+					file.delete();
+				}
+			}
+			List<File> unzipDirList2 = getDirectoryFileList(deleteFile);
+			for (File file : unzipDirList2) {
+							file.delete();
+			}
+			}
+			log.finest("delete file :"+deleteFile.getName());
+			deleteFile.delete();
+			log.finest("deleteDirFile  <<---<<");
+	  }
+	  
+	  public void clearDirectory( File deleteFile)
+	  {		  
+		  log.finest("clearDirectory  >>--->>");
+		
+			List<File> currentDirFileList = getCurrDirAllFiles(deleteFile);
+			for (File file : currentDirFileList) {
+					 deleteDirFile( file);			
+			}
+			log.finest("clearDirectory  <<---<<");
+	  }
+
+	  public static void copy(String fromFileName, String toFileName)
+	      throws IOException {
+	    File fromFile = new File(fromFileName);
+	    File toFile = new File(toFileName);
+
+	    if (!fromFile.exists())
+	      throw new IOException("FileCopy: " + "no such source file: "
+	          + fromFileName);
+	    if (!fromFile.isFile())
+	      throw new IOException("FileCopy: " + "can't copy directory: "
+	          + fromFileName);
+	    if (!fromFile.canRead())
+	      throw new IOException("FileCopy: " + "source file is unreadable: "
+	          + fromFileName);
+
+	    if (toFile.isDirectory())
+	      toFile = new File(toFile, fromFile.getName());
+
+	    if (toFile.exists()) {
+	      if (!toFile.canWrite())
+	        throw new IOException("FileCopy: "
+	            + "destination file is unwriteable: " + toFileName);
+	      System.out.print("Overwrite existing file " + toFile.getName()
+	          + "? (Y/N): ");
+	      System.out.flush();
+	      BufferedReader in = new BufferedReader(new InputStreamReader(
+	          System.in));
+	      String response = in.readLine();
+	      if (!response.equals("Y") && !response.equals("y"))
+	        throw new IOException("FileCopy: "
+	            + "existing file was not overwritten.");
+	    } else {
+	      String parent = toFile.getParent();
+	      if (parent == null)
+	        parent = System.getProperty("user.dir");
+	      File dir = new File(parent);
+	      if (!dir.exists())
+	        throw new IOException("FileCopy: "
+	            + "destination directory doesn't exist: " + parent);
+	      if (dir.isFile())
+	        throw new IOException("FileCopy: "
+	            + "destination is not a directory: " + parent);
+	      if (!dir.canWrite())
+	        throw new IOException("FileCopy: "
+	            + "destination directory is unwriteable: " + parent);
+	    }
+
+	    FileInputStream from = null;
+	    FileOutputStream to = null;
+	    try {
+	      from = new FileInputStream(fromFile);
+	      to = new FileOutputStream(toFile);
+	      byte[] buffer = new byte[4096];
+	      int bytesRead;
+
+	      while ((bytesRead = from.read(buffer)) != -1)
+	        to.write(buffer, 0, bytesRead); // write
+	    } finally {
+	      if (from != null)
+	        try {
+	          from.close();
+	        } catch (IOException e) {
+	          ;
+	        }
+	      if (to != null)
+	        try {
+	          to.close();
+	        } catch (IOException e) {
+	          ;
+	        }
+	    }
+	  }
+	  public void copyDirectory(File sourceLocation , File targetLocation)
+	    throws IOException {
+	        
+	        if (sourceLocation.isDirectory()) {
+	            if (!targetLocation.exists()) {
+	                targetLocation.mkdir();
+	            }
+	            
+	            String[] children = sourceLocation.list();
+	            for (int i=0; i<children.length; i++) {
+	                copyDirectory(new File(sourceLocation, children[i]),
+	                        new File(targetLocation, children[i]));
+	            }
+	        } else {
+	            
+	            InputStream in = new FileInputStream(sourceLocation);
+	            OutputStream out = new FileOutputStream(targetLocation);
+	            
+	            // Copy the bits from instream to outstream
+	            byte[] buf = new byte[1024];
+	            int len;
+	            while ((len = in.read(buf)) > 0) {
+	                out.write(buf, 0, len);
+	            }
+	            in.close();
+	            out.close();
+	        }
+	    } 
+	  
+	public static void main(String[] args) {
+		FileUtil trs = new FileUtil();
+		String candidate = "C:/Test/t1/HOROSCOPEnew.zip";
+		 System.out.println("main starting   :");
+		String filePath=System.getProperty("java.io.tmpdir");
+		//	    	traverse(new File(dirName));
+		//		   trs.getDirectoryFileList( dirName);
+		trs.unZip(candidate,"C:/Test/t1/");
+		
+		 System.out.println("------------------------------------------------------");
+	List curList=	trs.getCurrDirAllFiles(new File ("C:/Test/t1/HOROSCOPEnew"));
+		for (int i = 0; i < curList.size(); i++) {
+			Util.showData("----file name ---------------:"+((File)curList.get(i)).getAbsolutePath());
+			
+	
+	}
+		trs.deleteParentEmptydir("C:/Test/t1/HOROSCOPEnew","C:/Test/t1") ;
+//		Util.showData(trs.getCurrDirFileNames(new File (candidate)), "File List");
+//		trs.trimFilePath(new File(filePath+"Beep"));
+	}
+
+	public File getFile(String string) {
+	return new File(string);
+
+	}
+	
+	
+	/**
+	 * Returns the logger
+	 * @return
+	 */
+	public Logger getLog() {
+		return log;
+	}
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/util/Messages.java	Wed Jan 27 15:05:37 2010 -0800
@@ -0,0 +1,41 @@
+/**
+ * Copyright (c) 2009 Symbian Foundation and/or its subsidiary(-ies).
+ * All rights reserved.
+ * This component and the accompanying materials are made available
+ * under the terms of the License "Eclipse Public License v1.0"
+ * which accompanies this distribution, and is available
+ * at the URL "http://www.eclipse.org/legal/epl-v10.html".
+ *
+ * Initial Contributors:
+ * Symbian Foundation - initial contribution.
+ * Contributors:
+ * Description:
+ * Overview:
+ * Details:
+ * Platforms/Drives/Compatibility:
+ * Assumptions/Requirement/Pre-requisites:
+ * Failures and causes:
+ */
+
+package org.symbian.tools.wrttools.util;
+
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+public class Messages {
+	private static final String BUNDLE_NAME = "com.nokia.wrt.util.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 + '!';
+		}
+	}
+}
--- a/org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/util/Util.java	Mon Jan 25 16:30:51 2010 -0500
+++ b/org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/util/Util.java	Wed Jan 27 15:05:37 2010 -0800
@@ -18,6 +18,10 @@
  */
 package org.symbian.tools.wrttools.util;
 
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
 public class Util {
 
 	public static String removeSpaces(String widgetName) {
@@ -27,5 +31,139 @@
 	public static String removeNonAlphaNum(String projectName) {
 		return projectName != null ? projectName.replaceAll("[^a-zA-Z0-9 ]", "") : null;
 	}
+public static void logEvent(Logger log, Level level, Throwable throwable)
+	{
+		if (level==Level.SEVERE)
+		{
+			log.severe(throwable.getLocalizedMessage());
+			if(throwable.getCause()!=null)
+			log.severe(throwable.getCause().toString());
+			log.severe(throwable.getStackTrace().toString());
+		}
+		if (level==Level.WARNING)
+		{
+			log.warning(throwable.getLocalizedMessage());
+			if(throwable.getCause()!=null)
+			log.warning(throwable.getCause().toString());
+			log.warning(throwable.getStackTrace().toString());
+		}
+		if (level==Level.INFO)
+		{
+			log.info(throwable.getLocalizedMessage());
+			if(throwable.getCause()!=null)
+			log.info(throwable.getCause().toString());
+			log.info(throwable.getStackTrace().toString());
+		}
+		
+	}
+	
+	public static String replaceChar(String input, char asciiOutChar, char asciiInChar){
+		char x;
+		int ascii ;
+		String outString="";
+		int outCharAscii= (asciiOutChar > 127) ? '?' : (char)(asciiOutChar & 0x7F);
+		int inCharAscii= (asciiInChar > 127) ? '?' : (char)(asciiInChar & 0x7F);
+		
+		for (int i = 0; i < input.length(); i++) {
+			 x = input.charAt(i);	
+			 ascii = (x > 127) ? '?' : (char)(x & 0x7F);
+			 
+			 if(ascii==outCharAscii){
+				 outString=outString+asciiInChar;
+			 }else{
+				 outString=outString+x; 
+			 }
+		
+		}
+		return outString;
+	}
+	
+	  public static void showData(String s) {
+		System.out.println(s);
+	}
+	  
+	  public static void showData(List<String> listString, String header) {
+		 
+		  if(listString!=null&&listString.size()>0) {
+			  System.out.println("--------"+header+"------");
+		  for(String s:listString){
+			System.out.println(s);
+			}
+		  }else {
+			  System.out.println("--------Empty/Null "+header+"------");
+		  }
+		}
 
+
+		@SuppressWarnings("restriction")
+		/* Validation tests for both Windows & Mac OS */
+		private static String commonValidate(String argName)
+		{
+			if (argName.length() == 0 ) {
+				return ("Can not be empty");	    		 
+			}
+			
+        	// filenames starting with dot are not valid for both Widget name & UID
+	    	if ( argName.charAt(0) == '.' ) {
+	    		return("Can not begin with a dot");
+	    	}
+
+	    	final char lastChar = argName.charAt(argName.length()-1);
+			// filenames ending in dot are not valid for both Widget name & UID
+			if (lastChar == '.') {
+				return("Can not end with dot");
+			}
+			
+			return null;
+		}
+
+
+		public static String validateWidgetName(String widgetName){    	
+			String strError = null;			
+			if ((strError = commonValidate(widgetName)) != null)
+				return "Invalid Widget name. " + strError;			
+			if (widgetName.indexOf("<") > -1 || widgetName.indexOf(">") > -1){
+        		return("Invalid Widget name. Angle brackets are not allowed");
+        	}
+			final char lastChar = widgetName.charAt(widgetName.length()-1);
+			// trailing or beginning space is not valid in filenames for Widget name
+			if ((Character.isWhitespace(widgetName.charAt(0)) || Character.isWhitespace(lastChar))) {
+				return("Invalid Widget name. Beginning or trailing spaces are not allowed");
+			}
+
+			if (widgetName.indexOf('\n') != -1 || widgetName.indexOf('\t') != -1 ) {
+				return("Invalid Widget name. newline character is not allowed");
+			}
+			
+	        return null;
+		}
+
+		public static String validateWidgetID(String widgetID)
+		{
+			String strError = null; 			
+			if ((strError = commonValidate(widgetID)) != null)
+				return "Invalid Widget identifier. " + strError;
+
+			// file names with white spaces are not allowed for Widget Identifier (UID)
+        	if (widgetID.indexOf(" ") > -1 ){
+        		return("Invalid Widget identifier. Whitespaces are not allowed");
+        	}
+        	
+        	if (widgetID.length() > 78 ) {
+        		return("Invalid Widget identifier. Maximum string length exceeded");
+        	}
+        	
+        	/* test invalid characters, allows only alphanumeric and '.' for UID*/
+			String alphnum = ".0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
+			for (int i = 0; i < widgetID.length(); i++)
+				if (alphnum.indexOf(widgetID.charAt(i),0) == -1) {
+					return("Invalid Widget identifier. Only alphanumeric or '.' is allowed");
+				}
+
+			if (widgetID.matches(".*[.]{2,}.*")) {				
+				return("Invalid Widget identifier. Consecutive dots are not allowed");				
+			}	        
+
+			return null;
+		}
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/util/WRTEntityResolver.java	Wed Jan 27 15:05:37 2010 -0800
@@ -0,0 +1,63 @@
+/**
+ * Copyright (c) 2009 Symbian Foundation and/or its subsidiary(-ies).
+ * All rights reserved.
+ * This component and the accompanying materials are made available
+ * under the terms of the License "Eclipse Public License v1.0"
+ * which accompanies this distribution, and is available
+ * at the URL "http://www.eclipse.org/legal/epl-v10.html".
+ *
+ * Initial Contributors:
+ * Symbian Foundation - initial contribution.
+ * Contributors:
+ * Description:
+ * Overview:
+ * Details:
+ * Platforms/Drives/Compatibility:
+ * Assumptions/Requirement/Pre-requisites:
+ * Failures and causes:
+ */
+
+package org.symbian.tools.wrttools.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.xml.sax.EntityResolver;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+/**
+ * This entity resolver class can be used when DOM Parser is used for local files
+ * @author ranoliya
+ *
+ */
+public class WRTEntityResolver {
+
+	 
+	/**
+	 * 
+	 * @param dtdSystemID -- DTD System ID
+	 * @param dtdFilename -- Local DTD File name
+	 * @return
+	 */
+	public EntityResolver inputResolveEntity(final String dtdSystemID, final String dtdName) {
+		EntityResolver er = new EntityResolver() {
+
+			/**
+			 * This method resolves publicID and systemID for local files
+			 */
+  			public InputSource resolveEntity(String publicId, String systemId)
+  					throws SAXException, IOException {
+  					InputSource result = null;
+  					InputStream resourceAsStream = this.getClass().getResourceAsStream(dtdName);
+  					result = new InputSource(resourceAsStream);
+  					result.setPublicId(publicId);
+  					result.setSystemId(systemId);
+  				return result;
+  			}
+  			
+  		};
+		return er;
+	}
+	
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.symbian.tools.wrttools/src/org/symbian/tools/wrttools/util/messages.properties	Wed Jan 27 15:05:37 2010 -0800
@@ -0,0 +1,5 @@
+util.src.not.found=Source file - "{0}" is an invalid input
+
+util.write.error = Can not write back to the given destination "{0}", please check permissions.
+
+util.read.error=Converter input is not readable "{0}", Please check permissions.