package org.eclipse.jst.j2ee.internal.web.operations;

import java.util.*;
import org.eclipse.jst.j2ee.internal.common.operations.*;

public class ServletTemplate
{
  protected static String nl;
  public static synchronized ServletTemplate create(String lineSeparator)
  {
    nl = lineSeparator;
    ServletTemplate result = new ServletTemplate();
    nl = null;
    return result;
  }

  public final String NL = nl == null ? (System.getProperties().getProperty("line.separator")) : nl; //$NON-NLS-1$
  protected final String TEXT_1 = "package "; //$NON-NLS-1$
  protected final String TEXT_2 = ";"; //$NON-NLS-1$
  protected final String TEXT_3 = NL;
  protected final String TEXT_4 = NL + "import "; //$NON-NLS-1$
  protected final String TEXT_5 = ";"; //$NON-NLS-1$
  protected final String TEXT_6 = NL;
  protected final String TEXT_7 = NL;
  protected final String TEXT_8 = "/**" + NL + " * Servlet implementation class "; //$NON-NLS-1$ //$NON-NLS-2$
  protected final String TEXT_9 = NL + " *" + NL + " * @web.servlet" + NL + " *   name=\""; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
  protected final String TEXT_10 = "\"" + NL + " *   display-name=\""; //$NON-NLS-1$ //$NON-NLS-2$
  protected final String TEXT_11 = "\""; //$NON-NLS-1$
  protected final String TEXT_12 = NL + " *   description=\""; //$NON-NLS-1$
  protected final String TEXT_13 = "\""; //$NON-NLS-1$
  protected final String TEXT_14 = NL + " *" + NL + " * @web.servlet-mapping" + NL + " *   url-pattern=\""; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
  protected final String TEXT_15 = "\""; //$NON-NLS-1$
  protected final String TEXT_16 = NL + " *" + NL + " * @web.servlet-init-param" + NL + " *    name=\""; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
  protected final String TEXT_17 = "\"" + NL + " *    value=\""; //$NON-NLS-1$ //$NON-NLS-2$
  protected final String TEXT_18 = "\""; //$NON-NLS-1$
  protected final String TEXT_19 = NL + " *    description=\""; //$NON-NLS-1$
  protected final String TEXT_20 = "\""; //$NON-NLS-1$
  protected final String TEXT_21 = NL + " */"; //$NON-NLS-1$
  protected final String TEXT_22 = NL + "@WebServlet"; //$NON-NLS-1$
  protected final String TEXT_23 = "(\""; //$NON-NLS-1$
  protected final String TEXT_24 = "\")"; //$NON-NLS-1$
  protected final String TEXT_25 = "({ "; //$NON-NLS-1$
  protected final String TEXT_26 = ", "; //$NON-NLS-1$
  protected final String TEXT_27 = "\""; //$NON-NLS-1$
  protected final String TEXT_28 = "\""; //$NON-NLS-1$
  protected final String TEXT_29 = " })"; //$NON-NLS-1$
  protected final String TEXT_30 = "("; //$NON-NLS-1$
  protected final String TEXT_31 = ", "; //$NON-NLS-1$
  protected final String TEXT_32 = NL + "\t\t"; //$NON-NLS-1$
  protected final String TEXT_33 = " = \""; //$NON-NLS-1$
  protected final String TEXT_34 = "\""; //$NON-NLS-1$
  protected final String TEXT_35 = " = { "; //$NON-NLS-1$
  protected final String TEXT_36 = ", "; //$NON-NLS-1$
  protected final String TEXT_37 = NL + "\t\t\t\t"; //$NON-NLS-1$
  protected final String TEXT_38 = "\""; //$NON-NLS-1$
  protected final String TEXT_39 = "\""; //$NON-NLS-1$
  protected final String TEXT_40 = NL + "\t\t"; //$NON-NLS-1$
  protected final String TEXT_41 = " "; //$NON-NLS-1$
  protected final String TEXT_42 = "}"; //$NON-NLS-1$
  protected final String TEXT_43 = " = { "; //$NON-NLS-1$
  protected final String TEXT_44 = ", "; //$NON-NLS-1$
  protected final String TEXT_45 = NL + "\t\t\t\t@WebInitParam(name = \""; //$NON-NLS-1$
  protected final String TEXT_46 = "\", value = \""; //$NON-NLS-1$
  protected final String TEXT_47 = "\""; //$NON-NLS-1$
  protected final String TEXT_48 = ", description = \""; //$NON-NLS-1$
  protected final String TEXT_49 = "\""; //$NON-NLS-1$
  protected final String TEXT_50 = ")"; //$NON-NLS-1$
  protected final String TEXT_51 = NL + "\t\t}"; //$NON-NLS-1$
  protected final String TEXT_52 = ")"; //$NON-NLS-1$
  protected final String TEXT_53 = NL + "public "; //$NON-NLS-1$
  protected final String TEXT_54 = "abstract "; //$NON-NLS-1$
  protected final String TEXT_55 = "final "; //$NON-NLS-1$
  protected final String TEXT_56 = "class "; //$NON-NLS-1$
  protected final String TEXT_57 = " extends "; //$NON-NLS-1$
  protected final String TEXT_58 = " implements "; //$NON-NLS-1$
  protected final String TEXT_59 = ", "; //$NON-NLS-1$
  protected final String TEXT_60 = " {"; //$NON-NLS-1$
  protected final String TEXT_61 = NL + "\tprivate static final long serialVersionUID = 1L;"; //$NON-NLS-1$
  protected final String TEXT_62 = NL + NL + "    /**" + NL + "     * Default constructor. " + NL + "     */" + NL + "    public "; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
  protected final String TEXT_63 = "() {" + NL + "        // TODO Auto-generated constructor stub" + NL + "    }"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
  protected final String TEXT_64 = NL + "       " + NL + "    /**" + NL + "     * @see "; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
  protected final String TEXT_65 = "#"; //$NON-NLS-1$
  protected final String TEXT_66 = "("; //$NON-NLS-1$
  protected final String TEXT_67 = ")" + NL + "     */" + NL + "    public "; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
  protected final String TEXT_68 = "("; //$NON-NLS-1$
  protected final String TEXT_69 = ") {" + NL + "        super("; //$NON-NLS-1$ //$NON-NLS-2$
  protected final String TEXT_70 = ");" + NL + "        // TODO Auto-generated constructor stub" + NL + "    }"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
  protected final String TEXT_71 = NL + NL + "\t/**" + NL + "     * @see "; //$NON-NLS-1$ //$NON-NLS-2$
  protected final String TEXT_72 = "#"; //$NON-NLS-1$
  protected final String TEXT_73 = "("; //$NON-NLS-1$
  protected final String TEXT_74 = ")" + NL + "     */" + NL + "    public "; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
  protected final String TEXT_75 = " "; //$NON-NLS-1$
  protected final String TEXT_76 = "("; //$NON-NLS-1$
  protected final String TEXT_77 = ") {" + NL + "        // TODO Auto-generated method stub"; //$NON-NLS-1$ //$NON-NLS-2$
  protected final String TEXT_78 = NL + "\t\t\treturn "; //$NON-NLS-1$
  protected final String TEXT_79 = ";"; //$NON-NLS-1$
  protected final String TEXT_80 = NL + "    }"; //$NON-NLS-1$
  protected final String TEXT_81 = NL + NL + "\t/**" + NL + "\t * @see Servlet#init(ServletConfig)" + NL + "\t */" + NL + "\tpublic void init(ServletConfig config) throws ServletException {" + NL + "\t\t// TODO Auto-generated method stub" + NL + "\t}"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$
  protected final String TEXT_82 = NL + NL + "\t/**" + NL + "\t * @see Servlet#destroy()" + NL + "\t */" + NL + "\tpublic void destroy() {" + NL + "\t\t// TODO Auto-generated method stub" + NL + "\t}"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$
  protected final String TEXT_83 = NL + NL + "\t/**" + NL + "\t * @see Servlet#getServletConfig()" + NL + "\t */" + NL + "\tpublic ServletConfig getServletConfig() {" + NL + "\t\t// TODO Auto-generated method stub" + NL + "\t\treturn null;" + NL + "\t}"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$
  protected final String TEXT_84 = NL + NL + "\t/**" + NL + "\t * @see Servlet#getServletInfo()" + NL + "\t */" + NL + "\tpublic String getServletInfo() {" + NL + "\t\t// TODO Auto-generated method stub" + NL + "\t\treturn null; " + NL + "\t}"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$
  protected final String TEXT_85 = NL + NL + "\t/**" + NL + "\t * @see Servlet#service(ServletRequest request, ServletResponse response)" + NL + "\t */" + NL + "\tpublic void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {" + NL + "\t\t// TODO Auto-generated method stub" + NL + "\t}"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$
  protected final String TEXT_86 = NL + NL + "\t/**" + NL + "\t * @see HttpServlet#service(HttpServletRequest request, HttpServletResponse response)" + NL + "\t */" + NL + "\tprotected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {" + NL + "\t\t// TODO Auto-generated method stub" + NL + "\t}"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$
  protected final String TEXT_87 = NL + NL + "\t/**" + NL + "\t * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)" + NL + "\t */" + NL + "\tprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {" + NL + "\t\t// TODO Auto-generated method stub" + NL + "\t}"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$
  protected final String TEXT_88 = NL + NL + "\t/**" + NL + "\t * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)" + NL + "\t */" + NL + "\tprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {" + NL + "\t\t// TODO Auto-generated method stub" + NL + "\t}"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$
  protected final String TEXT_89 = NL + NL + "\t/**" + NL + "\t * @see HttpServlet#doPut(HttpServletRequest, HttpServletResponse)" + NL + "\t */" + NL + "\tprotected void doPut(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {" + NL + "\t\t// TODO Auto-generated method stub" + NL + "\t}"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$
  protected final String TEXT_90 = NL + NL + "\t/**" + NL + "\t * @see HttpServlet#doDelete(HttpServletRequest, HttpServletResponse)" + NL + "\t */" + NL + "\tprotected void doDelete(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {" + NL + "\t\t// TODO Auto-generated method stub" + NL + "\t}"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$
  protected final String TEXT_91 = NL + NL + "\t/**" + NL + "\t * @see HttpServlet#doHead(HttpServletRequest, HttpServletResponse)" + NL + "\t */" + NL + "\tprotected void doHead(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {" + NL + "\t\t// TODO Auto-generated method stub" + NL + "\t}"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$
  protected final String TEXT_92 = NL + NL + "\t/**" + NL + "\t * @see HttpServlet#doOptions(HttpServletRequest, HttpServletResponse)" + NL + "\t */" + NL + "\tprotected void doOptions(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {" + NL + "\t\t// TODO Auto-generated method stub" + NL + "\t}"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$
  protected final String TEXT_93 = NL + NL + "\t/**" + NL + "\t * @see HttpServlet#doTrace(HttpServletRequest, HttpServletResponse)" + NL + "\t */" + NL + "\tprotected void doTrace(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {" + NL + "\t\t// TODO Auto-generated method stub" + NL + "\t}"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$
  protected final String TEXT_94 = NL + NL + "}"; //$NON-NLS-1$
  protected final String TEXT_95 = NL;

  public String generate(Object argument)
  {
    final StringBuffer stringBuffer = new StringBuffer();
     CreateServletTemplateModel model = (CreateServletTemplateModel) argument; 
    
	model.removeFlags(CreateJavaEEArtifactTemplateModel.FLAG_QUALIFIED_SUPERCLASS_NAME); 

    
	if (model.getJavaPackageName() != null && model.getJavaPackageName().length() > 0) {

    stringBuffer.append(TEXT_1);
    stringBuffer.append( model.getJavaPackageName() );
    stringBuffer.append(TEXT_2);
    
	}

    stringBuffer.append(TEXT_3);
     
	Collection<String> imports = model.getImports();
	for (String anImport : imports) { 

    stringBuffer.append(TEXT_4);
    stringBuffer.append( anImport );
    stringBuffer.append(TEXT_5);
     
	}

    stringBuffer.append(TEXT_6);
    stringBuffer.append(TEXT_7);
    stringBuffer.append(TEXT_8);
    stringBuffer.append( model.getClassName() );
     
	if (model.isAnnotated()) { 

    stringBuffer.append(TEXT_9);
    stringBuffer.append( model.getServletName() );
    stringBuffer.append(TEXT_10);
    stringBuffer.append( model.getServletName() );
    stringBuffer.append(TEXT_11);
     
		if (model.getDescription() != null && model.getDescription().length() > 0) { 

    stringBuffer.append(TEXT_12);
    stringBuffer.append( model.getDescription() );
    stringBuffer.append(TEXT_13);
     
		} 
		
		List<String[]> mappings = model.getServletMappings();
 		if (mappings != null && mappings.size() > 0) {
			for (int i = 0; i < mappings.size(); i++) {
				String map = model.getServletMapping(i); 
    stringBuffer.append(TEXT_14);
    stringBuffer.append( map );
    stringBuffer.append(TEXT_15);
     
			} 
		}
 		List<String[]> initParams = model.getInitParams();
 		if (initParams != null && initParams.size() > 0) {
    		for (int i = 0; i < initParams.size(); i++) {
				String name = model.getInitParam(i, CreateServletTemplateModel.NAME);
				String value = model.getInitParam(i, CreateServletTemplateModel.VALUE);
 				String description = model.getInitParam(i, CreateServletTemplateModel.DESCRIPTION); 

    stringBuffer.append(TEXT_16);
    stringBuffer.append( name );
    stringBuffer.append(TEXT_17);
    stringBuffer.append( value );
    stringBuffer.append(TEXT_18);
     
				if (description != null && description.length() > 0) { 

    stringBuffer.append(TEXT_19);
    stringBuffer.append( description );
    stringBuffer.append(TEXT_20);
    
				}
			} 
		} 
	} 

    stringBuffer.append(TEXT_21);
     
	if ("3.0".equals(model.getJavaEEVersion())) {  //$NON-NLS-1$

    stringBuffer.append(TEXT_22);
    
		Map<String, Object> params = model.getClassAnnotationParams();
		if (params.size() == 1 && params.containsKey(CreateServletTemplateModel.ATT_URL_PATTERNS)) {
			List<String[]> mappings = (List<String[]>) params.get(CreateServletTemplateModel.ATT_URL_PATTERNS);
			if (mappings.size() == 1) {
				String value = mappings.get(0)[0];

    stringBuffer.append(TEXT_23);
    stringBuffer.append( value );
    stringBuffer.append(TEXT_24);
    
			} else {

    stringBuffer.append(TEXT_25);
    
				boolean needComma = false;
				for (String[] mapping : mappings) {
					if (needComma) {

    stringBuffer.append(TEXT_26);
    
					}

    stringBuffer.append(TEXT_27);
    stringBuffer.append( mapping[0] );
    stringBuffer.append(TEXT_28);
    
					needComma = true;
				}

    stringBuffer.append(TEXT_29);
    
			}
		} else if (!params.isEmpty()) { 

    stringBuffer.append(TEXT_30);
    
			Set<String> keys = params.keySet();
			boolean needNewLine = keys.contains(CreateServletTemplateModel.ATT_INIT_PARAMS) || 
					(keys.contains(CreateServletTemplateModel.ATT_URL_PATTERNS) && 
							((List<String[]>) params.get(CreateServletTemplateModel.ATT_URL_PATTERNS)).size() > 1);
			boolean needComma = false;
			for (String key : keys) {
				if (needComma) {

    stringBuffer.append(TEXT_31);
    
				}
				
				if (needNewLine) {

    stringBuffer.append(TEXT_32);
    
				} 
			
				if (key.equals(CreateServletTemplateModel.ATT_NAME) || key.equals(CreateServletTemplateModel.ATT_DESCRIPTION)) { 
					String value = (String) params.get(key);

    stringBuffer.append( key );
    stringBuffer.append(TEXT_33);
    stringBuffer.append( value );
    stringBuffer.append(TEXT_34);
    
				} else if (key.equals(CreateServletTemplateModel.ATT_URL_PATTERNS)) {

    stringBuffer.append( key );
    stringBuffer.append(TEXT_35);
    
					List<String[]> mappings = (List<String[]>) params.get(key);
					boolean needComma2 = false;
					boolean needNewLine2 = mappings.size() > 1;
					for (String[] mapping : mappings) {
						if (needComma2) {

    stringBuffer.append(TEXT_36);
    
						}
				
						if (needNewLine2) {

    stringBuffer.append(TEXT_37);
    
						} 

    stringBuffer.append(TEXT_38);
    stringBuffer.append( mapping[0] );
    stringBuffer.append(TEXT_39);
    				
						needComma2 = true;
					}
				
					if (needNewLine2) {

    stringBuffer.append(TEXT_40);
    
					} else {

    stringBuffer.append(TEXT_41);
    
					}

    stringBuffer.append(TEXT_42);
    
				} else if (key.equals(CreateServletTemplateModel.ATT_INIT_PARAMS)) {

    stringBuffer.append( key );
    stringBuffer.append(TEXT_43);
    
					List<String[]> initParams = (List<String[]>) params.get(key);
					boolean needComma2 = false;
					for (String[] initParam : initParams) {
						if (needComma2) {

    stringBuffer.append(TEXT_44);
    
						}
						
						String name = initParam[CreateServletTemplateModel.NAME];
						String value = initParam[CreateServletTemplateModel.VALUE];
						String description = initParam[CreateServletTemplateModel.DESCRIPTION];

    stringBuffer.append(TEXT_45);
    stringBuffer.append( name );
    stringBuffer.append(TEXT_46);
    stringBuffer.append( value );
    stringBuffer.append(TEXT_47);
    				
						if (description != null && description.length() > 0) {

    stringBuffer.append(TEXT_48);
    stringBuffer.append( description );
    stringBuffer.append(TEXT_49);
    
						}

    stringBuffer.append(TEXT_50);
    
						needComma2 = true;
					}

    stringBuffer.append(TEXT_51);
    
				}
			
				needComma = true;
  			}

    stringBuffer.append(TEXT_52);
    
		}
	}

    
	if (model.isPublic()) { 

    stringBuffer.append(TEXT_53);
     
	} 

	if (model.isAbstract()) { 

    stringBuffer.append(TEXT_54);
    
	}

	if (model.isFinal()) {

    stringBuffer.append(TEXT_55);
    
	}

    stringBuffer.append(TEXT_56);
    stringBuffer.append( model.getClassName() );
    
	String superClass = model.getSuperclassName();
 	if (superClass != null && superClass.length() > 0) {

    stringBuffer.append(TEXT_57);
    stringBuffer.append( superClass );
    
	}

	List<String> interfaces = model.getInterfaces(); 
 	if ( interfaces.size() > 0) { 

    stringBuffer.append(TEXT_58);
    
	}
	
 	for (int i = 0; i < interfaces.size(); i++) {
   		String INTERFACE = interfaces.get(i);
   		if (i > 0) {

    stringBuffer.append(TEXT_59);
    
		}

    stringBuffer.append( INTERFACE );
    
	}

    stringBuffer.append(TEXT_60);
     
	if (model.isGenericServletSuperclass()) { 

    stringBuffer.append(TEXT_61);
     
	} 

     
	if (!model.hasEmptySuperclassConstructor()) { 

    stringBuffer.append(TEXT_62);
    stringBuffer.append( model.getClassName() );
    stringBuffer.append(TEXT_63);
     
	} 

	if (model.shouldGenSuperclassConstructors()) {
		List<Constructor> constructors = model.getConstructors();
		for (Constructor constructor : constructors) {
			if (constructor.isPublic() || constructor.isProtected()) { 

    stringBuffer.append(TEXT_64);
    stringBuffer.append( model.getSuperclassName() );
    stringBuffer.append(TEXT_65);
    stringBuffer.append( model.getSuperclassName() );
    stringBuffer.append(TEXT_66);
    stringBuffer.append( constructor.getParamsForJavadoc() );
    stringBuffer.append(TEXT_67);
    stringBuffer.append( model.getClassName() );
    stringBuffer.append(TEXT_68);
    stringBuffer.append( constructor.getParamsForDeclaration() );
    stringBuffer.append(TEXT_69);
    stringBuffer.append( constructor.getParamsForCall() );
    stringBuffer.append(TEXT_70);
    
			} 
		} 
	} 

    
	if (model.shouldImplementAbstractMethods()) {
		for (Method method : model.getUnimplementedMethods()) { 

    stringBuffer.append(TEXT_71);
    stringBuffer.append( method.getContainingJavaClass() );
    stringBuffer.append(TEXT_72);
    stringBuffer.append( method.getName() );
    stringBuffer.append(TEXT_73);
    stringBuffer.append( method.getParamsForJavadoc() );
    stringBuffer.append(TEXT_74);
    stringBuffer.append( method.getReturnType() );
    stringBuffer.append(TEXT_75);
    stringBuffer.append( method.getName() );
    stringBuffer.append(TEXT_76);
    stringBuffer.append( method.getParamsForDeclaration() );
    stringBuffer.append(TEXT_77);
     
			String defaultReturnValue = method.getDefaultReturnValue();
			if (defaultReturnValue != null) { 

    stringBuffer.append(TEXT_78);
    stringBuffer.append( defaultReturnValue );
    stringBuffer.append(TEXT_79);
    
			} 

    stringBuffer.append(TEXT_80);
     
		}
	} 

     if (model.shouldGenInit()) { 
    stringBuffer.append(TEXT_81);
     } 
     if (model.shouldGenDestroy()) { 
    stringBuffer.append(TEXT_82);
     } 
     if (model.shouldGenGetServletConfig()) { 
    stringBuffer.append(TEXT_83);
     } 
     if (model.shouldGenGetServletInfo()) { 
    stringBuffer.append(TEXT_84);
     } 
     if (model.shouldGenService() && !model.isHttpServletSuperclass()) { 
    stringBuffer.append(TEXT_85);
     } 
     if (model.shouldGenService() && model.isHttpServletSuperclass()) { 
    stringBuffer.append(TEXT_86);
     } 
     if (model.shouldGenDoGet()) { 
    stringBuffer.append(TEXT_87);
     } 
     if (model.shouldGenDoPost()) { 
    stringBuffer.append(TEXT_88);
     } 
     if (model.shouldGenDoPut()) { 
    stringBuffer.append(TEXT_89);
     } 
     if (model.shouldGenDoDelete()) { 
    stringBuffer.append(TEXT_90);
     } 
     if (model.shouldGenDoHead()) { 
    stringBuffer.append(TEXT_91);
     } 
     if (model.shouldGenDoOptions()) { 
    stringBuffer.append(TEXT_92);
     } 
     if (model.shouldGenDoTrace()) { 
    stringBuffer.append(TEXT_93);
     } 
    stringBuffer.append(TEXT_94);
    stringBuffer.append(TEXT_95);
    return stringBuffer.toString();
  }
}
