#vulnerable code 
                             private byte[] processRequest(StunRequest request, InetSocketAddress localPeer, InetSocketAddress remotePeer) throws IOException {
		/*
		 * The agent MUST use a short-term credential to authenticate the
		 * request and perform a message integrity check.
		 */

		// Produce Binding Response
		TransportAddress transportAddress = new TransportAddress(remotePeer.getAddress(), remotePeer.getPort(), TransportProtocol.UDP);
		StunResponse response = StunMessageFactory.createBindingResponse(request, transportAddress);
		byte[] transactionID = request.getTransactionId();
		try {
			response.setTransactionID(transactionID);
		} catch (StunException e) {
			throw new IOException("Illegal STUN Transaction ID: " + new String(transactionID), e);
		}

		UsernameAttribute remoteUnameAttribute;
		String remoteUsername;
		// Send binding error response if username is null
		try {
			remoteUnameAttribute = (UsernameAttribute) request.getAttribute(StunAttribute.USERNAME);
			remoteUsername = new String(remoteUnameAttribute.getUsername());
		}
		catch(NullPointerException nullPointer) {
			response.setMessageType(StunMessage.BINDING_ERROR_RESPONSE);
			response.addAttribute(StunAttributeFactory.createErrorCodeAttribute(ErrorCodeAttribute.BAD_REQUEST,
					ErrorCodeAttribute.getDefaultReasonPhrase(ErrorCodeAttribute.BAD_REQUEST)));
			return response.encode();
		}
		
		/*
		 * The agent MUST consider the username to be valid if it consists of
		 * two values separated by a colon, where the first value is equal to
		 * the username fragment generated by the agent in an offer or answer
		 * for a session in-progress.
		 */
		if(!this.iceAuthenticator.validateUsername(remoteUsername)) {
			// TODO return error response
			throw new IOException("Invalid username "+ remoteUsername);
		}
		
		/*
		 * The username for the credential is formed by concatenating the
		 * username fragment provided by the peer with the username fragment of
		 * the agent sending the request, separated by a colon (":").
		 */
		int colon = remoteUsername.indexOf(":");
		String localUFrag = remoteUsername.substring(0, colon);
		String remoteUfrag = remoteUsername.substring(colon);
		
		/*
		 * An agent MUST include the PRIORITY attribute in its Binding request.
		 * This priority value will be computed identically to how the priority
		 * for the local candidate of the pair was computed, except that the
		 * type preference is set to the value for peer reflexive candidate
		 * types
		 */
		long priority = extractPriority(request);

		/*
		 * Add USERNAME and MESSAGE-INTEGRITY attribute in the response. The
		 * responses utilize the same usernames and passwords as the requests
		 */
		String localUsername = remoteUfrag.concat(":").concat(localUFrag);
		StunAttribute unameAttribute = StunAttributeFactory.createUsernameAttribute(localUsername);
		response.addAttribute(unameAttribute);

		byte[] localKey = this.iceAuthenticator.getLocalKey(localUFrag);
		MessageIntegrityAttribute messageIntegrityAttribute = StunAttributeFactory.createMessageIntegrityAttribute(remoteUsername, localKey);
		response.addAttribute(messageIntegrityAttribute);
		
		// If the client issues a USE-CANDIDATE, tell ICE Agent to select the candidate
		if (request.containsAttribute(StunAttribute.USE_CANDIDATE)) {
			fireStunBindingEvent(localPeer, remotePeer);
		}

		// Pass response to the server
		return response.encode();
	} 
                            #location 22 
                            #vulnerability type NULL_DEREFERENCE
#fixed code
                             private byte[] processRequest(StunRequest request, InetSocketAddress localPeer, InetSocketAddress remotePeer) throws IOException {
		/*
		 * The agent MUST use a short-term credential to authenticate the
		 * request and perform a message integrity check.
		 */

		// Produce Binding Response
		TransportAddress transportAddress = new TransportAddress(remotePeer.getAddress(), remotePeer.getPort(), TransportProtocol.UDP);
		StunResponse response = StunMessageFactory.createBindingResponse(request, transportAddress);
		byte[] transactionID = request.getTransactionId();
		try {
			response.setTransactionID(transactionID);
		} catch (StunException e) {
			throw new IOException("Illegal STUN Transaction ID: " + new String(transactionID), e);
		}

		UsernameAttribute remoteUnameAttribute = (UsernameAttribute) request.getAttribute(StunAttribute.USERNAME);

		// Send binding error response if username is null
		if (remoteUnameAttribute.getUsername()== null)	{
			response.setMessageType(StunMessage.BINDING_ERROR_RESPONSE);
			response.addAttribute(StunAttributeFactory.createErrorCodeAttribute(ErrorCodeAttribute.BAD_REQUEST,
					ErrorCodeAttribute.getDefaultReasonPhrase(ErrorCodeAttribute.BAD_REQUEST)));
			return response.encode();
		}
		String remoteUsername = new String(remoteUnameAttribute.getUsername());
		
		/*
		 * The agent MUST consider the username to be valid if it consists of
		 * two values separated by a colon, where the first value is equal to
		 * the username fragment generated by the agent in an offer or answer
		 * for a session in-progress.
		 */
		if(!this.iceAuthenticator.validateUsername(remoteUsername)) {
			// TODO return error response
			throw new IOException("Invalid username "+ remoteUsername);
		}
		
		/*
		 * The username for the credential is formed by concatenating the
		 * username fragment provided by the peer with the username fragment of
		 * the agent sending the request, separated by a colon (":").
		 */
		int colon = remoteUsername.indexOf(":");
		String localUFrag = remoteUsername.substring(0, colon);
		String remoteUfrag = remoteUsername.substring(colon);
		
		/*
		 * An agent MUST include the PRIORITY attribute in its Binding request.
		 * This priority value will be computed identically to how the priority
		 * for the local candidate of the pair was computed, except that the
		 * type preference is set to the value for peer reflexive candidate
		 * types
		 */
		long priority = extractPriority(request);

		/*
		 * Add USERNAME and MESSAGE-INTEGRITY attribute in the response. The
		 * responses utilize the same usernames and passwords as the requests
		 */
		String localUsername = remoteUfrag.concat(":").concat(localUFrag);
		StunAttribute unameAttribute = StunAttributeFactory.createUsernameAttribute(localUsername);
		response.addAttribute(unameAttribute);

		byte[] localKey = this.iceAuthenticator.getLocalKey(localUFrag);
		MessageIntegrityAttribute messageIntegrityAttribute = StunAttributeFactory.createMessageIntegrityAttribute(remoteUsername, localKey);
		response.addAttribute(messageIntegrityAttribute);
		
		// If the client issues a USE-CANDIDATE, tell ICE Agent to select the candidate
		if (request.containsAttribute(StunAttribute.USE_CANDIDATE)) {
			fireStunBindingEvent(localPeer, remotePeer);
		}

		// Pass response to the server
		return response.encode();
	}