/*******************************************************************************
 * Copyright (c) 2003, 2005 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
 *******************************************************************************/
package org.eclipse.jst.j2ee.internal.common.operations;

import java.io.ByteArrayInputStream;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.commands.operations.AbstractOperation;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
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.eclipse.jdt.core.Flags;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.ITypeHierarchy;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.Signature;
import org.eclipse.jem.util.logger.proxy.Logger;
import org.eclipse.jem.workbench.utility.JemProjectUtilities;
import org.eclipse.wst.common.componentcore.internal.operation.ArtifactEditProviderOperation;
import org.eclipse.wst.common.frameworks.datamodel.IDataModel;

/**
 * NewJavaClassOperation is a data model operation that is used to create a default instance of a new java class
 * based on the input and properties set in the NewJavaClassDataModelProvider.  
 * @see org.eclipse.jst.j2ee.internal.common.operations.NewJavaClassDataModelProvider
 * 
 * It is a subclass of ArtifactEditProviderOperation and clients can invoke this operation as is or it may be subclassed to
 * add additional or modify behaviour.  The execute() method can be extended to drive this behaviour.
 * @see org.eclipse.wst.common.componentcore.internal.operation.ArtifactEditProviderOperation
 * 
 * The new java class is generated through the use of adding a series of static tokens defined within to
 * an ongoing string buffer.
 * 
 * The use of this class is EXPERIMENTAL and is subject to substantial changes.
 * 
 * This needs to be removed as it is legacy inherited from another team
 */
public class NewJavaClassOperation extends ArtifactEditProviderOperation {

	// Tokens for string buffer creation of default java class
	protected static final String EMPTY_STRING = ""; //$NON-NLS-1$
	protected static final String TAB = "\t"; //$NON-NLS-1$
	protected static final String SPACE = " "; //$NON-NLS-1$
	protected static final String DOT = "."; //$NON-NLS-1$
	protected static final String COMMA = ","; //$NON-NLS-1$
	protected static final String SEMICOLON = ";"; //$NON-NLS-1$
	protected static final String POUND = "#"; //$NON-NLS-1$
	protected static final String OPEN_PAR = "("; //$NON-NLS-1$
	protected static final String CLOSE_PAR = ")"; //$NON-NLS-1$
	protected static final String OPEN_BRA = "{"; //$NON-NLS-1$
	protected static final String CLOSE_BRA = "}"; //$NON-NLS-1$
	protected static final String lineSeparator = System.getProperty("line.separator"); //$NON-NLS-1$

	protected static final String JAVA_LANG_OBJECT = "java.lang.Object"; //$NON-NLS-1$
	protected static final String PACKAGE = "package "; //$NON-NLS-1$
	protected static final String CLASS = "class "; //$NON-NLS-1$
	protected static final String IMPORT = "import "; //$NON-NLS-1$
	protected static final String EXTENDS = "extends "; //$NON-NLS-1$
	protected static final String IMPLEMENTS = "implements "; //$NON-NLS-1$
	protected static final String THROWS = "throws "; //$NON-NLS-1$
	protected static final String SUPER = "super"; //$NON-NLS-1$
	protected static final String PUBLIC = "public "; //$NON-NLS-1$
	protected static final String PROTECTED = "protected "; //$NON-NLS-1$
	protected static final String PRIVATE = "private "; //$NON-NLS-1$
	protected static final String STATIC = "static "; //$NON-NLS-1$
	protected static final String ABSTRACT = "abstract "; //$NON-NLS-1$
	protected static final String FINAL = "final "; //$NON-NLS-1$
	protected static final String VOID = "void"; //$NON-NLS-1$
	protected static final String INT = "int"; //$NON-NLS-1$
	protected static final String BOOLEAN = "boolean"; //$NON-NLS-1$
	protected static final String MAIN_METHOD = "\tpublic static void main(String[] args) {"; //$NON-NLS-1$
	protected static final String TODO_COMMENT = "\t\t// TODO Auto-generated method stub"; //$NON-NLS-1$
	protected static final String RETURN_NULL = "\t\treturn null;"; //$NON-NLS-1$
	protected static final String RETURN_0 = "\t\treturn 0;"; //$NON-NLS-1$
	protected static final String RETURN_FALSE = "\t\treturn false;"; //$NON-NLS-1$

	/**
	 * This is a list of all the calculated import statements that will need to be added
	 */
	private List importStatements;

	/**
	 * This is a NewJavaClassOperation constructor.  Data models passed in should be instances
	 * of NewJavaClassDataModel.  This method does not accept null.  It will not return null.
	 * @see NewJavaClassDataModelProvider
	 * 
	 * @param dataModel
	 * @return NewJavaClassOperation
	 */
	public NewJavaClassOperation(IDataModel dataModel) {
		super(dataModel);
		importStatements = new ArrayList();
	}

	/**
	 * Subclasses may extend this method to add their own actions during execution.
	 * The implementation of the execute method drives the running of the operation.  This
	 * method will create the source folder, the java package, and then create the java file.
	 * This method will accept null.
	 * @see AbstractOperation#execute(org.eclipse.core.runtime.IProgressMonitor, org.eclipse.core.runtime.IAdaptable)
	 * 
	 * @param monitor ProgressMonitor
	 * @throws CoreException
	 * @throws InterruptedException
	 * @throws InvocationTargetException
	 */
	public IStatus doExecute(IProgressMonitor monitor, IAdaptable info) throws ExecutionException {
		// Ensure source folder exists
		IFolder sourceFolder = createJavaSourceFolder();
		// Ensure java package exists
		IPackageFragment pack = createJavaPackage();
		// Create java class
		createJavaFile(sourceFolder, pack);
		return OK_STATUS;
	}

	/**
	 * This method will return the java source folder as specified in the java class data model. 
	 * It will create the java source folder if it does not exist.  This method may return null.
	 * @see INewJavaClassDataModelProperties#SOURCE_FOLDER
	 * @see IFolder#create(boolean, boolean, org.eclipse.core.runtime.IProgressMonitor)
	 * 
	 * @return IFolder the java source folder
	 */
	protected final IFolder createJavaSourceFolder() {
		// Get the source folder name from the data model
		String folderFullPath = model.getStringProperty(INewJavaClassDataModelProperties.SOURCE_FOLDER);
		IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
		IFolder folder = root.getFolder(new Path(folderFullPath));
		// If folder does not exist, create the folder with the specified path
		if (!folder.exists()) {
			try {
				folder.create(true, true, null);
			} catch (CoreException e) {
				Logger.getLogger().log(e);
			}
		}
		// Return the source folder
		return folder;
	}

	/**
	 * This method will return the java package as specified by the new java class data model.
	 * If the package does not exist, it will create the package.  This method should not return
	 * null.
	 * @see INewJavaClassDataModelProperties#JAVA_PACKAGE
	 * @see IPackageFragmentRoot#createPackageFragment(java.lang.String, boolean, org.eclipse.core.runtime.IProgressMonitor)
	 * 
	 * @return IPackageFragment the java package
	 */
	protected final IPackageFragment createJavaPackage() {
		// Retrieve the package name from the java class data model
		String packageName = model.getStringProperty(INewJavaClassDataModelProperties.JAVA_PACKAGE);
		IPackageFragmentRoot packRoot = (IPackageFragmentRoot) model.getProperty(INewJavaClassDataModelProperties.JAVA_PACKAGE_FRAGMENT_ROOT);
		IPackageFragment pack =	packRoot.getPackageFragment(packageName);
		// Handle default package
		if (pack == null) {
			pack = packRoot.getPackageFragment(""); //$NON-NLS-1$
		}
		// Create the package fragment if it does not exist
		if (!pack.exists()) {
			String packName = pack.getElementName();
			try {
				pack = packRoot.createPackageFragment(packName, true, null);
			} catch (JavaModelException e) {
				Logger.getLogger().log(e);
			}
		}
		// Return the package
		return pack;
	}

	/**
	 * Subclasses may extend this method to provide their own java file creation path.
	 * This implementation will use the properties specified in the data model to create
	 * a default java class.  The class will be built using pre-defined tokens and will be
	 * built up using a string buffer.  The method getJavaFileContent will handle the building
	 * of the string buffer while this method will write those contents to the file.
	 * This method does not accept null parameters.
	 * @see INewJavaClassDataModelProperties#CLASS_NAME
	 * @see NewJavaClassOperation#getJavaFileContent(IPackageFragment, String)
	 * 
	 * @param sourceFolder
	 * @param pack
	 */
	protected void createJavaFile(IFolder sourceFolder, IPackageFragment pack) {
		// Retrieve properties from the java class data model
		String packageName = model.getStringProperty(INewJavaClassDataModelProperties.JAVA_PACKAGE);
		String className = model.getStringProperty(INewJavaClassDataModelProperties.CLASS_NAME);
		String fileName = className + ".java"; //$NON-NLS-1$
		//ICompilationUnit cu = null;
		try {
			// Get the java file content from the string buffer
			String content = getJavaFileContent(pack, className);
			// Create the compilation unit
			pack.createCompilationUnit(fileName, content, true, null);
			byte[] contentBytes = content.getBytes();
			IPath packageFullPath = new Path(packageName.replace('.', IPath.SEPARATOR));
			IPath javaFileFullPath = packageFullPath.append(fileName);
			IFile file = sourceFolder.getFile(javaFileFullPath);
			// Set the contents in the file if it already exists
			if (file != null && file.exists()) {
				file.setContents(new ByteArrayInputStream(contentBytes), false, true, null);
			} // If the file does not exist, create it with the contents
			else if (file != null) {
				file.create(new ByteArrayInputStream(contentBytes), false, null);
			}
			// editModel.getWorkingCopy(cu, true); //Track CU.
		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}

	/**
	 * This is intended for internal use only.  This is where the string buffer for the contents
	 * of the java file is built up using the properties in the data model and the predefined tokens.
	 * This method will not accept null parameters. It will not return null.
	 * @see NewJavaClassDataModelProvider
	 * @see NewJavaClassOperation#createJavaFile(IFolder, IPackageFragment)
	 * 
	 * @param pack
	 * @param className
	 * @return String java file contents
	 */
	private String getJavaFileContent(IPackageFragment pack, String className) {
		// Create the superclass name
		String superclassName = model.getStringProperty(INewJavaClassDataModelProperties.SUPERCLASS);
		List interfaces = (List) model.getProperty(INewJavaClassDataModelProperties.INTERFACES);
		String packageStatement = getPackageStatement(pack);
		// Create the import statements
		setupImportStatements(pack, superclassName, interfaces);
		// Create the class declaration
		String classDeclaration = getClassDeclaration(superclassName, className, interfaces);
		// Create the fields
		String fields = getFields();
		// Create the methods
		String methods = getMethodStubs(superclassName, className);

		StringBuffer contents = new StringBuffer();
		// Add the package statement to the buffer
		contents.append(packageStatement);
		// Add all the import statements to the buffer
		for (int i = 0; i < importStatements.size(); i++) {
			contents.append(IMPORT + importStatements.get(i) + SEMICOLON);
			contents.append(lineSeparator);
		}
		contents.append(lineSeparator);
		// Add the class declaration to the buffer
		contents.append(classDeclaration);
		// Add the fields to the buffer
		contents.append(fields);
		// Add the method bodies to the buffer
		contents.append(methods);
		contents.append(CLOSE_BRA);
		// Return the contents of the buffer
		return contents.toString();
	}

	/**
	 * This is intended for internal use only.  This method will return a package string for
	 * the class.  It will not accept a null parameter.  It will not return null.
	 * @see NewJavaClassOperation#getJavaFileContent(IPackageFragment, String)
	 * 
	 * @param pack
	 * @return String package statement
	 */
	private String getPackageStatement(IPackageFragment pack) {
		StringBuffer sb = new StringBuffer();
		// If it is not default package, add package statement
		if (!pack.isDefaultPackage()) {
			sb.append(PACKAGE + pack.getElementName() + SEMICOLON);
			sb.append(lineSeparator);
			sb.append(lineSeparator);
		}
		// Return contents of buffer
		return sb.toString();
	}

	/**
	 * This method is intended for internal use.  It checks to see if the qualified class name
	 * belongs to the specified package. This method will not accept nulls.  It will not return null.
	 * @see NewJavaClassOperation#setupImportStatements(IPackageFragment, String, List)
	 *
	 * @param packageFragment
	 * @param className
	 * @return boolean is class in this package?
	 */
	private boolean isSamePackage(IPackageFragment packageFragment, String className) {
		if (className != null && className.length() > 0) {
			String sPackageName = packageFragment.getElementName();
			String classPackageName = Signature.getQualifier(className);
			// Does the qualified class's package name match the passed in package's name?
			if (classPackageName.equals(sPackageName))
				return true;
		}
		return false;
	}

	/**
	 * This method is intended for internal use only.  This method will set up the required import
	 * statements and cache to the importStatements list.
	 * This method does not accept null parameters.
	 * @see NewJavaClassOperation#importStatements
	 * @see NewJavaClassOperation#getJavaFileContent(IPackageFragment, String)
	 * 
	 * @param pack
	 * @param superclassName
	 * @param interfaces
	 */
	private void setupImportStatements(IPackageFragment pack, String superclassName, List interfaces) {
		// If there is a superclass and it is not in the same package, add an import for it
		if (superclassName != null && superclassName.length() > 0) {
			if (!superclassName.equals(JAVA_LANG_OBJECT) && !isSamePackage(pack, superclassName)) {
				importStatements.add(superclassName);
			}
		}
		// Add an import the list of implemented interfaces
		if (interfaces != null && interfaces.size() > 0) {
			int size = interfaces.size();
			for (int i = 0; i < size; i++) {
				String interfaceName = (String) interfaces.get(i);
				importStatements.add(interfaceName);
			}
		}
	}

	/**
	 * This class is intended for internal use only.  This will build up the class declartion
	 * statement based off the properties set in the java class data model.
	 * This method does not accept null parameters.  It will not return null.
	 * @see NewJavaClassOperation#getJavaFileContent(IPackageFragment, String)
	 * 
	 * @param superclassName
	 * @param className
	 * @param interfaces
	 * @return String class declaration string
	 */
	private String getClassDeclaration(String superclassName, String className, List interfaces) {
		StringBuffer sb = new StringBuffer();
		// Append appropriate modifiers
		if (model.getBooleanProperty(INewJavaClassDataModelProperties.MODIFIER_PUBLIC))
			sb.append(PUBLIC);
		if (model.getBooleanProperty(INewJavaClassDataModelProperties.MODIFIER_ABSTRACT))
			sb.append(ABSTRACT);
		if (model.getBooleanProperty(INewJavaClassDataModelProperties.MODIFIER_FINAL))
			sb.append(FINAL);
		// Add the class token 
		sb.append(CLASS);
		// Add the class name
		sb.append(className + SPACE);
		// If there is a superclass, add the extends and super class name
		if (superclassName != null && superclassName.length() > 0 && !superclassName.equals(JAVA_LANG_OBJECT)) {
			int index = superclassName.lastIndexOf(DOT);
			if (index != -1)
				superclassName = superclassName.substring(index + 1);
			sb.append(EXTENDS + superclassName + SPACE);
		}
		// If there are interfaces, add the implements and then interate over the interface list
		if (interfaces != null && interfaces.size() > 0) {
			sb.append(IMPLEMENTS);
			int size = interfaces.size();
			for (int i = 0; i < size; i++) {
				String interfaceName = (String) interfaces.get(i);
				int index = interfaceName.lastIndexOf(DOT);
				if (index != -1)
					interfaceName = interfaceName.substring(index + 1);
				sb.append(interfaceName);
				if (i < size - 1)
					sb.append(COMMA);
				sb.append(SPACE);
			}
		}
		sb.append(OPEN_BRA);
		sb.append(lineSeparator);
		// Return the finished class declaration string
		return sb.toString();
	}

	/**
	 * Subclasses may extend this method to add their own fields.  The default implementation
	 * is not to have any fields.  This method will not return null.
	 * @see NewJavaClassOperation#getJavaFileContent(IPackageFragment, String)
	 * 
	 * @return String fields string
	 */
	protected String getFields() {
		return EMPTY_STRING;
	}

	/**
	 * This method is intended for internal use only.  This will build up a string with the
	 * contents of all the method stubs for the unimplemented methods defined in the interfaces.
	 * It will also add inherited constructors from the superclass as appropriate.
	 * This method does not accept null parameters.  It will not return null.
	 * @see NewJavaClassOperation#getJavaFileContent(IPackageFragment, String)
	 * 
	 * @param superclassName
	 * @param className
	 * @return String method stubs string
	 */
	private String getMethodStubs(String superclassName, String className) {
		StringBuffer sb = new StringBuffer();
		IJavaProject javaProj = JemProjectUtilities.getJavaProject(getTargetProject());
		if (model.getBooleanProperty(INewJavaClassDataModelProperties.MAIN_METHOD)) {
			// Add main method
			sb.append(MAIN_METHOD);
			sb.append(lineSeparator);
			sb.append(TODO_COMMENT);
			sb.append(lineSeparator);
			sb.append(TAB + CLOSE_BRA);
			sb.append(lineSeparator);
			sb.append(lineSeparator);
		}

		IType superClassType = null;
		if (model.getBooleanProperty(INewJavaClassDataModelProperties.CONSTRUCTOR) || model.getBooleanProperty(INewJavaClassDataModelProperties.ABSTRACT_METHODS)) {
			// Find super class type
			try {
				superClassType = javaProj.findType(superclassName);
			} catch (JavaModelException e) {
				Logger.getLogger().log(e);
			}
		}
		if (model.getBooleanProperty(INewJavaClassDataModelProperties.CONSTRUCTOR)) {
			// Implement constructors from superclass
			try {
				if (superClassType != null) {
					IMethod[] methods = superClassType.getMethods();
					for (int j = 0; j < methods.length; j++) {
						if (methods[j].isConstructor() && !Flags.isPrivate(methods[j].getFlags())) {
							String methodStub = getMethodStub(methods[j], superclassName, className);
							sb.append(methodStub);
						}
					}
				}
			} catch (JavaModelException e) {
				Logger.getLogger().log(e);
			}
		}
		// Add unimplemented methods defined in the interfaces list
		if (model.getBooleanProperty(INewJavaClassDataModelProperties.ABSTRACT_METHODS) && superClassType != null) {
			String methodStub = getUnimplementedMethodsFromSuperclass(superClassType, className);
			if (methodStub != null && methodStub.trim().length() > 0)
				sb.append(methodStub);
			methodStub = getUnimplementedMethodsFromInterfaces(superClassType, className, javaProj);
			if (methodStub != null && methodStub.trim().length() > 0)
				sb.append(methodStub);
		}
		// Add any user defined method stubs
		if (superClassType != null) {
			String userDefined = getUserDefinedMethodStubs(superClassType);
			if (userDefined != null && userDefined.trim().length() > 0)
				sb.append(userDefined);
		}
		// Return the methods string
		return sb.toString();
	}

	/**
	 * This method is intended for internal use only.  This will retrieve method stubs for
	 * unimplemented methods in the superclass that will need to be created in the new class.
	 * This method does not accept null parameters. It will not return null.
	 * @see NewJavaClassOperation#getMethodStubs(String, String)
	 * 
	 * @param superClassType
	 * @param className
	 * @return String unimplemented methods defined in superclass
	 */
	private String getUnimplementedMethodsFromSuperclass(IType superClassType, String className) {
		StringBuffer sb = new StringBuffer();
		try {
			// Implement abstract methods from superclass
			IMethod[] methods = superClassType.getMethods();
			for (int j = 0; j < methods.length; j++) {
				IMethod method = methods[j];
				int flags = method.getFlags();
				// Add if the method is abstract, not private or static, and the option is selected in data model
				if ((Flags.isAbstract(flags) && !Flags.isStatic(flags) && !Flags.isPrivate(flags)) || implementImplementedMethod(methods[j])) {
					String methodStub = getMethodStub(methods[j], superClassType.getFullyQualifiedName(), className);
					sb.append(methodStub);
				}
			}
		} catch (JavaModelException e) {
			Logger.getLogger().log(e);
		}
		// Return method stubs string
		return sb.toString();
	}

	/**
	 * This method is intended for internal use only.  This will retrieve method stubs for
	 * unimplemented methods defined in the interfaces that will need to be created in the new class.
	 * This method does not accept null parameters. It will not return null.
	 * @see NewJavaClassOperation#getMethodStubs(String, String)
	 * 
	 * @param superClassType
	 * @param className
	 * @param javaProj
	 * @return String unimplemented methods defined in interfaces
	 */
	private String getUnimplementedMethodsFromInterfaces(IType superClassType, String className, IJavaProject javaProj) {
		StringBuffer sb = new StringBuffer();
		try {
			// Implement defined methods from interfaces
			List interfaces = (List) model.getProperty(INewJavaClassDataModelProperties.INTERFACES);
			if (interfaces != null) {
				for (int i = 0; i < interfaces.size(); i++) {
					String qualifiedClassName = (String) interfaces.get(i);
					IType interfaceType = javaProj.findType(qualifiedClassName);
					IMethod[] methodArray = interfaceType.getMethods();
					// Make sure the method isn't already defined in the heirarchy
					for (int j = 0; j < methodArray.length; j++) {
						if (isMethodImplementedInHierarchy(methodArray[j], superClassType))
							continue;
						String methodStub = getMethodStub(methodArray[j], qualifiedClassName, className);
						sb.append(methodStub);
					}
				}
			}
		} catch (JavaModelException e) {
			Logger.getLogger().log(e);
		}
		// Return method stubs string
		return sb.toString();
	}

	/**
	 * This method is intended for internal use only.  Checks to see if the passed type name
	 * is of a primitive type.  This method does not accept null.  It will not return null.
	 * @see Signature#getElementType(java.lang.String)
	 * 
	 * @param typeName
	 * @return boolean is type Primitive?
	 */
	private boolean isPrimitiveType(String typeName) {
		char first = Signature.getElementType(typeName).charAt(0);
		return (first != Signature.C_RESOLVED && first != Signature.C_UNRESOLVED);
	}

	/**
	 * This method is intended for internal use only.  This will add import statements for the specified
	 * type if it is determined to be necessary. This does accept null parameters.  It will not return null.
	 * @see NewJavaClassOperation#getMethodStub(IMethod, String, String)
	 * 
	 * @param refTypeSig
	 * @param declaringType
	 * @return String type signature
	 * @throws JavaModelException
	 */
	private String resolveAndAdd(String refTypeSig, IType declaringType) throws JavaModelException {
		String resolvedTypeName = JavaModelUtil.getResolvedTypeName(refTypeSig, declaringType);
		// Could type not be resolved and is import statement missing?
		if (resolvedTypeName != null && !importStatements.contains(resolvedTypeName) && !resolvedTypeName.startsWith("java.lang")) { //$NON-NLS-1$
			importStatements.add(resolvedTypeName);
		}
		return Signature.toString(refTypeSig);
	}

	/**
	 * This method is intended for internal use only.  This will use the predefined tokens to generate the
	 * actual method stubs.  This method does not accept null parameters.  It will not return null.
	 * 
	 * @param method
	 * @param superClassName
	 * @param className
	 * @return String method stub
	 */
	private String getMethodStub(IMethod method, String superClassName, String className) {
		StringBuffer sb = new StringBuffer();
		try {
			IType parentType = method.getDeclaringType();
			String name = method.getElementName();
			String[] paramTypes = method.getParameterTypes();
			String[] paramNames = method.getParameterNames();
			String[] exceptionTypes = method.getExceptionTypes();

			// Parameters String
			String paramString = EMPTY_STRING;
			int nP = paramTypes.length;
			for (int i = 0; i < nP; i++) {
				String type = paramTypes[i];
				// update import statements
				if (!isPrimitiveType(type)) {
					type = resolveAndAdd(type, parentType);
				} else {
					type = Signature.toString(type);
				}

				int index = type.lastIndexOf(DOT);
				if (index != -1)
					type = type.substring(index + 1);
				paramString += type + SPACE + paramNames[i];
				if (i < nP - 1)
					paramString += COMMA + SPACE;
			}
			// Java doc
			sb.append("\t/* (non-Java-doc)"); //$NON-NLS-1$
			sb.append(lineSeparator);
			sb.append("\t * @see "); //$NON-NLS-1$
			sb.append(superClassName + POUND + name + OPEN_PAR);
			sb.append(paramString);
			sb.append(CLOSE_PAR);
			sb.append(lineSeparator);
			sb.append("\t */"); //$NON-NLS-1$
			sb.append(lineSeparator);
			// access
			sb.append(TAB);
			if (Flags.isPublic(method.getFlags()))
				sb.append(PUBLIC);
			else if (Flags.isProtected(method.getFlags()))
				sb.append(PROTECTED);
			else if (Flags.isPrivate(method.getFlags()))
				sb.append(PRIVATE);
			String returnType = null;
			if (method.isConstructor()) {
				sb.append(className);
			} else {
				// return type
				returnType = method.getReturnType();
				if (!isPrimitiveType(returnType)) {
					returnType = resolveAndAdd(returnType, parentType);
				} else {
					returnType = Signature.toString(returnType);
				}
				int idx = returnType.lastIndexOf(DOT);
				if (idx == -1)
					sb.append(returnType);
				else
					sb.append(returnType.substring(idx + 1));
				sb.append(SPACE);
				// name
				sb.append(name);
			}
			// Parameters
			sb.append(OPEN_PAR + paramString + CLOSE_PAR);
			// exceptions
			int nE = exceptionTypes.length;
			if (nE > 0) {
				sb.append(SPACE + THROWS);
				for (int i = 0; i < nE; i++) {
					String type = exceptionTypes[i];
					if (!isPrimitiveType(type)) {
						type = resolveAndAdd(type, parentType);
					} else {
						type = Signature.toString(type);
					}
					int index = type.lastIndexOf(DOT);
					if (index != -1)
						type = type.substring(index + 1);
					sb.append(type);
					if (i < nE - 1)
						sb.append(COMMA + SPACE);
				}
			}
			sb.append(SPACE + OPEN_BRA);
			sb.append(lineSeparator);
			if (method.isConstructor()) {
				sb.append(TAB + TAB + SUPER + OPEN_PAR);
				for (int i = 0; i < nP; i++) {
					sb.append(paramNames[i]);
					if (i < nP - 1)
						sb.append(COMMA + SPACE);
				}
				sb.append(CLOSE_PAR + SEMICOLON);
				sb.append(lineSeparator);
			} else {
				String methodBody = getMethodBody(method, returnType);
				sb.append(methodBody);
			}
			sb.append(TAB + CLOSE_BRA);
			sb.append(lineSeparator);
			sb.append(lineSeparator);
		} catch (JavaModelException e) {
			Logger.getLogger().log(e);
		}
		return sb.toString();
	}

	/**
	 * This method is intended for internal use only.  It checks to see whether or not the
	 * method is already implemented in the class heirarchy.
	 * It does not accept null parameters.  It will not return null.
	 * @see NewJavaClassOperation#getUnimplementedMethodsFromInterfaces(IType, String, IJavaProject)
	 * 
	 * @param method
	 * @param superClass
	 * @return boolean is method already in heirarchy?
	 */
	private boolean isMethodImplementedInHierarchy(IMethod method, IType superClass) {
		boolean ret = false;
		IMethod foundMethod = findMethodImplementationInHierarchy(method, superClass);
		// if the method exists and the property is set on the data model, then return true
		if (foundMethod != null && foundMethod.exists() && !implementImplementedMethod(method))
			ret = true;
		return ret;
	}

	/**
	 * This method is intended for internal use only.  This will recursively check the supertype heirarchy for
	 * the passed in method.  This will not accept null parameters.  It will return null if the method does
	 * not already exist in the heirarchy.
	 * @see NewJavaClassOperation#isMethodImplementedInHierarchy(IMethod, IType)
	 * 
	 * @param method
	 * @param superClass
	 * @return IMethod the method from the heirarchy
	 */
	private IMethod findMethodImplementationInHierarchy(IMethod method, IType superClass) {
		IMethod implementedMethod = null;
		try {
			if (superClass != null && superClass.exists()) {
				ITypeHierarchy tH = superClass.newSupertypeHierarchy(new NullProgressMonitor());
				implementedMethod = findMethodImplementationInHierarchy(tH, superClass, method.getElementName(), method.getParameterTypes(), method.isConstructor());
			}
		} catch (JavaModelException e) {
			//Ignore
		}
		return implementedMethod;
	}

	/**
	 * This method is intended for internal use only.  This will recursively check the supertype heirarchy for
	 * the passed in method.  This will not accept null parameters.  It will return null if the method does
	 * not already exist in the heirarchy.
	 * @see NewJavaClassOperation#findMethodImplementationInHierarchy(IMethod, IType)
	 * @see JavaModelUtil#findMethodImplementationInHierarchy(ITypeHierarchy, IType, String, String[], boolean)
	 * 
	 * @param tH
	 * @param thisType
	 * @param methodName
	 * @param parameterTypes
	 * @param isConstructor
	 * @return IMethod
	 * @throws JavaModelException
	 */
	private IMethod findMethodImplementationInHierarchy(ITypeHierarchy tH, IType thisType, String methodName, String parameterTypes[], boolean isConstructor) throws JavaModelException {
		IMethod found = JavaModelUtil.findMethod(methodName, parameterTypes, isConstructor, thisType);
		// If method exists make sure it is not abstract
		if (found != null && !Flags.isAbstract(found.getFlags())) {
			return found;
		}
		// Check recursively
		return JavaModelUtil.findMethodImplementationInHierarchy(tH, thisType, methodName, parameterTypes, isConstructor);
	}

	/**
	 * Subclasses may extend this method to provide their own specific method body definitions.
	 * The default implementation is to add a todo, and to return the appropriate type.
	 * This method does not accept null parameters.  It will not return null.
	 * @see NewJavaClassOperation#getMethodStub(IMethod, String, String)
	 * 
	 * @param method
	 * @param returnType
	 * @return String method body
	 */
	protected String getMethodBody(IMethod method, String returnType) {
		// Add a todo comment
		String body = TODO_COMMENT;
		body += lineSeparator;
		// Add the appropriate default return type
		if (returnType == null || returnType.equals(VOID))
			return body;
		if (returnType.equals(INT))
			body += RETURN_0;
		else if (returnType.equals(BOOLEAN))
			body += RETURN_FALSE;
		else
			body += RETURN_NULL;
		body += lineSeparator;
		// Return the method body
		return body;
	}

	/**
	 * Subclasses may extend this method to provide their own user defined method stubs.  The
	 * default implementation to just return an empty string.  This method will not accept
	 * null parameter.  It will not return null.
	 * @see NewJavaClassOperation#getMethodStubs(String, String)
	 * 
	 * @param superClassType
	 * @return String user defined methods
	 */
	protected String getUserDefinedMethodStubs(IType superClassType) {
		return EMPTY_STRING;
	}

	/**
	 * Subclasses may extend this method to provide their own specialized return on which nonimplemented
	 * methods to implement.  This does not accept a null parameter.  This will not return null.
	 * The default implementation is to always return false.
	 * 
	 * @param method
	 * @return boolean should implement method?
	 */
	protected boolean implementImplementedMethod(IMethod method) {
		return false;
	}
}
