private void decodeHeader(final BufferedReader in, final Map<String, String> pre, final Map<String, String> parms, final Map<String, String> header) throws InterruptedException {
		
			try {
				// Read the request line
				final String inLine = in.readLine();
				if (inLine == null) {
					return;
				}
				
				final StringTokenizer st = new StringTokenizer(inLine);
				if (!st.hasMoreTokens()) {
					Response.error(channel, Response.Status.BAD_REQUEST, "BAD REQUEST: Syntax error. Usage: GET /example/file.html");
					throw new InterruptedException();
				}
				
				pre.put("method", st.nextToken());
				
				if (!st.hasMoreTokens()) {
					Response.error(channel, Response.Status.BAD_REQUEST, "BAD REQUEST: Missing URI. Usage: GET /example/file.html");
					throw new InterruptedException();
				}
				
				String uri = st.nextToken();
				
				// Decode parameters from the URI
				final int qmi = uri.indexOf('?');
				if (qmi >= 0) {
					decodeParms(uri.substring(qmi + 1), parms);
					uri = decodePercent(uri.substring(0, qmi));
				} else {
					uri = decodePercent(uri);
				}
				
				// If there's another token, it's protocol version,
				// followed by HTTP headers. Ignore version but parse headers.
				// NOTE: this now forces header names lowercase since they are
				// case insensitive and vary by client.
				if (st.hasMoreTokens()) {
					String line = in.readLine();
					while(line != null && line.trim().length() > 0) {
						final int p = line.indexOf(':');
						if (p >= 0) {
							header.put(line.substring(0, p).trim().toLowerCase(), line.substring(p + 1).trim());
						}
						line = in.readLine();
					}
				}
				
				pre.put("uri", uri);
			} catch (final IOException ioe) {
				Response.error(channel, Response.Status.INTERNAL_ERROR, "SERVER INTERNAL ERROR: IOException: " + ioe.getMessage());
				throw new InterruptedException();
			}
		}