#vulnerable code 
                             @Override
	public void processHttpMessage(int toolFlag, boolean messageIsRequest, IHttpRequestResponse messageInfo) {
		synchronized (messageInfo) {
			if (messageIsRequest) {

				boolean isRequestChanged = false;
				MessageEditor editer = new MessageEditor(messageIsRequest, messageInfo, helpers);

				URL url = editer.getURL();
				String path = url.getPath();
				String host = editer.getHost();
				byte[] body = editer.getBody();
				LinkedHashMap<String, String> headers = editer.getHeaderMap();//this will lost the first line


				//remove header
				List<ConfigEntry> configEntries = tableModel.getConfigByType(ConfigEntry.Action_Remove_From_Headers);
				for (ConfigEntry entry : configEntries) {
					String key = entry.getKey();
					if (headers.remove(key) != null) {
						isRequestChanged = true;
					}
				}

				if (config.getTmpMap().containsKey(host)) {//自动更新cookie
					String cookieValue = config.getTmpMap().get(host);
					String[] values = cookieValue.split("::::");
					String trueCookie = values[1];
					headers.put("Cookie", trueCookie);
					isRequestChanged = true;
				}

				//add/update/append header
				if (toolFlag == (toolFlag & checkEnabledFor())) {
					//if ((config.isOnlyForScope() && callbacks.isInScope(url))|| !config.isOnlyForScope()) {
					if (!config.isOnlyForScope()||callbacks.isInScope(url)){
						try {
							List<ConfigEntry> updateOrAddEntries = tableModel.getConfigEntries();
							for (ConfigEntry entry : updateOrAddEntries) {
								String key = entry.getKey();
								String value = entry.getValue();

								if (value.contains("%host")) {
									value = value.replaceAll("%host", host);
									//stdout.println("3333"+value);
								}

								if (value.toLowerCase().contains("%dnslogserver")) {
									String dnslog = tableModel.getConfigByKey("DNSlogServer");
									Pattern p = Pattern.compile("(?u)%dnslogserver");
									Matcher m = p.matcher(value);

									while (m.find()) {
										String found = m.group(0);
										value = value.replaceAll(found, dnslog);
									}
								}

								if (entry.getType().equals(ConfigEntry.Action_Add_Or_Replace_Header) && entry.isEnable()) {
									headers.put(key, value);
									isRequestChanged = true;

								} else if (entry.getType().equals(ConfigEntry.Action_Append_To_header_value) && entry.isEnable()) {
									value = headers.get(key) + value;
									headers.put(key, value);
									isRequestChanged = true;
									//stdout.println("2222"+value);
								} else if (entry.getKey().equalsIgnoreCase("Chunked-AutoEnable") && entry.isEnable()) {
									headers.put("Transfer-Encoding", "chunked");
									isRequestChanged = true;

									try {
										boolean useComment = false;
										if (this.tableModel.getConfigByKey("Chunked-UseComment") != null) {
											useComment = true;
										}
										String lenStr = this.tableModel.getConfigByKey("Chunked-Length");
										int len = 10;
										if (lenStr != null) {
											len = Integer.parseInt(lenStr);
										}
										body = Methods.encoding(body, len, useComment);
										editer.setBody(body);
									} catch (UnsupportedEncodingException e) {
										e.printStackTrace(stderr);
									}
								}
							}


							///proxy function should be here
							//reference https://support.portswigger.net/customer/portal/questions/17350102-burp-upstream-proxy-settings-and-sethttpservice
							String proxy = this.tableModel.getConfigByKey("Proxy-ServerList");
							String mode = this.tableModel.getConfigByKey("Proxy-UseRandomMode");

							if (proxy != null) {//if enable is false, will return null.
								List<String> proxyList = Arrays.asList(proxy.split(";"));//如果字符串是以;结尾，会被自动丢弃

								if (mode != null) {//random mode
									proxyServerIndex = (int) (Math.random() * proxyList.size());
									//proxyServerIndex = new Random().nextInt(proxyList.size());
								} else {
									proxyServerIndex = (proxyServerIndex + 1) % proxyList.size();
								}
								String proxyhost = proxyList.get(proxyServerIndex).split(":")[0].trim();
								int port = Integer.parseInt(proxyList.get(proxyServerIndex).split(":")[1].trim());
								editer.setService(
										helpers.buildHttpService(proxyhost, port, messageInfo.getHttpService().getProtocol()));
								String firstrline = editer.getFirstLineOfHeader().replaceFirst(path, url.toString().split("\\?",0)[0]);
								editer.setFirstLineOfHeader(firstrline);
								isRequestChanged = true;
								//success or failed,need to check?
							}
						} catch (Exception e) {
							e.printStackTrace(stderr);
						}
					}
				}
				//set final request
				editer.setHeaderMap(headers);
				messageInfo = editer.getMessageInfo();

				if (isRequestChanged) {
					//debug
					List<String> finalheaders = helpers.analyzeRequest(messageInfo).getHeaders();
					//List<String> finalheaders = editer.getHeaderList();//error here:bodyOffset getted twice are different
					stdout.println(System.lineSeparator() + "//////////edited request by knife//////////////" + System.lineSeparator());
					for (String entry : finalheaders) {
						stdout.println(entry);
					}
				}
			}
		}//sync
	} 
                            #location 20 
                            #vulnerability type NULL_DEREFERENCE
#fixed code
                             @Override
	public void processHttpMessage(int toolFlag, boolean messageIsRequest, IHttpRequestResponse messageInfo) {
		if (messageIsRequest) {
			Getter getter = new Getter(helpers);

			URL url = getter.getURL(messageInfo);
			String host = getter.getHost(messageInfo);
			String path = url.getPath();
			String firstLineOfHeader = getter.getHeaderFirstLine(messageIsRequest,messageInfo);
			LinkedHashMap headers = getter.getHeaderHashMap(messageIsRequest,messageInfo);
			IHttpService service = messageInfo.getHttpService();
			byte[] body = getter.getBody(messageIsRequest,messageInfo);

			boolean isRequestChanged = false;

			//remove header
			List<ConfigEntry> configEntries = tableModel.getConfigByType(ConfigEntry.Action_Remove_From_Headers);
			for (ConfigEntry entry : configEntries) {
				String key = entry.getKey();
				if (headers.remove(key) != null) {
					isRequestChanged = true;
				}
			}

			//add/update/append header
			if (toolFlag == (toolFlag & checkEnabledFor())) {
				//if ((config.isOnlyForScope() && callbacks.isInScope(url))|| !config.isOnlyForScope()) {
				if (!config.isOnlyForScope()||callbacks.isInScope(url)){
					try {
						List<ConfigEntry> updateOrAddEntries = tableModel.getConfigEntries();
						for (ConfigEntry entry : updateOrAddEntries) {
							String key = entry.getKey();
							String value = entry.getValue();

							if (value.contains("%host")) {
								value = value.replaceAll("%host", host);
								//stdout.println("3333"+value);
							}

							if (value.toLowerCase().contains("%dnslogserver")) {
								String dnslog = tableModel.getConfigByKey("DNSlogServer");
								Pattern p = Pattern.compile("(?u)%dnslogserver");
								Matcher m = p.matcher(value);

								while (m.find()) {
									String found = m.group(0);
									value = value.replaceAll(found, dnslog);
								}
							}

							if (entry.getType().equals(ConfigEntry.Action_Add_Or_Replace_Header) && entry.isEnable()) {
								headers.put(key, value);
								isRequestChanged = true;

							} else if (entry.getType().equals(ConfigEntry.Action_Append_To_header_value) && entry.isEnable()) {
								value = headers.get(key) + value;
								headers.put(key, value);
								isRequestChanged = true;
								//stdout.println("2222"+value);
							} else if (entry.getKey().equalsIgnoreCase("Chunked-AutoEnable") && entry.isEnable()) {
								headers.put("Transfer-Encoding", "chunked");
								isRequestChanged = true;

								try {
									boolean useComment = false;
									if (this.tableModel.getConfigByKey("Chunked-UseComment") != null) {
										useComment = true;
									}
									String lenStr = this.tableModel.getConfigByKey("Chunked-Length");
									int len = 10;
									if (lenStr != null) {
										len = Integer.parseInt(lenStr);
									}
									body = Methods.encoding(body, len, useComment);
								} catch (UnsupportedEncodingException e) {
									e.printStackTrace(stderr);
								}
							}
						}


						///proxy function should be here
						//reference https://support.portswigger.net/customer/portal/questions/17350102-burp-upstream-proxy-settings-and-sethttpservice
						String proxy = this.tableModel.getConfigByKey("Proxy-ServerList");
						String mode = this.tableModel.getConfigByKey("Proxy-UseRandomMode");

						if (proxy != null) {//if enable is false, will return null.
							List<String> proxyList = Arrays.asList(proxy.split(";"));//如果字符串是以;结尾，会被自动丢弃

							if (mode != null) {//random mode
								proxyServerIndex = (int) (Math.random() * proxyList.size());
								//proxyServerIndex = new Random().nextInt(proxyList.size());
							} else {
								proxyServerIndex = (proxyServerIndex + 1) % proxyList.size();
							}
							String proxyhost = proxyList.get(proxyServerIndex).split(":")[0].trim();
							int port = Integer.parseInt(proxyList.get(proxyServerIndex).split(":")[1].trim());

							messageInfo.setHttpService(helpers.buildHttpService(proxyhost, port, messageInfo.getHttpService().getProtocol()));

							firstLineOfHeader = firstLineOfHeader.replaceFirst(path, url.toString().split("\\?",0)[0]);
							isRequestChanged = true;
							//success or failed,need to check?
						}
					} catch (Exception e) {
						e.printStackTrace(stderr);
					}
				}
			}

			//set final request
			List<String> headerList = getter.HeaderMapToList(firstLineOfHeader,headers);
			messageInfo.setRequest(helpers.buildHttpMessage(headerList,body));

			if (isRequestChanged) {
				//debug
				List<String> finalheaders = helpers.analyzeRequest(messageInfo).getHeaders();
				//List<String> finalheaders = editer.getHeaderList();//error here:bodyOffset getted twice are different
				stdout.println(System.lineSeparator() + "//////////edited request by knife//////////////" + System.lineSeparator());
				for (String entry : finalheaders) {
					stdout.println(entry);
				}
			}
		}else {//response

		}
	}