/**
 * Servlet implementation class <%= model.getClassName() %>
<% 
	if (model.isAnnotated()) { 
%>
 *
 * @web.servlet
 *   name="<%= model.getServletName() %>"
 *   display-name="<%= model.getServletName() %>"
<% 
		if (model.getDescription() != null && model.getDescription().length() > 0) { 
%>
 *   description="<%= model.getDescription() %>"
<% 
		} 
		
		List<String[]> mappings = model.getServletMappings();
 		if (mappings != null && mappings.size() > 0) {
			for (int i = 0; i < mappings.size(); i++) {
				String map = model.getServletMapping(i); %>
 *
 * @web.servlet-mapping
 *   url-pattern="<%= map %>"
<% 
			} 
		}
 		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); 
%>
 *
 * @web.servlet-init-param
 *    name="<%= name %>"
 *    value="<%= value %>"
<% 
				if (description != null && description.length() > 0) { 
%>
 *    description="<%= description %>"
<%
				}
			} 
		} 
	} 
%>
 */
<% 
	if ("3.0".equals(model.getJavaEEVersion())) { 
%>
@WebServlet
<%
		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];
%>("<%= value %>")
<%
			} else {
%>({ 
<%
				boolean needComma = false;
				for (String[] mapping : mappings) {
					if (needComma) {
%>, 
<%
					}
%>"<%= mapping[0] %>"
<%
					needComma = true;
				}
%> })
<%
			}
		} else if (!params.isEmpty()) { 
%>(
<%
			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) {
%>, 
<%
				}
				
				if (needNewLine) {
%>
		
<%
				} 
			
				if (key.equals(CreateServletTemplateModel.ATT_NAME) || key.equals(CreateServletTemplateModel.ATT_DESCRIPTION)) { 
					String value = (String) params.get(key);
%><%= key %> = "<%= value %>"
<%
				} else if (key.equals(CreateServletTemplateModel.ATT_URL_PATTERNS)) {
%><%= key %> = { 
<%
					List<String[]> mappings = (List<String[]>) params.get(key);
					boolean needComma2 = false;
					boolean needNewLine2 = mappings.size() > 1;
					for (String[] mapping : mappings) {
						if (needComma2) {
%>, 
<%
						}
				
						if (needNewLine2) {
%>
				
<%
						} 
%>"<%= mapping[0] %>"
<%				
						needComma2 = true;
					}
				
					if (needNewLine2) {
%>
		
<%
					} else {
%> 
<%
					}
%>}
<%
				} else if (key.equals(CreateServletTemplateModel.ATT_INIT_PARAMS)) {
%><%= key %> = { 
<%
					List<String[]> initParams = (List<String[]>) params.get(key);
					boolean needComma2 = false;
					for (String[] initParam : initParams) {
						if (needComma2) {
%>, 
<%
						}
						
						String name = initParam[CreateServletTemplateModel.NAME];
						String value = initParam[CreateServletTemplateModel.VALUE];
						String description = initParam[CreateServletTemplateModel.DESCRIPTION];
%>
				@WebInitParam(name = "<%= name %>", value = "<%= value %>"
<%				
						if (description != null && description.length() > 0) {
%>, description = "<%= description %>"
<%
						}
%>)
<%
						needComma2 = true;
					}
%>
		}
<%
				}
			
				needComma = true;
  			}
%>)
<%
		}
	}
%>