#vulnerable code 
                             public void handleAPIv1 (String format, String type, String key, int pageIdx, int pageSize, HttpServletRequest req, HttpServletResponse resp) 
		throws IOException, ServletException {

		String viewPath = "";
		String searchString = "";
		String originalType = type;
		String sFormat = "json";
		String sortField = "when";
		boolean sortOrder = true;

		if(type != null) {
			if(type.contains("bill")) {
				sortField = "sortindex";
				sortOrder = false;
			}
			else if(type.contains("meeting")) {
				sortField = "sortindex";
			}
		}
		
		
		SenateResponse sr = null;
		
		
		if (type.equalsIgnoreCase("sponsor")) {
			String filter = req.getParameter("filter");
			key = "sponsor:\"" + key + (filter != null ? " AND " + filter : "");
			type = "bills";
		}
		else if (type.equalsIgnoreCase("committee")) {
			key = "committee:\"" + key + "\" AND oid:s*-" + SessionYear.getSessionYear();
			type = "bills";
		}
		
		key = key.trim();
		
		if (pageSize > MAX_PAGE_SIZE)
			throw new ServletException ("The maximum page size is " + MAX_PAGE_SIZE);
		//now calculate start, end idx based on pageIdx and pageSize
		int start = (pageIdx - 1) * pageSize;
		int end = start + pageSize;
		
		
		logger.info("request: key=" + key + ";type=" + type + ";format=" + format + ";paging=" + start + "/" + end);
		try	{
			/*
			 * construct query with "otype:<type>" if type present
			 */
			if (type != null) {
				
				/*
				 * for searches
				 * 
				 * applicable to: bills, calendars, meetings, transcripts, actions, votes
				 */
				if (type.endsWith("s"))	{
					type = type.substring(0,type.length()-1);
					
					searchString = "otype:" + type;
					
					if (key != null && key.length() > 0)
						searchString += " AND " + key;
				}
				/*
				 * for individual documents
				 * 
				 * applicable to: bill, calendar, meeting, transcript
				 */
				else {
					searchString ="otype:" + type;
	
					if (key != null && key.length() > 0) {
						if (type.equals("bill") && key.indexOf("-") == -1)
							key += "-" + DEFAULT_SESSION_YEAR;
	
						key = key.replace(" ","+");
						searchString += " AND oid:" + key;
					}
				}
			}
			else
			{
				searchString = key;
			}
			
			req.setAttribute("sortField", sortField);
			req.setAttribute("sortOrder", Boolean.toString(sortOrder));
			req.setAttribute("type", type);
			req.setAttribute("term", searchString);
			req.setAttribute("format", format);
			req.setAttribute("key", key);
			req.setAttribute(PAGE_IDX,pageIdx+"");
			req.setAttribute(PAGE_SIZE,pageSize+"");
						
			/* 
			 * applicable to: bills
			 * 
			 * only return bills with "year:<currentSessionYear>"
			 */
			if(originalType.equals("bills")) {
				sr = searchEngine.search(ApiHelper.dateReplace(searchString) 
						+ " AND year:" + SessionYear.getSessionYear() 
						+ " AND active:true",
						sFormat,start,pageSize,sortField,sortOrder);
			}
			/*
			 * applicable to: calendars, meetings, transcripts
			 * 
			 * only want current session documents as defined by the time
			 * frame between DATE_START and DATE_END
			 */
			else if(originalType.endsWith("s")) {
				sr = searchEngine.search(ApiHelper.dateReplace(searchString) 
						+ " AND when:[" 
						+ DATE_START 
						+ " TO " 
						+ DATE_END + "]"
						+ " AND active:true",
						sFormat,start,pageSize,sortField,sortOrder);
			}
			/*
			 * applicable to: individual documents
			 * 
			 * attempting to access a document by id doesn't
			 * doesn't require any special formatting
			 */
			else {
				sr = searchEngine.search(ApiHelper.dateReplace(searchString),sFormat,start,pageSize,sortField,sortOrder);
			}
			
			logger.info("got search results: " + sr.getResults().size());
						
			if (sr.getResults().size()==0) {
				resp.sendError(404);
				return;
			}
			else if (sr.getResults().size()==1 && format.matches("(html(\\-print)?|mobile|lrs\\-print)"))	{
				
				Result result = sr.getResults().get(0);
				
				/* if not an exact match on the oid it's likely 
				 * the correct id, just the wrong case */
				if (!result.getOid().equals(key)) {
					if(format.equals("html"))
						resp.sendRedirect("/legislation/" 
								+ result.getOtype() 
								+ "/" 
								+ result.getOid());
					else
						resp.sendRedirect("/legislation/api/1.0/" 
								+ format 
								+ "/" 
								+ result.getOtype() 
								+ "/" 
								+ result.getOid());
					return;
				}
				
				String jsonData = result.getData();
				req.setAttribute("active", result.getActive());
								
				jsonData = jsonData.substring(jsonData.indexOf(":")+1);
				jsonData = jsonData.substring(0,jsonData.lastIndexOf("}"));
				
				/* Jackson ObjectMaper will deserialize our json in to an object,
				 * we need to know what sort of an object that is
				 */
				String className = "gov.nysenate.openleg.model.bill." + type.substring(0,1).toUpperCase() + type.substring(1);
				
				/* 
				 * for bills we populate other relevant data, such as
				 * 		votes, calendars, meetings, sameas bills, older versions, etc.
				 */
				if (type.equals("bill")) {
					String billQueryId = key;
					String sessionYear = DEFAULT_SESSION_YEAR;
					
					/* default behavior to maintain previous permalinks
					 * is if key=S1234 to transform to S1234-2009
					 * in line with our new bill oid format <billno>-<sessYear> */
					String[] billParts = billQueryId.split("-");
					billQueryId = billParts[0];
					if (billParts.length > 1)
						sessionYear = billParts[1];
				
					/* turns S1234A in to S1234 */
					String billWildcard = billQueryId;
					if (!Character.isDigit(billWildcard.charAt(billWildcard.length()-1)))
						billWildcard = billWildcard.substring(0,billWildcard.length()-1);
						
					//get BillEvents for this 
					//otype:action AND billno:((S1234-2011 OR [S1234A-2011 TO S1234Z-2011) AND S1234*-2011)
					String rType = "action";
					String rQuery = null;
					rQuery = billWildcard + "-" + sessionYear;
					
					logger.info(rQuery);
					
					rQuery = "billno:((" 
						+ rQuery 
	                        + " OR [" + billWildcard + "A-" + sessionYear 
	                           + " TO " + billWildcard + "Z-" + sessionYear
	                        + "]) AND " + billWildcard + "*-" + sessionYear + ")";

					ArrayList<SearchResult> relatedActions = ApiHelper.getRelatedSenateObjects(rType,rQuery);
					Hashtable<String,SearchResult> uniqResults = new Hashtable<String,SearchResult>();
					for (SearchResult rResult: relatedActions) {
						BillEvent rAction = (BillEvent)rResult.getObject();
						uniqResults.put(rAction.getEventDate().toGMTString()+'-'+rResult.getTitle().toUpperCase(), rResult);
						
					}
					
					ArrayList<SearchResult> list = Collections.list(uniqResults.elements());
					Collections.sort(list);
					req.setAttribute("related-" + rType, list);

					//get older bills (e.g. for S1234A get S1234)
					//otype:meeting AND oid:((S1234-2011 OR [S1234A-2011 TO S1234Z-2011) AND S1234*-2011)
					rType = "bill";
					rQuery = billWildcard + "-" + sessionYear;
					
					logger.info(rQuery);
					
					rQuery = "oid:((" 
						+ rQuery 
	                        + " OR [" + billWildcard + "A-" + sessionYear 
	                           + " TO " + billWildcard + "Z-" + sessionYear
	                        + "]) AND " + billWildcard + "*-" + sessionYear + ")";
					
					req.setAttribute("related-" + rType, ApiHelper.getRelatedSenateObjects (rType,rQuery));

					//get Meetings
					//otype:meeting AND bills:"S67005-2011"
					rType = "meeting";
					rQuery = "bills:\"" + key + "\"";					
					req.setAttribute("related-" + rType, ApiHelper.getRelatedSenateObjects(rType,rQuery));
					
					//get calendars
					//otype:calendar AND  bills:"S337A-2011"
					rType = "calendar";
					 rQuery = "bills:\"" + key + "\"";
					req.setAttribute("related-" + rType, ApiHelper.getRelatedSenateObjects(rType,rQuery));
					
					//get votes
					//otype:vote AND billno:"A11597-2011"
					rType = "vote";
					 rQuery = "billno:\"" + key + "\"";
					 					 
					req.setAttribute("related-" + rType, ApiHelper.getRelatedSenateObjects(rType,rQuery));
				}
				else if (type.equals("calendar")) {
					className = "gov.nysenate.openleg.model.calendar.Calendar";
				}
				else if (type.equals("meeting")) {
					className = "gov.nysenate.openleg.model.committee.Meeting";
				}
				else if(type.equals("transcript")) {
					className = "gov.nysenate.openleg.model.transcript.Transcript";
				}
				
				Object resultObj = null;
				
				try	{
					resultObj = ApiHelper.getMapper().readValue(jsonData,  Class.forName(className));
				}
				catch (Exception e) {
					logger.warn("error binding className", e);
				}
				
				req.setAttribute(type, resultObj);
				viewPath = "/views/" + type + "-" + format + ".jsp";
			}
			else {
				/* all non html/print bill views go here */
				if (type.equals("bill") && (!format.equals("html"))) {
					viewPath = "/views/bills-" + format + ".jsp";
					
					ArrayList<SearchResult> searchResults = ApiHelper.buildSearchResultList(sr);
					ArrayList<Bill> bills = new ArrayList<Bill>();
					
					for (SearchResult result : searchResults) {
						bills.add((Bill)result.getObject());
					}
										
					req.setAttribute("bills", bills);
				}
				/* all calendar, meeting, transcript multi views go here */
				else
				{
					viewPath = "/views/" + "search" + "-" + format + ".jsp";
					
					SearchResultSet srs = new SearchResultSet();
					srs.setTotalHitCount((Integer)sr.getMetadata().get("totalresults"));
					srs.setResults(ApiHelper.buildSearchResultList(sr));
					
					req.setAttribute("results", srs);
				}
			}
		}
		catch (Exception e) {
			logger.warn("search controller didn't work for: " + req.getRequestURI(),e);
			e.printStackTrace();
		}

		try {
			logger.info("routing to search controller:" + viewPath);
			getServletContext().getRequestDispatcher(viewPath).forward(req, resp);
		}
		catch (Exception e)	{
			logger.warn("search controller didn't work for: " + req.getRequestURI(),e);
		}
	} 
                            #location 293 
                            #vulnerability type NULL_DEREFERENCE
#fixed code
                             public void handleAPIv1 (String format, String type, String key, int pageIdx, int pageSize, HttpServletRequest req, HttpServletResponse resp) 
		throws IOException, ServletException {
		
		String urlPath = "/legislation/" + type + "/" + ((key != null && !key.matches("\\s*")) ? key + "/" :"");
		
		if (type.equalsIgnoreCase("sponsor")) {
			String filter = req.getParameter("filter");
			key = "sponsor:\"" + key + "\"";
			if(filter != null) {
				req.setAttribute("filter", filter);
				key += (filter != null ? " AND " + filter : "");
			}
			type = "bills";
		}
		else if (type.equalsIgnoreCase("committee")) {
			key = "committee:\"" + key + "\"";
			type = "bills";
		}
		
		String originalType = type;
		String viewPath = "";
		String searchString = "";
		String sFormat = "json";
		String sortField = "when";
		boolean sortOrder = true;
		

		if(type != null) {
			if(type.contains("bill")) {
				sortField = "sortindex";
				sortOrder = false;
			}
			else if(type.contains("meeting")) {
				sortField = "sortindex";
			}
		}
		
		
		SenateResponse sr = null;
		
		key = key.trim();
		
		if (pageSize > MAX_PAGE_SIZE)
			throw new ServletException ("The maximum page size is " + MAX_PAGE_SIZE);
		//now calculate start, end idx based on pageIdx and pageSize
		int start = (pageIdx - 1) * pageSize;
		int end = start + pageSize;
						
		logger.info("request: key=" + key + ";type=" + type + ";format=" + format + ";paging=" + start + "/" + end);
		try	{
			/*
			 * construct query with "otype:<type>" if type present
			 */
			if (type != null) {
				
				/*
				 * for searches
				 * 
				 * applicable to: bills, calendars, meetings, transcripts, actions, votes
				 */
				if (type.endsWith("s"))	{
					type = type.substring(0,type.length()-1);
					
					searchString = "otype:" + type;
					
					if (key != null && key.length() > 0)
						searchString += " AND " + key;
				}
				/*
				 * for individual documents
				 * 
				 * applicable to: bill, calendar, meeting, transcript
				 */
				else {
					searchString ="otype:" + type;
	
					if (key != null && key.length() > 0) {
						if (type.equals("bill") && key.indexOf("-") == -1)
							key += "-" + DEFAULT_SESSION_YEAR;
	
						key = key.replace(" ","+");
						searchString += " AND oid:" + key;
					}
				}
			}
			else
			{
				searchString = key;
			}
							
			/* 
			 * applicable to: bills
			 * 
			 * only return bills with "year:<currentSessionYear>"
			 */
			if(originalType.equals("bills")) {
				req.setAttribute("urlPath", urlPath);
				searchString = ApiHelper.dateReplace(searchString) 
					+ " AND year:" + SessionYear.getSessionYear() 
					+ " AND active:true";
			}
			/*
			 * applicable to: calendars, meetings, transcripts
			 * 
			 * only want current session documents as defined by the time
			 * frame between DATE_START and DATE_END
			 */
			else if(originalType.endsWith("s")) {
				req.setAttribute("urlPath", urlPath);
				searchString = ApiHelper.dateReplace(searchString) 
					+ " AND when:[" 
					+ DATE_START 
					+ " TO " 
					+ DATE_END + "]"
					+ " AND active:true";
			}
			/*
			 * applicable to: individual documents
			 * 
			 * attempting to access a document by id doesn't
			 * doesn't require any special formatting
			 */
			else {
				searchString = ApiHelper.dateReplace(searchString);
			}
			
			req.setAttribute("sortField", sortField);
			req.setAttribute("sortOrder", Boolean.toString(sortOrder));
			req.setAttribute("type", type);
			req.setAttribute("term", searchString);
			req.setAttribute("format", format);
			req.setAttribute("key", key);
			req.setAttribute(PAGE_IDX,pageIdx+"");
			req.setAttribute(PAGE_SIZE,pageSize+"");
			
			sr = searchEngine.search(searchString,sFormat,start,pageSize,sortField,sortOrder);
						
			logger.info("got search results: " + sr.getResults().size());
						
			if (sr.getResults().size()==0) {
				resp.sendError(404);
				return;
			}
			else if (sr.getResults().size()==1 && format.matches("(html(\\-print)?|mobile|lrs\\-print)"))	{
				
				Result result = sr.getResults().get(0);
				
				/* if not an exact match on the oid it's likely 
				 * the correct id, just the wrong case */
				if (!result.getOid().equals(key)) {
					if(format.equals("html"))
						resp.sendRedirect("/legislation/" 
								+ result.getOtype() 
								+ "/" 
								+ result.getOid());
					else
						resp.sendRedirect("/legislation/api/1.0/" 
								+ format 
								+ "/" 
								+ result.getOtype() 
								+ "/" 
								+ result.getOid());
					return;
				}
				
				String jsonData = result.getData();
				req.setAttribute("active", result.getActive());
								
				jsonData = jsonData.substring(jsonData.indexOf(":")+1);
				jsonData = jsonData.substring(0,jsonData.lastIndexOf("}"));
				
				/* Jackson ObjectMaper will deserialize our json in to an object,
				 * we need to know what sort of an object that is
				 */
				String className = "gov.nysenate.openleg.model.bill." + type.substring(0,1).toUpperCase() + type.substring(1);
				
				/* 
				 * for bills we populate other relevant data, such as
				 * 		votes, calendars, meetings, sameas bills, older versions, etc.
				 */
				if (type.equals("bill")) {
					String billQueryId = key;
					String sessionYear = DEFAULT_SESSION_YEAR;
					
					/* default behavior to maintain previous permalinks
					 * is if key=S1234 to transform to S1234-2009
					 * in line with our new bill oid format <billno>-<sessYear> */
					String[] billParts = billQueryId.split("-");
					billQueryId = billParts[0];
					if (billParts.length > 1)
						sessionYear = billParts[1];
				
					/* turns S1234A in to S1234 */
					String billWildcard = billQueryId;
					if (!Character.isDigit(billWildcard.charAt(billWildcard.length()-1)))
						billWildcard = billWildcard.substring(0,billWildcard.length()-1);
						
					//get BillEvents for this 
					//otype:action AND billno:((S1234-2011 OR [S1234A-2011 TO S1234Z-2011) AND S1234*-2011)
					String rType = "action";
					String rQuery = null;
					rQuery = billWildcard + "-" + sessionYear;
					
					logger.info(rQuery);
					
					rQuery = "billno:((" 
						+ rQuery 
	                        + " OR [" + billWildcard + "A-" + sessionYear 
	                           + " TO " + billWildcard + "Z-" + sessionYear
	                        + "]) AND " + billWildcard + "*-" + sessionYear + ")";

					ArrayList<SearchResult> relatedActions = ApiHelper.getRelatedSenateObjects(rType,rQuery);
					Hashtable<String,SearchResult> uniqResults = new Hashtable<String,SearchResult>();
					for (SearchResult rResult: relatedActions) {
						BillEvent rAction = (BillEvent)rResult.getObject();
						uniqResults.put(rAction.getEventDate().toGMTString()+'-'+rResult.getTitle().toUpperCase(), rResult);
						
					}
					
					ArrayList<SearchResult> list = Collections.list(uniqResults.elements());
					Collections.sort(list);
					req.setAttribute("related-" + rType, list);

					//get older bills (e.g. for S1234A get S1234)
					//otype:meeting AND oid:((S1234-2011 OR [S1234A-2011 TO S1234Z-2011) AND S1234*-2011)
					rType = "bill";
					rQuery = billWildcard + "-" + sessionYear;
					
					logger.info(rQuery);
					
					rQuery = "oid:((" 
						+ rQuery 
	                        + " OR [" + billWildcard + "A-" + sessionYear 
	                           + " TO " + billWildcard + "Z-" + sessionYear
	                        + "]) AND " + billWildcard + "*-" + sessionYear + ")";
					
					req.setAttribute("related-" + rType, ApiHelper.getRelatedSenateObjects (rType,rQuery));

					//get Meetings
					//otype:meeting AND bills:"S67005-2011"
					rType = "meeting";
					rQuery = "bills:\"" + key + "\"";					
					req.setAttribute("related-" + rType, ApiHelper.getRelatedSenateObjects(rType,rQuery));
					
					//get calendars
					//otype:calendar AND  bills:"S337A-2011"
					rType = "calendar";
					 rQuery = "bills:\"" + key + "\"";
					req.setAttribute("related-" + rType, ApiHelper.getRelatedSenateObjects(rType,rQuery));
					
					//get votes
					//otype:vote AND billno:"A11597-2011"
					rType = "vote";
					 rQuery = "billno:\"" + key + "\"";
					 					 
					req.setAttribute("related-" + rType, ApiHelper.getRelatedSenateObjects(rType,rQuery));
				}
				else if (type.equals("calendar")) {
					className = "gov.nysenate.openleg.model.calendar.Calendar";
				}
				else if (type.equals("meeting")) {
					className = "gov.nysenate.openleg.model.committee.Meeting";
				}
				else if(type.equals("transcript")) {
					className = "gov.nysenate.openleg.model.transcript.Transcript";
				}
				
				Object resultObj = null;
				
				try	{
					resultObj = ApiHelper.getMapper().readValue(jsonData,  Class.forName(className));
				}
				catch (Exception e) {
					logger.warn("error binding className", e);
				}
				
				req.setAttribute(type, resultObj);
				viewPath = "/views/" + type + "-" + format + ".jsp";
			}
			else {
				/* all non html/print bill views go here */
				if (type.equals("bill") && (!format.equals("html"))) {
					viewPath = "/views/bills-" + format + ".jsp";
					
					ArrayList<SearchResult> searchResults = ApiHelper.buildSearchResultList(sr);
					ArrayList<Bill> bills = new ArrayList<Bill>();
					
					for (SearchResult result : searchResults) {
						bills.add((Bill)result.getObject());
					}
										
					req.setAttribute("bills", bills);
				}
				/* all calendar, meeting, transcript multi views go here */
				else
				{
					viewPath = "/views/" + "search" + "-" + format + ".jsp";
					
					SearchResultSet srs = new SearchResultSet();
					srs.setTotalHitCount((Integer)sr.getMetadata().get("totalresults"));
					srs.setResults(ApiHelper.buildSearchResultList(sr));
					
					req.setAttribute("results", srs);
				}
			}
		}
		catch (Exception e) {
			logger.warn("search controller didn't work for: " + req.getRequestURI(),e);
			e.printStackTrace();
		}

		try {
			logger.info("routing to search controller:" + viewPath);
			getServletContext().getRequestDispatcher(viewPath).forward(req, resp);
		}
		catch (Exception e)	{
			logger.warn("search controller didn't work for: " + req.getRequestURI(),e);
		}
	}