templates for new file
diff --git a/core/plugins/org.eclipse.dltk.ui/META-INF/MANIFEST.MF b/core/plugins/org.eclipse.dltk.ui/META-INF/MANIFEST.MF
index 1d1fa97..2ed1f83 100644
--- a/core/plugins/org.eclipse.dltk.ui/META-INF/MANIFEST.MF
+++ b/core/plugins/org.eclipse.dltk.ui/META-INF/MANIFEST.MF
@@ -8,6 +8,7 @@
 Bundle-Localization: plugin
 Require-Bundle: org.eclipse.ui,
  org.eclipse.core.runtime,
+ org.eclipse.core.variables,
  org.eclipse.ui.workbench.texteditor,
  org.eclipse.jface.text,
  org.eclipse.ui.editors,
diff --git a/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/ui/preferences/CodeTemplateBlock.java b/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/ui/preferences/CodeTemplateBlock.java
index afa2548..b087044 100644
--- a/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/ui/preferences/CodeTemplateBlock.java
+++ b/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/ui/preferences/CodeTemplateBlock.java
@@ -128,7 +128,7 @@
 					return null;
 				}
 				if (category.isGroup()) {
-					return codeTemplateAccess.getCodeTemplateContextRegistry()
+					return codeTemplateAccess.getContextTypeRegistry()
 							.getContextType(contextTypeId);
 				} else {
 					return category;
@@ -460,7 +460,7 @@
 					.get(0);
 			Template template = data.getTemplate();
 			TemplateContextType type = codeTemplateAccess
-					.getCodeTemplateContextRegistry().getContextType(
+					.getContextTypeRegistry().getContextType(
 							template.getContextTypeId());
 			fTemplateProcessor.setContextType(type);
 			fPatternViewer.getDocument().set(template.getPattern());
@@ -542,8 +542,7 @@
 				contextTypeRegistry.addContextType(contextTypes[i]);
 			}
 		} else {
-			contextTypeRegistry = codeTemplateAccess
-					.getCodeTemplateContextRegistry();
+			contextTypeRegistry = codeTemplateAccess.getContextTypeRegistry();
 		}
 		EditTemplateDialog dialog = new EditTemplateDialog(toolkit, getShell(),
 				newTemplate, !isNew, data.isUserAdded(), category.isGroup(),
diff --git a/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/ui/preferences/CodeTemplatesPreferencePage.java b/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/ui/preferences/CodeTemplatesPreferencePage.java
index 9b2e283..4c6be58 100644
--- a/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/ui/preferences/CodeTemplatesPreferencePage.java
+++ b/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/ui/preferences/CodeTemplatesPreferencePage.java
@@ -18,7 +18,7 @@
 import org.eclipse.dltk.internal.ui.dialogs.StatusUtil;
 import org.eclipse.dltk.internal.ui.preferences.PropertyAndPreferencePage;
 import org.eclipse.dltk.ui.IDLTKUILanguageToolkit;
-import org.eclipse.dltk.ui.text.templates.ICodeTemplateAccess;
+import org.eclipse.dltk.ui.text.templates.ICodeTemplateArea;
 import org.eclipse.jface.text.templates.persistence.TemplatePersistenceData;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Control;
@@ -35,14 +35,14 @@
 	public static final String DATA_SELECT_TEMPLATE = "CodeTemplatePreferencePage.select_template"; //$NON-NLS-1$
 
 	private final IDLTKUILanguageToolkit toolkit;
-	private final ICodeTemplateAccess codeTemplateAccess;
+	private final ICodeTemplateArea codeTemplateArea;
 
 	private CodeTemplateBlock fCodeTemplateConfigurationBlock;
 
 	protected CodeTemplatesPreferencePage(IDLTKUILanguageToolkit toolkit,
-			ICodeTemplateAccess codeTemplateAccess) {
+			ICodeTemplateArea codeTemplateArea) {
 		this.toolkit = toolkit;
-		this.codeTemplateAccess = codeTemplateAccess;
+		this.codeTemplateArea = codeTemplateArea;
 		setTitle(PreferencesMessages.CodeTemplatesPreferencePage_title);
 	}
 
@@ -53,7 +53,7 @@
 		IWorkbenchPreferenceContainer container = (IWorkbenchPreferenceContainer) getContainer();
 		fCodeTemplateConfigurationBlock = new CodeTemplateBlock(
 				getNewStatusChangedListener(), getProject(), container,
-				toolkit, codeTemplateAccess);
+				toolkit, codeTemplateArea.getTemplateAccess());
 
 		super.createControl(parent);
 		// TODO PlatformUI.getWorkbench().getHelpSystem().setHelp(getControl(),
@@ -147,10 +147,10 @@
 			if (id instanceof String) {
 				final TemplatePersistenceData[] templates = fCodeTemplateConfigurationBlock.fTemplateStore
 						.getTemplateData();
-				TemplatePersistenceData template = null;
 				for (int index = 0; index < templates.length; index++) {
-					template = templates[index];
-					if (template.getId().equals(id)) {
+					TemplatePersistenceData template = templates[index];
+					if (id.equals(template.getId())
+							|| id.equals(template.getTemplate().getName())) {
 						fCodeTemplateConfigurationBlock
 								.postSetSelection(template);
 						break;
@@ -160,4 +160,19 @@
 		}
 		super.applyData(data);
 	}
+
+	/*
+	 * @see PropertyAndPreferencePage#getPreferencePageId()
+	 */
+	protected String getPreferencePageId() {
+		return codeTemplateArea.getTemplatePreferencePageId();
+	}
+
+	/*
+	 * @see PropertyAndPreferencePage#getPropertyPageId()
+	 */
+	protected String getPropertyPageId() {
+		return codeTemplateArea.getTemplatePropertyPageId();
+	}
+
 }
diff --git a/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/ui/text/templates/CodeTemplateAccess.java b/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/ui/text/templates/CodeTemplateAccess.java
index 336c63e..83dd2e6 100644
--- a/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/ui/text/templates/CodeTemplateAccess.java
+++ b/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/ui/text/templates/CodeTemplateAccess.java
@@ -20,7 +20,7 @@
 import org.eclipse.ui.editors.text.templates.ContributionTemplateStore;
 
 public abstract class CodeTemplateAccess implements ICodeTemplateAccess,
-		ICodeTemplateAccess.ICodeTemplateAccessInternal {
+		ITemplateAccess.ITemplateAccessInternal {
 
 	private final String preferenceQualifier;
 	private final String preferenceKey;
@@ -49,11 +49,10 @@
 	/*
 	 * @see ICodeTemplateAccess#getInstanceStore()
 	 */
-	public TemplateStore getCodeTemplateStore() {
+	public TemplateStore getTemplateStore() {
 		if (fCodeTemplateStore == null) {
 			fCodeTemplateStore = new ContributionTemplateStore(
-					getCodeTemplateContextRegistry(), preferenceStore,
-					preferenceKey);
+					getContextTypeRegistry(), preferenceStore, preferenceKey);
 			try {
 				fCodeTemplateStore.load();
 			} catch (IOException e) {
@@ -85,7 +84,7 @@
 	 * @return the template context type registry for the code generation
 	 *         templates
 	 */
-	public ContextTypeRegistry getCodeTemplateContextRegistry() {
+	public ContextTypeRegistry getContextTypeRegistry() {
 		if (fCodeTemplateContextTypeRegistry == null) {
 			fCodeTemplateContextTypeRegistry = createContextTypeRegistry();
 		}
diff --git a/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/ui/text/templates/FileTemplateContext.java b/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/ui/text/templates/FileTemplateContext.java
new file mode 100644
index 0000000..844fa23
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/ui/text/templates/FileTemplateContext.java
@@ -0,0 +1,120 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Anton Leherbauer (Wind River Systems) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.dltk.ui.text.templates;
+
+import java.util.Iterator;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.dltk.compiler.util.Util;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.DefaultLineTracker;
+import org.eclipse.jface.text.ILineTracker;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.templates.Template;
+import org.eclipse.jface.text.templates.TemplateBuffer;
+import org.eclipse.jface.text.templates.TemplateContext;
+import org.eclipse.jface.text.templates.TemplateContextType;
+import org.eclipse.jface.text.templates.TemplateException;
+import org.eclipse.jface.text.templates.TemplateTranslator;
+import org.eclipse.jface.text.templates.TemplateVariableResolver;
+
+/**
+ * A template context for plain file resources.
+ */
+public class FileTemplateContext extends TemplateContext {
+
+	private final String fLineDelimiter;
+
+	public FileTemplateContext(TemplateContextType contextType,
+			String lineDelimiter) {
+		super(contextType);
+		fLineDelimiter = lineDelimiter;
+	}
+
+	/*
+	 * @see TemplateContext#evaluate(Template)
+	 */
+	public TemplateBuffer evaluate(Template template)
+			throws BadLocationException, TemplateException {
+		// test that all variables are defined
+		Iterator iterator = getContextType().resolvers();
+		while (iterator.hasNext()) {
+			TemplateVariableResolver var = (TemplateVariableResolver) iterator
+					.next();
+			if (var.getClass() == FileTemplateContextType.FileTemplateVariableResolver.class) {
+				Assert.isNotNull(getVariable(var.getType()),
+						"Variable " + var.getType() + " not defined"); //$NON-NLS-1$ //$NON-NLS-2$
+			}
+		}
+
+		if (!canEvaluate(template))
+			return null;
+
+		String pattern = changeLineDelimiter(template.getPattern(),
+				fLineDelimiter);
+
+		TemplateTranslator translator = new TemplateTranslator();
+		TemplateBuffer buffer = translator.translate(pattern);
+		getContextType().resolve(buffer, this);
+		return buffer;
+	}
+
+	private static String changeLineDelimiter(String code, String lineDelim) {
+		try {
+			ILineTracker tracker = new DefaultLineTracker();
+			tracker.set(code);
+			int nLines = tracker.getNumberOfLines();
+			if (nLines == 1) {
+				return code;
+			}
+
+			StringBuffer buf = new StringBuffer();
+			for (int i = 0; i < nLines; i++) {
+				if (i != 0) {
+					buf.append(lineDelim);
+				}
+				IRegion region = tracker.getLineInformation(i);
+				String line = code.substring(region.getOffset(), region
+						.getOffset()
+						+ region.getLength());
+				buf.append(line);
+			}
+			return buf.toString();
+		} catch (BadLocationException e) {
+			// can not happen
+			return code;
+		}
+	}
+
+	/*
+	 * @see TemplateContext#canEvaluate(Template)
+	 */
+	public boolean canEvaluate(Template template) {
+		return true;
+	}
+
+	public void setResourceVariables(IFile file) {
+		setVariable(FileTemplateContextType.FILENAME, file.getName());
+		setVariable(FileTemplateContextType.FILEBASE, new Path(file.getName())
+				.removeFileExtension().lastSegment());
+		IPath location = file.getLocation();
+		setVariable(FileTemplateContextType.FILELOCATION,
+				location != null ? location.toOSString() : Util.EMPTY_STRING);
+		setVariable(FileTemplateContextType.FILEPATH, file.getFullPath()
+				.toString());
+		setVariable(FileTemplateContextType.PROJECTNAME, file.getProject()
+				.getName());
+	}
+
+}
diff --git a/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/ui/text/templates/FileTemplateContextType.java b/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/ui/text/templates/FileTemplateContextType.java
new file mode 100644
index 0000000..11987ec
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/ui/text/templates/FileTemplateContextType.java
@@ -0,0 +1,280 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Anton Leherbauer (Wind River Systems) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.dltk.ui.text.templates;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.variables.IStringVariableManager;
+import org.eclipse.core.variables.VariablesPlugin;
+import org.eclipse.dltk.compiler.util.Util;
+import org.eclipse.jface.text.templates.GlobalTemplateVariables;
+import org.eclipse.jface.text.templates.SimpleTemplateVariableResolver;
+import org.eclipse.jface.text.templates.TemplateContext;
+import org.eclipse.jface.text.templates.TemplateContextType;
+import org.eclipse.jface.text.templates.TemplateException;
+import org.eclipse.jface.text.templates.TemplateVariable;
+import org.eclipse.jface.text.templates.TemplateVariableResolver;
+import org.eclipse.jface.text.templates.TemplateVariableType;
+import org.eclipse.osgi.util.NLS;
+
+import com.ibm.icu.text.DateFormat;
+import com.ibm.icu.text.SimpleDateFormat;
+
+/**
+ * A generic template context type for file resources based on content-type.
+ */
+public class FileTemplateContextType extends TemplateContextType {
+
+	/* resolver types */
+	public static final String FILENAME = "file_name"; //$NON-NLS-1$
+	public static final String FILEBASE = "file_base"; //$NON-NLS-1$
+	public static final String FILELOCATION = "file_loc"; //$NON-NLS-1$
+	public static final String FILEPATH = "file_path"; //$NON-NLS-1$
+	public static final String PROJECTNAME = "project_name"; //$NON-NLS-1$
+
+	/**
+	 * Resolver that resolves to the variable defined in the context.
+	 */
+	static class FileTemplateVariableResolver extends
+			SimpleTemplateVariableResolver {
+		public FileTemplateVariableResolver(String type, String description) {
+			super(type, description);
+		}
+
+		protected String resolve(TemplateContext context) {
+			String value = context.getVariable(getType());
+			return value != null ? value : Util.EMPTY_STRING;
+		}
+	}
+
+	/**
+	 * This date variable evaluates to the current date in a specific format.
+	 */
+	static class DateVariableResolver extends SimpleTemplateVariableResolver {
+		private String fFormat;
+
+		public DateVariableResolver() {
+			super(
+					"date", TemplateMessages.FileTemplateContextType_variable_description_date); //$NON-NLS-1$
+		}
+
+		/*
+		 * @see
+		 * org.eclipse.jface.text.templates.TemplateVariableResolver#resolve
+		 * (org.eclipse.jface.text.templates.TemplateVariable,
+		 * org.eclipse.jface.text.templates.TemplateContext)
+		 */
+		public void resolve(TemplateVariable variable, TemplateContext context) {
+			fFormat = null;
+			TemplateVariableType type = variable.getVariableType();
+			List params = type.getParams();
+			if (params.size() == 1) {
+				fFormat = params.get(0).toString();
+			}
+			super.resolve(variable, context);
+		}
+
+		/*
+		 * @see
+		 * org.eclipse.jface.text.templates.SimpleTemplateVariableResolver#resolve
+		 * (org.eclipse.jface.text.templates.TemplateContext)
+		 */
+		protected String resolve(TemplateContext context) {
+			DateFormat f;
+			if (fFormat == null) {
+				f = DateFormat.getDateInstance();
+			} else {
+				f = new SimpleDateFormat(fFormat);
+			}
+			return f.format(new java.util.Date());
+		}
+	}
+
+	/**
+	 * Resolver that resolves to the value of a core variable.
+	 */
+	static class CoreVariableResolver extends SimpleTemplateVariableResolver {
+		private String fVariableName;
+		private String[] fArguments;
+
+		public CoreVariableResolver(String type) {
+			super(
+					type,
+					TemplateMessages.FileTemplateContextType__variable_description_eclipse);
+		}
+
+		/*
+		 * @see
+		 * org.eclipse.jface.text.templates.TemplateVariableResolver#resolve
+		 * (org.eclipse.jface.text.templates.TemplateVariable,
+		 * org.eclipse.jface.text.templates.TemplateContext)
+		 */
+		public void resolve(TemplateVariable variable, TemplateContext context) {
+			fVariableName = variable.getName();
+			TemplateVariableType type = variable.getVariableType();
+			List params = type.getParams();
+			fArguments = (String[]) params.toArray(new String[params.size()]);
+			super.resolve(variable, context);
+		}
+
+		/*
+		 * @see
+		 * org.eclipse.jface.text.templates.SimpleTemplateVariableResolver#resolve
+		 * (org.eclipse.jface.text.templates.TemplateContext)
+		 */
+		protected String resolve(TemplateContext context) {
+			StringBuffer expr = new StringBuffer("${"); //$NON-NLS-1$
+			expr.append(fVariableName);
+			for (int i = 0; i < fArguments.length; i++) {
+				expr.append(':').append(fArguments[i]);
+			}
+			expr.append('}');
+			IStringVariableManager mgr = VariablesPlugin.getDefault()
+					.getStringVariableManager();
+			try {
+				return mgr.performStringSubstitution(expr.toString(), false);
+			} catch (CoreException exc) {
+				return expr.toString();
+			}
+		}
+
+	}
+
+	public FileTemplateContextType() {
+		// global
+		addResolver(new GlobalTemplateVariables.Dollar());
+		addResolver(new DateVariableResolver());
+		addResolver(new GlobalTemplateVariables.Year());
+		addResolver(new GlobalTemplateVariables.Time());
+		addResolver(new GlobalTemplateVariables.User());
+		//addResolver(new CoreVariableResolver("eclipse")); //$NON-NLS-1$
+		addResourceVariables();
+	}
+
+	protected void addResourceVariables() {
+		addResolver(new FileTemplateVariableResolver(
+				FILENAME,
+				TemplateMessages.FileTemplateContextType_variable_description_filename));
+		addResolver(new FileTemplateVariableResolver(
+				FILEBASE,
+				TemplateMessages.FileTemplateContextType_variable_description_filebase));
+		addResolver(new FileTemplateVariableResolver(
+				FILELOCATION,
+				TemplateMessages.FileTemplateContextType_variable_description_fileloc));
+		addResolver(new FileTemplateVariableResolver(
+				FILEPATH,
+				TemplateMessages.FileTemplateContextType_variable_description_filepath));
+		addResolver(new FileTemplateVariableResolver(
+				PROJECTNAME,
+				TemplateMessages.FileTemplateContextType_variable_description_projectname));
+	}
+
+	protected TemplateVariableResolver getResolver(String type) {
+		// compatibility with editor template variables
+		if ("file".equals(type)) { //$NON-NLS-1$
+			type = FILENAME;
+		} else if ("project".equals(type) || "enclosing_project".equals(type)) { //$NON-NLS-1$ //$NON-NLS-2$
+			type = PROJECTNAME;
+		}
+		return super.getResolver(type);
+	}
+
+	protected void validateVariables(TemplateVariable[] variables)
+			throws TemplateException {
+		ArrayList required = new ArrayList(5);
+		for (int i = 0; i < variables.length; i++) {
+			String type = variables[i].getType();
+			if (getResolver(type) == null) {
+				throw new TemplateException(
+						NLS
+								.bind(
+										TemplateMessages.FileTemplateContextType_validate_unknownvariable,
+										type));
+			}
+			required.remove(type);
+		}
+		if (!required.isEmpty()) {
+			String missing = (String) required.get(0);
+			throw new TemplateException(
+					NLS
+							.bind(
+									TemplateMessages.FileTemplateContextType_validate_missingvariable,
+									missing));
+		}
+		super.validateVariables(variables);
+	}
+
+	/*
+	 * @see
+	 * org.eclipse.jface.text.templates.TemplateContextType#resolve(org.eclipse
+	 * .jface.text.templates.TemplateVariable,
+	 * org.eclipse.jface.text.templates.TemplateContext)
+	 */
+	public void resolve(TemplateVariable variable, TemplateContext context) {
+		String type = variable.getType();
+		TemplateVariableResolver resolver = getResolver(type);
+		if (resolver == null) {
+			resolver = new FileTemplateVariableResolver(type, ""); //$NON-NLS-1$
+		}
+		resolver.resolve(variable, context);
+	}
+
+	// public static void registerContextTypes(ContextTypeRegistry registry) {
+	// IContentTypeManager contentTypeMgr = Platform.getContentTypeManager();
+	// IContentType[] contentTypes = contentTypeMgr.getAllContentTypes();
+	// for (int i = 0; i < contentTypes.length; i++) {
+	// IContentType contentType = contentTypes[i];
+	// if (isTextContentType(contentType)
+	// && contentType
+	// .getFileSpecs(IContentType.FILE_EXTENSION_SPEC).length > 0) {
+	// final String contextTypeId = contextTypeIdForContentType(contentType);
+	// if (registry.getContextType(contextTypeId) == null) {
+	// registry.addContextType(new FileTemplateContextType(
+	// contextTypeId, contentType.getName()));
+	// }
+	// }
+	// }
+	// }
+
+	// public static String contextTypeIdForContentType(IContentType
+	// contentType) {
+	// return contentType.getId() + CONTEXTTYPE_SUFFIX;
+	// }
+	// public static boolean isFileTemplateContextType(String contextTypeId) {
+	// return contextTypeId.endsWith(CONTEXTTYPE_SUFFIX);
+	// }
+	// public static boolean isContextTypeForContentType(String contextTypeId,
+	// String contentTypeId) {
+	// return contextTypeId.endsWith(CONTEXTTYPE_SUFFIX) &&
+	// contextTypeId.startsWith(contentTypeId);
+	// }
+	// public static String contentTypeIdForContextType(String contextTypeId) {
+	// return contextTypeId.substring(0, contextTypeId.length() -
+	// CONTEXTTYPE_SUFFIX.length());
+	// }
+
+	// private static boolean isTextContentType(IContentType contentType) {
+	// if (contentType == null) {
+	// return false;
+	// }
+	// String id = contentType.getId();
+	// if (id.equals(CONTENTTYPE_TEXT)) {
+	// return true;
+	// }
+	//		if (id.indexOf(".pde.") != -1 || id.indexOf(".jdt.") != -1) { //$NON-NLS-1$ //$NON-NLS-2$
+	// return false;
+	// }
+	// return isTextContentType(contentType.getBaseType());
+	// }
+
+}
diff --git a/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/ui/text/templates/ICodeTemplateAccess.java b/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/ui/text/templates/ICodeTemplateAccess.java
index bfc2974..b0be47a 100644
--- a/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/ui/text/templates/ICodeTemplateAccess.java
+++ b/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/ui/text/templates/ICodeTemplateAccess.java
@@ -11,34 +11,7 @@
  *******************************************************************************/
 package org.eclipse.dltk.ui.text.templates;
 
-import org.eclipse.jface.text.templates.ContextTypeRegistry;
-import org.eclipse.jface.text.templates.persistence.TemplateStore;
-
-public interface ICodeTemplateAccess {
-
-	public interface ICodeTemplateAccessInternal {
-		void dispose();
-	}
-
-	String getPreferenceQualifier();
-
-	String getPreferenceKey();
-
-	/**
-	 * Returns the template context type registry for the code generation
-	 * templates.
-	 * 
-	 * @return the template context type registry for the code generation
-	 *         templates
-	 */
-	ContextTypeRegistry getCodeTemplateContextRegistry();
-
-	/**
-	 * Returns the template store for the code generation templates.
-	 * 
-	 * @return the template store for the code generation templates
-	 */
-	TemplateStore getCodeTemplateStore();
+public interface ICodeTemplateAccess extends ITemplateAccess {
 
 	ICodeTemplateCategory[] getCategories();
 
diff --git a/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/ui/text/templates/ICodeTemplateArea.java b/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/ui/text/templates/ICodeTemplateArea.java
new file mode 100644
index 0000000..1b7f8e3
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/ui/text/templates/ICodeTemplateArea.java
@@ -0,0 +1,22 @@
+/*******************************************************************************
+ * Copyright (c) 2009 xored software, Inc.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     xored software, Inc. - initial API and Implementation (Alex Panchenko)
+ *******************************************************************************/
+package org.eclipse.dltk.ui.text.templates;
+
+public interface ICodeTemplateArea {
+
+	ICodeTemplateAccess getTemplateAccess();
+
+	String getTemplatePreferencePageId();
+
+	String getTemplatePropertyPageId();
+
+}
diff --git a/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/ui/text/templates/ITemplateAccess.java b/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/ui/text/templates/ITemplateAccess.java
new file mode 100644
index 0000000..03d5c24
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/ui/text/templates/ITemplateAccess.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (c) 2009 xored software, Inc.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     xored software, Inc. - initial API and Implementation (Alex Panchenko)
+ *******************************************************************************/
+package org.eclipse.dltk.ui.text.templates;
+
+import org.eclipse.jface.text.templates.ContextTypeRegistry;
+import org.eclipse.jface.text.templates.persistence.TemplateStore;
+
+public interface ITemplateAccess {
+
+	public interface ITemplateAccessInternal {
+		void dispose();
+	}
+
+	String getPreferenceQualifier();
+
+	String getPreferenceKey();
+
+	/**
+	 * Returns the template context type registry for the code generation
+	 * templates.
+	 * 
+	 * @return the template context type registry for the code generation
+	 *         templates
+	 */
+	ContextTypeRegistry getContextTypeRegistry();
+
+	/**
+	 * Returns the template store for the code generation templates.
+	 * 
+	 * @return the template store for the code generation templates
+	 */
+	TemplateStore getTemplateStore();
+
+}
diff --git a/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/ui/text/templates/ITemplateContextFactory.java b/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/ui/text/templates/ITemplateContextFactory.java
new file mode 100644
index 0000000..ffd4509
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/ui/text/templates/ITemplateContextFactory.java
@@ -0,0 +1,20 @@
+/*******************************************************************************
+ * Copyright (c) 2009 xored software, Inc.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     xored software, Inc. - initial API and Implementation (Alex Panchenko)
+ *******************************************************************************/
+package org.eclipse.dltk.ui.text.templates;
+
+import org.eclipse.jface.text.templates.TemplateContext;
+
+public interface ITemplateContextFactory {
+
+	TemplateContext createContext(Object input);
+
+}
diff --git a/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/ui/text/templates/ProjectTemplateStore.java b/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/ui/text/templates/ProjectTemplateStore.java
index 70c336e..8653b51 100644
--- a/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/ui/text/templates/ProjectTemplateStore.java
+++ b/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/ui/text/templates/ProjectTemplateStore.java
@@ -30,22 +30,21 @@
 
 public class ProjectTemplateStore {
 
-	private final ICodeTemplateAccess fCodeTemplateAccess;
+	private final ITemplateAccess fTemplateAccess;
 	private final TemplateStore fInstanceStore;
 	private final TemplateStore fProjectStore;
 
-	public ProjectTemplateStore(ICodeTemplateAccess codeTemplateAccess,
-			IProject project) {
-		this.fCodeTemplateAccess = codeTemplateAccess;
-		this.fInstanceStore = codeTemplateAccess.getCodeTemplateStore();
+	public ProjectTemplateStore(ITemplateAccess templateAccess, IProject project) {
+		this.fTemplateAccess = templateAccess;
+		this.fInstanceStore = templateAccess.getTemplateStore();
 		if (project == null) {
 			fProjectStore = null;
 		} else {
 			final ScopedPreferenceStore projectSettings = new ScopedPreferenceStore(
-					new ProjectScope(project), codeTemplateAccess
+					new ProjectScope(project), templateAccess
 							.getPreferenceQualifier());
-			fProjectStore = new TemplateStore(projectSettings,
-					codeTemplateAccess.getPreferenceKey()) {
+			fProjectStore = new TemplateStore(projectSettings, templateAccess
+					.getPreferenceKey()) {
 				/*
 				 * Make sure we keep the id of added code templates - add
 				 * removes it in the usual add() method
@@ -64,7 +63,7 @@
 							TemplateReaderWriter writer = new TemplateReaderWriter();
 							writer.save(getTemplateData(false), output);
 
-							projectSettings.setValue(fCodeTemplateAccess
+							projectSettings.setValue(fTemplateAccess
 									.getPreferenceKey(), output.toString());
 							projectSettings.save();
 
@@ -72,7 +71,7 @@
 						}
 					}
 
-					projectSettings.setToDefault(fCodeTemplateAccess
+					projectSettings.setToDefault(fTemplateAccess
 							.getPreferenceKey());
 					projectSettings.save();
 				}
@@ -82,8 +81,8 @@
 
 	public boolean hasProjectSpecificTempates(IProject project) {
 		String pref = new ProjectScope(project).getNode(
-				fCodeTemplateAccess.getPreferenceQualifier()).get(
-				fCodeTemplateAccess.getPreferenceKey(), null);
+				fTemplateAccess.getPreferenceQualifier()).get(
+				fTemplateAccess.getPreferenceKey(), null);
 		if (pref != null && pref.trim().length() > 0) {
 			Reader input = new StringReader(pref);
 			TemplateReaderWriter reader = new TemplateReaderWriter();
diff --git a/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/ui/text/templates/SourceModuleTemplateContext.java b/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/ui/text/templates/SourceModuleTemplateContext.java
new file mode 100644
index 0000000..2acf181
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/ui/text/templates/SourceModuleTemplateContext.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2009 xored software, Inc.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     xored software, Inc. - initial API and Implementation (Alex Panchenko)
+ *******************************************************************************/
+package org.eclipse.dltk.ui.text.templates;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.dltk.core.ISourceModule;
+import org.eclipse.jface.text.templates.TemplateContextType;
+
+public class SourceModuleTemplateContext extends FileTemplateContext {
+
+	/**
+	 * @param contextType
+	 * @param lineDelimiter
+	 */
+	public SourceModuleTemplateContext(TemplateContextType contextType,
+			String lineDelimiter) {
+		super(contextType, lineDelimiter);
+	}
+
+	public void setSourceModuleVariables(ISourceModule module) {
+		// TODO add interpreter variables
+		final IResource resource = module.getResource();
+		if (resource instanceof IFile) {
+			setResourceVariables((IFile) resource);
+		}
+	}
+
+}
diff --git a/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/ui/text/templates/SourceModuleTemplateContextType.java b/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/ui/text/templates/SourceModuleTemplateContextType.java
new file mode 100644
index 0000000..cd22f4e
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/ui/text/templates/SourceModuleTemplateContextType.java
@@ -0,0 +1,21 @@
+/*******************************************************************************
+ * Copyright (c) 2009 xored software, Inc.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     xored software, Inc. - initial API and Implementation (Alex Panchenko)
+ *******************************************************************************/
+package org.eclipse.dltk.ui.text.templates;
+
+public class SourceModuleTemplateContextType extends FileTemplateContextType {
+
+	public SourceModuleTemplateContextType() {
+		super();
+		// TODO add interpreter variables
+	}
+
+}
diff --git a/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/ui/text/templates/TemplateMessages.java b/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/ui/text/templates/TemplateMessages.java
new file mode 100644
index 0000000..8bed9bf
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/ui/text/templates/TemplateMessages.java
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     QnX Software System
+ *     Anton Leherbauer (Wind River Systems)
+ *******************************************************************************/
+package org.eclipse.dltk.ui.text.templates;
+
+import org.eclipse.osgi.util.NLS;
+
+public final class TemplateMessages extends NLS {
+
+	private static final String BUNDLE_NAME = "org.eclipse.dltk.ui.text.templates.TemplateMessages";//$NON-NLS-1$
+
+	private TemplateMessages() {
+		// Do not instantiate
+	}
+
+	public static String CContextType_variable_description_file;
+	public static String CContextType_variable_description_enclosing_method;
+	public static String CContextType_variable_description_enclosing_project;
+	public static String CContextType_variable_description_enclosing_method_arguments;
+	public static String CContextType_variable_description_return_type;
+	public static String CContextType_variable_description_todo;
+	
+	public static String CodeTemplateContextType_variable_description_todo;
+	public static String CodeTemplateContextType_variable_description_typedeclaration;
+	public static String CodeTemplateContextType_variable_description_fieldname;
+	public static String CodeTemplateContextType_variable_description_fieldtype;
+	public static String CodeTemplateContextType_variable_description_typecomment;
+	public static String CodeTemplateContextType_variable_description_enclosingtype;
+	public static String CodeTemplateContextType_variable_description_typename;
+	public static String CodeTemplateContextType_variable_description_include_guard_symbol;
+	public static String CodeTemplateContextType_variable_description_enclosingmethod;
+	public static String CodeTemplateContextType_variable_description_bodystatement;
+	public static String CodeTemplateContextType_variable_description_returntype;
+	public static String CodeTemplateContextType_variable_description_filecomment;
+	public static String CodeTemplateContextType_validate_invalidcomment;
+	
+	public static String FileTemplateContextType__variable_description_eclipse;
+	public static String FileTemplateContextType_validate_unknownvariable;
+	public static String FileTemplateContextType_validate_missingvariable;
+	public static String FileTemplateContextType_variable_description_date;
+	public static String FileTemplateContextType_variable_description_filename;
+	public static String FileTemplateContextType_variable_description_filebase;
+	public static String FileTemplateContextType_variable_description_fileloc;
+	public static String FileTemplateContextType_variable_description_filepath;
+	public static String FileTemplateContextType_variable_description_projectname;
+
+	static {
+		NLS.initializeMessages(BUNDLE_NAME, TemplateMessages.class);
+	}
+}
\ No newline at end of file
diff --git a/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/ui/text/templates/TemplateMessages.properties b/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/ui/text/templates/TemplateMessages.properties
new file mode 100644
index 0000000..147a836
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/ui/text/templates/TemplateMessages.properties
@@ -0,0 +1,44 @@
+#########################################
+# Copyright (c) 2005, 2008 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+#     IBM Corporation - initial API and implementation
+#	  QnX Software System
+#     Anton Leherbauer (Wind River Systems)
+#########################################
+
+CContextType_variable_description_file=Filename of translation unit
+CContextType_variable_description_enclosing_method=Enclosing method name
+CContextType_variable_description_enclosing_project=Enclosing project name
+CContextType_variable_description_enclosing_method_arguments=Argument names of enclosing method
+CContextType_variable_description_return_type=Enclosing method return type
+CContextType_variable_description_todo=Todo task tag
+
+CodeTemplateContextType_variable_description_todo=Todo task tag
+CodeTemplateContextType_variable_description_typedeclaration=Generated type declaration
+CodeTemplateContextType_variable_description_fieldname=The name of field
+CodeTemplateContextType_variable_description_fieldtype=The type of the field
+CodeTemplateContextType_variable_description_typecomment=Content of code template 'Comments > Types'
+CodeTemplateContextType_variable_description_enclosingtype=The enclosing type
+CodeTemplateContextType_variable_description_typename=Name of the current type
+CodeTemplateContextType_variable_description_include_guard_symbol=Include guard symbol
+CodeTemplateContextType_variable_description_enclosingmethod=The enclosing method
+CodeTemplateContextType_variable_description_bodystatement=Return statement or super call
+CodeTemplateContextType_variable_description_returntype=Return type of the enclosing method
+CodeTemplateContextType_variable_description_filecomment=Content of code template 'Comments > Files'
+
+CodeTemplateContextType_validate_invalidcomment=Pattern is not a valid C/C++ comment.
+
+FileTemplateContextType__variable_description_eclipse=Resolve Eclipse core variables
+FileTemplateContextType_validate_unknownvariable=Variable ''{0}'' is unknown.
+FileTemplateContextType_validate_missingvariable=Variable ''{0}'' is required.
+FileTemplateContextType_variable_description_date= Current date
+FileTemplateContextType_variable_description_filename=Name of the file
+FileTemplateContextType_variable_description_filebase=Name of the file without extension
+FileTemplateContextType_variable_description_fileloc=File system location of the file
+FileTemplateContextType_variable_description_filepath=Workspace path of the file
+FileTemplateContextType_variable_description_projectname=Name of the enclosing project
diff --git a/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/ui/util/CodeGeneration.java b/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/ui/util/CodeGeneration.java
new file mode 100644
index 0000000..ea7ae71
--- /dev/null
+++ b/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/ui/util/CodeGeneration.java
@@ -0,0 +1,195 @@
+/*******************************************************************************
+ * Copyright (c) 2009 xored software, Inc.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     xored software, Inc. - initial API and Implementation (Alex Panchenko)
+ *******************************************************************************/
+package org.eclipse.dltk.ui.util;
+
+import java.util.HashSet;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.ProjectScope;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.preferences.IScopeContext;
+import org.eclipse.core.runtime.preferences.InstanceScope;
+import org.eclipse.dltk.compiler.util.Util;
+import org.eclipse.dltk.core.IBuffer;
+import org.eclipse.dltk.core.IModelElement;
+import org.eclipse.dltk.core.IScriptProject;
+import org.eclipse.dltk.core.ISourceModule;
+import org.eclipse.dltk.core.ModelException;
+import org.eclipse.dltk.internal.corext.util.Strings;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.Document;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.templates.Template;
+import org.eclipse.jface.text.templates.TemplateBuffer;
+import org.eclipse.jface.text.templates.TemplateContext;
+import org.eclipse.jface.text.templates.TemplateException;
+import org.eclipse.jface.text.templates.TemplateVariable;
+import org.eclipse.swt.SWT;
+import org.eclipse.text.edits.DeleteEdit;
+import org.eclipse.text.edits.InsertEdit;
+import org.eclipse.text.edits.MalformedTreeException;
+import org.eclipse.text.edits.MultiTextEdit;
+
+public class CodeGeneration {
+
+	public static String evaluateTemplate(TemplateContext context,
+			Template template, String[] fullLineVariables) throws CoreException {
+		TemplateBuffer buffer;
+		try {
+			buffer = context.evaluate(template);
+			if (buffer == null)
+				return null;
+			String str = fixFullLineVariables(buffer, fullLineVariables);
+			if (Strings.containsOnlyWhitespaces(str)) {
+				return null;
+			}
+			return str;
+		} catch (BadLocationException e) {
+			throw new CoreException(Status.CANCEL_STATUS);
+		} catch (TemplateException e) {
+			throw new CoreException(Status.CANCEL_STATUS);
+		}
+	}
+
+	// remove lines for empty variables, prefix multi-line variables
+	private static String fixFullLineVariables(TemplateBuffer buffer,
+			String[] variables) throws MalformedTreeException,
+			BadLocationException {
+		IDocument doc = new Document(buffer.getString());
+		int nLines = doc.getNumberOfLines();
+		MultiTextEdit edit = new MultiTextEdit();
+		HashSet removedLines = new HashSet();
+		for (int i = 0; i < variables.length; i++) {
+			TemplateVariable position = findVariable(buffer, variables[i]);
+			if (position == null) {
+				continue;
+			}
+			if (position.getLength() > 0) {
+				int[] offsets = position.getOffsets();
+				for (int j = 0; j < offsets.length; j++) {
+					final int offset = offsets[j];
+					try {
+						int startLine = doc.getLineOfOffset(offset);
+						int startOffset = doc.getLineOffset(startLine);
+						int endLine = doc.getLineOfOffset(offset
+								+ position.getLength());
+						String prefix = doc.get(startOffset, offset
+								- startOffset);
+						if (prefix.length() > 0 && startLine < endLine) {
+							for (int line = startLine + 1; line <= endLine; ++line) {
+								int lineOffset = doc.getLineOffset(line);
+								edit
+										.addChild(new InsertEdit(lineOffset,
+												prefix));
+							}
+						}
+					} catch (BadLocationException exc) {
+						break;
+					}
+				}
+			} else {
+				int[] offsets = position.getOffsets();
+				for (int k = 0; k < offsets.length; k++) {
+					int line = doc.getLineOfOffset(offsets[k]);
+					IRegion lineInfo = doc.getLineInformation(line);
+					int offset = lineInfo.getOffset();
+					String str = doc.get(offset, lineInfo.getLength());
+					if (Strings.containsOnlyWhitespaces(str)
+							&& nLines > line + 1
+							&& removedLines.add(new Integer(line))) {
+						int nextStart = doc.getLineOffset(line + 1);
+						int length = nextStart - offset;
+						edit.addChild(new DeleteEdit(offset, length));
+					}
+				}
+			}
+		}
+		edit.apply(doc, 0);
+		return doc.get();
+	}
+
+	private static TemplateVariable findVariable(TemplateBuffer buffer,
+			String variable) {
+		TemplateVariable[] positions = buffer.getVariables();
+		for (int i = 0; i < positions.length; i++) {
+			TemplateVariable curr = positions[i];
+			if (variable.equals(curr.getType())) {
+				return curr;
+			}
+		}
+		return null;
+	}
+
+	/**
+	 * Examines a string and returns the first line delimiter found.
+	 */
+	public static String getLineDelimiterUsed(IModelElement elem)
+			throws ModelException {
+		if (elem == null)
+			return Util.EMPTY_STRING;
+
+		ISourceModule cu = (ISourceModule) elem
+				.getAncestor(IModelElement.SOURCE_MODULE);
+		if (cu != null && cu.exists()) {
+			IBuffer buf = cu.getBuffer();
+			int length = buf.getLength();
+			for (int i = 0; i < length; i++) {
+				char ch = buf.getChar(i);
+				if (ch == SWT.CR) {
+					if (i + 1 < length) {
+						if (buf.getChar(i + 1) == SWT.LF) {
+							return "\r\n"; //$NON-NLS-1$
+						}
+					}
+					return "\r"; //$NON-NLS-1$
+				} else if (ch == SWT.LF) {
+					return "\n"; //$NON-NLS-1$
+				}
+			}
+		}
+		return getProjectLineDelimiter(elem.getScriptProject());
+	}
+
+	private static String getProjectLineDelimiter(IScriptProject cProject) {
+		IProject project = null;
+		if (cProject != null)
+			project = cProject.getProject();
+
+		String lineDelimiter = getLineDelimiterPreference(project);
+		if (lineDelimiter != null)
+			return lineDelimiter;
+
+		return Util.LINE_SEPARATOR;
+	}
+
+	public static String getLineDelimiterPreference(IProject project) {
+		IScopeContext[] scopeContext;
+		if (project != null) {
+			// project preference
+			scopeContext = new IScopeContext[] { new ProjectScope(project) };
+			String lineDelimiter = Platform.getPreferencesService().getString(
+					Platform.PI_RUNTIME, Platform.PREF_LINE_SEPARATOR, null,
+					scopeContext);
+			if (lineDelimiter != null)
+				return lineDelimiter;
+		}
+		// workspace preference
+		scopeContext = new IScopeContext[] { new InstanceScope() };
+		String platformDefault = System.getProperty("line.separator", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
+		return Platform.getPreferencesService().getString(Platform.PI_RUNTIME,
+				Platform.PREF_LINE_SEPARATOR, platformDefault, scopeContext);
+	}
+
+}
diff --git a/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/ui/wizards/Messages.java b/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/ui/wizards/Messages.java
index d55e244..d7929b8 100644
--- a/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/ui/wizards/Messages.java
+++ b/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/ui/wizards/Messages.java
@@ -16,11 +16,14 @@
 	public static String LinkedFolders_directory_label;
 	public static String LinkedFolders_environment_label;
 	public static String LinkedFolders_initializingFolders_taskName;
+	public static String NewSourceModulePage_ConfigureTemplates;
 	public static String NewSourceModulePage_file;
 	public static String NewSourceModulePage_fileAlreadyExists;
 	public static String NewSourceModulePage_noFoldersAvailable;
+	public static String NewSourceModulePage_noTemplate;
 	public static String NewSourceModulePage_pathCannotBeEmpty;
 	public static String NewSourceModulePage_selectScriptFolder;
+	public static String NewSourceModulePage_Template;
 	public static String NewSourceModuleWizard_errorInOpenInEditor;
 	public static String ProjectFolder_kind_libraryFolder;
 	public static String ProjectFolder_kind_folder;
diff --git a/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/ui/wizards/NewSourceModulePage.java b/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/ui/wizards/NewSourceModulePage.java
index 0f6ee05..a37bf2a 100644
--- a/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/ui/wizards/NewSourceModulePage.java
+++ b/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/ui/wizards/NewSourceModulePage.java
@@ -9,6 +9,11 @@
  *******************************************************************************/
 package org.eclipse.dltk.ui.wizards;
 
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.core.runtime.IStatus;
@@ -25,21 +30,37 @@
 import org.eclipse.dltk.core.IScriptFolder;
 import org.eclipse.dltk.core.ISourceModule;
 import org.eclipse.dltk.core.ModelException;
+import org.eclipse.dltk.internal.ui.util.SWTUtil;
+import org.eclipse.dltk.internal.ui.wizards.dialogfields.ComboDialogField;
 import org.eclipse.dltk.internal.ui.wizards.dialogfields.DialogField;
 import org.eclipse.dltk.internal.ui.wizards.dialogfields.IDialogFieldListener;
 import org.eclipse.dltk.internal.ui.wizards.dialogfields.LayoutUtil;
 import org.eclipse.dltk.internal.ui.wizards.dialogfields.StringDialogField;
 import org.eclipse.dltk.ui.ModelElementLabelProvider;
 import org.eclipse.dltk.ui.dialogs.StatusInfo;
+import org.eclipse.dltk.ui.preferences.CodeTemplatesPreferencePage;
+import org.eclipse.dltk.ui.text.templates.ICodeTemplateArea;
+import org.eclipse.dltk.ui.text.templates.SourceModuleTemplateContext;
+import org.eclipse.dltk.ui.util.CodeGeneration;
 import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IDialogSettings;
+import org.eclipse.jface.preference.PreferenceDialog;
+import org.eclipse.jface.text.templates.Template;
+import org.eclipse.jface.text.templates.TemplateContextType;
+import org.eclipse.jface.text.templates.persistence.TemplateStore;
 import org.eclipse.jface.viewers.ILabelProvider;
 import org.eclipse.jface.viewers.IStructuredSelection;
 import org.eclipse.jface.window.Window;
 import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.layout.GridData;
 import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Text;
 import org.eclipse.ui.dialogs.ElementListSelectionDialog;
+import org.eclipse.ui.dialogs.PreferencesUtil;
 
 public abstract class NewSourceModulePage extends NewContainerWizardPage {
 
@@ -79,9 +100,14 @@
 	 *            used to initialize the fields
 	 */
 	public void init(IStructuredSelection selection) {
+		if (getTemplateArea() != null) {
+			createTemplateField();
+		}
+
 		IModelElement element = getInitialScriptElement(selection);
 
 		initContainerPage(element);
+		updateTemplates();
 
 		updateStatus(new IStatus[] { containerStatus, fileChanged() });
 	}
@@ -94,6 +120,120 @@
 		DialogField.createEmptySpace(parent);
 	}
 
+	private static final String NO_TEMPLATE = Util.EMPTY_STRING;
+	private Template[] fTemplates;
+	private ComboDialogField fTemplateDialogField = null;
+
+	protected void createTemplateControls(Composite parent, int nColumns) {
+		fTemplateDialogField.doFillIntoGrid(parent, nColumns - 1);
+		LayoutUtil.setWidthHint(fTemplateDialogField.getComboControl(null),
+				getMaxFieldWidth());
+		final Button configureTemplates = new Button(parent, SWT.PUSH);
+		GridData configureData = new GridData(SWT.FILL, SWT.NONE, false, false);
+		configureData.widthHint = SWTUtil
+				.getButtonWidthHint(configureTemplates);
+		configureTemplates.setLayoutData(configureData);
+		configureTemplates
+				.setText(Messages.NewSourceModulePage_ConfigureTemplates);
+		configureTemplates.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				String templateName = null;
+				final Template template = getSelectedTemplate();
+				if (template != null) {
+					templateName = template.getName();
+				}
+				Map data = null;
+				if (templateName != null) {
+					data = new HashMap();
+					data.put(CodeTemplatesPreferencePage.DATA_SELECT_TEMPLATE,
+							templateName);
+				}
+				// TODO handle project specific preferences if any?
+				final String prefPageId = getTemplateArea()
+						.getTemplatePreferencePageId();
+				final PreferenceDialog dialog = PreferencesUtil
+						.createPreferenceDialogOn(getShell(), prefPageId,
+								new String[] { prefPageId }, data);
+				if (dialog.open() == Window.OK) {
+					updateTemplates();
+				}
+			}
+		});
+	}
+
+	protected void updateTemplates() {
+		if (fTemplateDialogField != null) {
+			Template selected = getSelectedTemplate();
+			String name = selected != null ? selected.getName()
+					: getLastUsedTemplateName();
+			fTemplates = getApplicableTemplates();
+			int idx = NO_TEMPLATE.equals(name) ? 0 : 1;
+			String[] names = new String[fTemplates.length + 1];
+			for (int i = 0; i < fTemplates.length; i++) {
+				names[i + 1] = fTemplates[i].getName();
+				if (name != null && name.equals(names[i + 1])) {
+					idx = i + 1;
+				}
+			}
+			names[0] = Messages.NewSourceModulePage_noTemplate;
+			fTemplateDialogField.setItems(names);
+			fTemplateDialogField.selectItem(idx);
+		}
+	}
+
+	protected Template[] getApplicableTemplates() {
+		final List result = new ArrayList();
+		final ICodeTemplateArea templateArea = getTemplateArea();
+		if (templateArea != null) {
+			final TemplateStore store = templateArea.getTemplateAccess()
+					.getTemplateStore();
+			final String[] contextTypeIds = getCodeTemplateContextTypeIds();
+			for (int i = 0; i < contextTypeIds.length; ++i) {
+				Template[] templates = store.getTemplates(contextTypeIds[i]);
+				for (int j = 0; j < templates.length; ++j) {
+					result.add(templates[j]);
+				}
+			}
+		}
+		return (Template[]) result.toArray(new Template[result.size()]);
+	}
+
+	protected String getLastUsedTemplateKey() {
+		return getClass().getName() + "_LAST_USED_TEMPLATE"; //$NON-NLS-1$
+	}
+
+	/**
+	 * @return the name of the template used in the previous dialog invocation.
+	 */
+	protected String getLastUsedTemplateName() {
+		final IDialogSettings dialogSettings = getDialogSettings();
+		return dialogSettings != null ? dialogSettings
+				.get(getLastUsedTemplateKey()) : null;
+	}
+
+	/**
+	 * Saves the name of the last used template.
+	 * 
+	 * @param name
+	 *            the name of a template, or an empty string for no template.
+	 */
+	protected void saveLastUsedTemplateName(String name) {
+		final IDialogSettings dialogSettings = getDialogSettings();
+		if (dialogSettings != null) {
+			dialogSettings.put(getLastUsedTemplateKey(), name);
+		}
+	}
+
+	protected Template getSelectedTemplate() {
+		if (fTemplateDialogField != null) {
+			int index = fTemplateDialogField.getSelectionIndex() - 1;
+			if (index >= 0 && index < fTemplates.length) {
+				return fTemplates[index];
+			}
+		}
+		return null;
+	}
+
 	public NewSourceModulePage() {
 		super("wizardPage"); //$NON-NLS-1$
 		setTitle(getPageTitle());
@@ -112,6 +252,12 @@
 		});
 	}
 
+	protected void createTemplateField() {
+		fTemplateDialogField = new ComboDialogField(SWT.READ_ONLY);
+		fTemplateDialogField
+				.setLabelText(Messages.NewSourceModulePage_Template);
+	}
+
 	protected void handleFieldChanged(String fieldName) {
 		super.handleFieldChanged(fieldName);
 		if (fieldName == CONTAINER) {
@@ -134,8 +280,10 @@
 
 		String fileName = getFileName();
 
-		final ISourceModule module = currentScriptFolder.createSourceModule(
-				fileName, getFileContent(), true, monitor);
+		final ISourceModule module = currentScriptFolder
+				.getSourceModule(fileName);
+		currentScriptFolder.createSourceModule(fileName,
+				getFileContent(module), true, monitor);
 
 		return module;
 	}
@@ -155,6 +303,9 @@
 		createContainerControls(composite, nColumns);
 		// createPackageControls(composite, nColumns);
 		createFileControls(composite, nColumns);
+		if (fTemplateDialogField != null) {
+			createTemplateControls(composite, nColumns);
+		}
 
 		setControl(composite);
 		Dialog.applyDialogFont(composite);
@@ -248,7 +399,53 @@
 
 	protected abstract String getPageDescription();
 
-	protected String getFileContent() {
-		return ""; //$NON-NLS-1$
+	protected ICodeTemplateArea getTemplateArea() {
+		return null;
 	}
+
+	protected String[] getCodeTemplateContextTypeIds() {
+		return null;
+	}
+
+	protected String getDefaultCodeTemplateId() {
+		return null;
+	}
+
+	protected String getFileContent(ISourceModule module) throws CoreException {
+		final ICodeTemplateArea templateArea = getTemplateArea();
+		if (templateArea != null) {
+			final Template template = getSelectedTemplate();
+			saveLastUsedTemplateName(template != null ? template.getName()
+					: NO_TEMPLATE);
+			if (template != null) {
+				final TemplateContextType contextType = templateArea
+						.getTemplateAccess().getContextTypeRegistry()
+						.getContextType(template.getContextTypeId());
+				// TODO introduce a way to create context by contextType
+				final SourceModuleTemplateContext context = new SourceModuleTemplateContext(
+						contextType, CodeGeneration
+								.getLineDelimiterUsed(module));
+				// String fileComment = getFileComment(file, lineDelimiter);
+				// context.setVariable(CodeTemplateContextType.FILE_COMMENT,
+				//					fileComment != null ? fileComment : ""); //$NON-NLS-1$
+				// ICProject cproject = CoreModel.getDefault().create(
+				// file.getProject());
+				// String includeGuardSymbol = generateIncludeGuardSymbol(file
+				// .getName(), cproject);
+				// context.setVariable(CodeTemplateContextType.INCLUDE_GUARD_SYMBOL,
+				//					includeGuardSymbol != null ? includeGuardSymbol : ""); //$NON-NLS-1$
+				context.setSourceModuleVariables(module);
+				final String[] fullLine = {};
+				final String result = CodeGeneration.evaluateTemplate(context,
+						template, fullLine);
+				return result != null ? result : Util.EMPTY_STRING;
+			}
+		}
+		return getFileContent();
+	}
+
+	protected String getFileContent() {
+		return Util.EMPTY_STRING;
+	}
+
 }
diff --git a/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/ui/wizards/messages.properties b/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/ui/wizards/messages.properties
index 4f0bb60..5641a34 100644
--- a/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/ui/wizards/messages.properties
+++ b/core/plugins/org.eclipse.dltk.ui/src/org/eclipse/dltk/ui/wizards/messages.properties
@@ -10,11 +10,14 @@
 LinkedFolders_directory_label=Directory:
 LinkedFolders_environment_label=Environment:
 LinkedFolders_initializingFolders_taskName=Initializing folders...
+NewSourceModulePage_ConfigureTemplates=Configure...
 NewSourceModulePage_pathCannotBeEmpty=Path cannot be empty
 NewSourceModulePage_fileAlreadyExists=File already exists
 NewSourceModulePage_file=File: 
 NewSourceModulePage_selectScriptFolder=Select Script Folder
 NewSourceModulePage_noFoldersAvailable=No folders available
+NewSourceModulePage_noTemplate=<None>
+NewSourceModulePage_Template=Template
 NewSourceModuleWizard_errorInOpenInEditor=Error in openInEditor({0})
 ProjectFolder_kind_libraryFolder=Library Folder
 ProjectFolder_kind_folder=Folder