gt: 			if (param == null)
context: /*
   * Licensed to the Apache Software Foundation (ASF) under one or more
   * contributor license agreements. See the NOTICE file distributed with this
   * work for additional information regarding copyright ownership. The ASF
   * licenses this file to You under the Apache License, Version 2.0 (the
   * "License"); you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   * 
   * http://www.apache.org/licenses/LICENSE-2.0
   * 
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
   * License for the specific language governing permissions and limitations under
   * the License.
   */
  
  package org.apache.coyote;
  
  import java.io.IOException;
  import java.util.HashMap;
  
  import org.apache.tomcat.util.buf.ByteChunk;
  import org.apache.tomcat.util.buf.MessageBytes;
  import org.apache.tomcat.util.buf.UDecoder;
  
  import org.apache.tomcat.util.http.MimeHeaders;
  import org.apache.tomcat.util.http.Parameters;
  import org.apache.tomcat.util.http.ContentType;
  import org.apache.tomcat.util.http.Cookies;
  
  /**
   * This is a low-level, efficient representation of a server request. Most
   * fields are GC-free, expensive operations are delayed until the user code
   * needs the information.
   * 
   * Processing is delegated to modules, using a hook mechanism.
   * 
   * This class is not intended for user code - it is used internally by tomcat
   * for processing the request in the most efficient way. Users ( servlets ) can
   * access the information using a facade, which provides the high-level view of
   * the request.
   * 
   * For lazy evaluation, the request uses the getInfo() hook. The following ids
   * are defined:
   * <ul>
   * <li>req.encoding - returns the request encoding
   * <li>req.attribute - returns a module-specific attribute ( like SSL keys, etc
   * ).
   * </ul>
   * 
   * Tomcat defines a number of attributes:
   * <ul>
   * <li>"org.apache.tomcat.request" - allows access to the low-level request
   * object in trusted applications
   * </ul>
   * 
   * @author James Duncan Davidson [duncan@eng.sun.com]
   * @author James Todd [gonzo@eng.sun.com]
   * @author Jason Hunter [jch@eng.sun.com]
   * @author Harish Prabandham
   * @author Alex Cruikshank [alex@epitonic.com]
   * @author Hans Bergsten [hans@gefionsoftware.com]
   * @author Costin Manolache
   * @author Remy Maucherat
   */
  public final class Request {
  
  	// ----------------------------------------------------------- Constructors
  
  	public Request() {
  
  		parameters.setQuery(queryMB);
  		parameters.setURLDecoder(urlDecoder);
  		parameters.setHeaders(headers);
  
  	}
  
  	// ----------------------------------------------------- Instance Variables
  
  	private int serverPort = -1;
  	private MessageBytes serverNameMB = MessageBytes.newInstance();
  
  	private int remotePort;
  	private int localPort;
  
  	private MessageBytes schemeMB = MessageBytes.newInstance();
  
  	private MessageBytes methodMB = MessageBytes.newInstance();
  	private MessageBytes unparsedURIMB = MessageBytes.newInstance();
  	private MessageBytes uriMB = MessageBytes.newInstance();
  	private MessageBytes decodedUriMB = MessageBytes.newInstance();
  	private MessageBytes queryMB = MessageBytes.newInstance();
  	private MessageBytes protoMB = MessageBytes.newInstance();
  
  	// remote address/host
  	private MessageBytes remoteAddrMB = MessageBytes.newInstance();
  	private MessageBytes localNameMB = MessageBytes.newInstance();
  	private MessageBytes remoteHostMB = MessageBytes.newInstance();
  	private MessageBytes localAddrMB = MessageBytes.newInstance();
  
  	private MimeHeaders headers = new MimeHeaders();
  
  	private MessageBytes instanceId = MessageBytes.newInstance();
  
  	/**
  	 * Notes.
  	 */
  	private Object notes[] = new Object[Constants.MAX_NOTES];
  
  	/**
  	 * Associated input buffer.
  	 */
  	private InputBuffer inputBuffer = null;
  
  	/**
  	 * URL decoder.
  	 */
  	private UDecoder urlDecoder = new UDecoder();
  
  	/**
  	 * HTTP specific fields. (remove them ?)
  	 */
  	private long contentLength = -1;
  	private MessageBytes contentTypeMB = null;
  	private String charEncoding = null;
  	private Cookies cookies = new Cookies(headers);
  	private Parameters parameters = new Parameters();
  
  	private MessageBytes remoteUser = MessageBytes.newInstance();
  	private MessageBytes authType = MessageBytes.newInstance();
  	private HashMap attributes = new HashMap();
  
  	private Response response;
  	private ActionHook hook;
  
  	private int bytesRead = 0;
  	// Time of the request - usefull to avoid repeated calls to
  	// System.currentTime
  	private long startTime = 0L;
  	private int available = 0;
  	private boolean sendfile = false;
  
  	private RequestInfo reqProcessorMX = new RequestInfo(this);
  
  	// ------------------------------------------------------------- Properties
  
  	/**
  	 * Get the instance id (or JVM route). Curently Ajp is sending it with each
  	 * request. In future this should be fixed, and sent only once ( or
  	 * 'negociated' at config time so both tomcat and apache share the same
  	 * name.
  	 * 
  	 * @return the instance id
  	 */
  	public MessageBytes instanceId() {
  		return instanceId;
  	}
  
  	public MimeHeaders getMimeHeaders() {
  		return headers;
  	}
  
  	public UDecoder getURLDecoder() {
  		return urlDecoder;
  	}
  
  	public boolean hasSendfile() {
  		return sendfile;
  	}
  
  	public void setSendfile(boolean sendfile) {
  		this.sendfile = sendfile;
  	}
  
  	// -------------------- Request data --------------------
  
  	public MessageBytes scheme() {
  		return schemeMB;
  	}
  
  	public MessageBytes method() {
  		return methodMB;
  	}
  
  	public MessageBytes unparsedURI() {
  		return unparsedURIMB;
  	}
  
  	public MessageBytes requestURI() {
  		return uriMB;
  	}
  
  	public MessageBytes decodedURI() {
  		return decodedUriMB;
  	}
  
  	public MessageBytes query() {
  		return queryMB;
  	}
  
  	public MessageBytes queryString() {
  		return queryMB;
  	}
  
  	public MessageBytes protocol() {
  		return protoMB;
  	}
  
  	/**
  	 * Return the buffer holding the server name, if any. Use isNull() to check
  	 * if there is no value set. This is the "virtual host", derived from the
  	 * Host: header.
  	 */
  	public MessageBytes serverName() {
  		return serverNameMB;
  	}
  
  	public int getServerPort() {
  		return serverPort;
  	}
  
  	public void setServerPort(int serverPort) {
  		this.serverPort = serverPort;
  	}
  
  	public MessageBytes remoteAddr() {
  		return remoteAddrMB;
  	}
  
  	public MessageBytes remoteHost() {
  		return remoteHostMB;
  	}
  
  	public MessageBytes localName() {
  		return localNameMB;
  	}
  
  	public MessageBytes localAddr() {
  		return localAddrMB;
  	}
  
  	public int getRemotePort() {
  		return remotePort;
  	}
  
  	public void setRemotePort(int port) {
  		this.remotePort = port;
  	}
  
  	public int getLocalPort() {
  		return localPort;
  	}
  
  	public void setLocalPort(int port) {
  		this.localPort = port;
  	}
  
  	// -------------------- encoding/type --------------------
  
  	/**
  	 * Get the character encoding used for this request.
  	 */
  	public String getCharacterEncoding() {
  
  		if (charEncoding != null)
  			return charEncoding;
  
  		charEncoding = ContentType.getCharsetFromContentType(getContentType());
  		return charEncoding;
  
  	}
  
  	public void setCharacterEncoding(String enc) {
  		this.charEncoding = enc;
  	}
  
  	public void setContentLength(int len) {
  		this.contentLength = len;
  	}
  
  	public int getContentLength() {
  		long length = getContentLengthLong();
  
  		if (length < Integer.MAX_VALUE) {
  			return (int) length;
  		}
  		return -1;
  	}
  
  	public long getContentLengthLong() {
  		if (contentLength > -1)
  			return contentLength;
  
  		MessageBytes clB = headers.getUniqueValue("content-length");
  		contentLength = (clB == null || clB.isNull()) ? -1 : clB.getLong();
  
  		return contentLength;
  	}
  
  	public String getContentType() {
  		contentType();
  		if ((contentTypeMB == null) || contentTypeMB.isNull())
  			return null;
  		return contentTypeMB.toString();
  	}
  
  	public void setContentType(String type) {
  		contentTypeMB.setString(type);
  	}
  
  	public MessageBytes contentType() {
  		if (contentTypeMB == null)
  			contentTypeMB = headers.getValue("content-type");
  		return contentTypeMB;
  	}
  
  	public void setContentType(MessageBytes mb) {
  		contentTypeMB = mb;
  	}
  
  	public String getHeader(String name) {
  		return headers.getHeader(name);
  	}
  
  	// -------------------- Associated response --------------------
  
  	public Response getResponse() {
  		return response;
  	}
  
  	public void setResponse(Response response) {
  		this.response = response;
  		response.setRequest(this);
  	}
  
  	public void action(ActionCode actionCode, Object param) {
  		if (hook == null && response != null)
  			hook = response.getHook();
  
  		if (hook != null) {
  