diff --git a/mina-core/src/main/java/org/apache/mina/filter/reqres/Request.java b/mina-core/src/main/java/org/apache/mina/filter/reqres/Request.java
deleted file mode 100644
index cf6d554..0000000
--- a/mina-core/src/main/java/org/apache/mina/filter/reqres/Request.java
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- *  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.mina.filter.reqres;
-
-import java.util.NoSuchElementException;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.ScheduledFuture;
-import java.util.concurrent.TimeUnit;
-
-/**
- * TODO Add documentation
- * 
- * @author <a href="http://mina.apache.org">Apache MINA Project</a>
- */
-public class Request {
-    private final Object id;
-
-    private final Object message;
-
-    private final long timeoutMillis;
-
-    private volatile Runnable timeoutTask;
-
-    private volatile ScheduledFuture<?> timeoutFuture;
-
-    private final BlockingQueue<Object> responses;
-
-    private volatile boolean endOfResponses;
-
-    public Request(Object id, Object message, long timeoutMillis) {
-        this(id, message, true, timeoutMillis);
-    }
-
-    public Request(Object id, Object message, boolean useResponseQueue, long timeoutMillis) {
-        this(id, message, useResponseQueue, timeoutMillis, TimeUnit.MILLISECONDS);
-    }
-
-    public Request(Object id, Object message, long timeout, TimeUnit unit) {
-        this(id, message, true, timeout, unit);
-    }
-
-    public Request(Object id, Object message, boolean useResponseQueue, long timeout, TimeUnit unit) {
-        if (id == null) {
-            throw new IllegalArgumentException("id");
-        }
-        if (message == null) {
-            throw new IllegalArgumentException("message");
-        }
-        if (timeout < 0) {
-            throw new IllegalArgumentException("timeout: " + timeout + " (expected: 0+)");
-        } else if (timeout == 0) {
-            timeout = Long.MAX_VALUE;
-        }
-
-        if (unit == null) {
-            throw new IllegalArgumentException("unit");
-        }
-
-        this.id = id;
-        this.message = message;
-        this.responses = useResponseQueue ? new LinkedBlockingQueue<Object>() : null;
-        this.timeoutMillis = unit.toMillis(timeout);
-    }
-
-    public Object getId() {
-        return id;
-    }
-
-    public Object getMessage() {
-        return message;
-    }
-
-    public long getTimeoutMillis() {
-        return timeoutMillis;
-    }
-
-    public boolean isUseResponseQueue() {
-        return responses != null;
-    }
-
-    public boolean hasResponse() {
-        checkUseResponseQueue();
-        return !responses.isEmpty();
-    }
-
-    public Response awaitResponse() throws RequestTimeoutException, InterruptedException {
-        checkUseResponseQueue();
-        chechEndOfResponses();
-        return convertToResponse(responses.take());
-    }
-
-    public Response awaitResponse(long timeout, TimeUnit unit) throws RequestTimeoutException, InterruptedException {
-        checkUseResponseQueue();
-        chechEndOfResponses();
-        return convertToResponse(responses.poll(timeout, unit));
-    }
-
-    private Response convertToResponse(Object o) {
-        if (o instanceof Response) {
-            return (Response) o;
-        }
-
-        if (o == null) {
-            return null;
-        }
-
-        throw (RequestTimeoutException) o;
-    }
-
-    public Response awaitResponseUninterruptibly() throws RequestTimeoutException {
-        for (;;) {
-            try {
-                return awaitResponse();
-            } catch (InterruptedException e) {
-                // Do nothing
-            }
-        }
-    }
-
-    private void chechEndOfResponses() {
-        if (responses != null && endOfResponses && responses.isEmpty()) {
-            throw new NoSuchElementException("All responses has been retrieved already.");
-        }
-    }
-
-    private void checkUseResponseQueue() {
-        if (responses == null) {
-            throw new UnsupportedOperationException("Response queue is not available; useResponseQueue is false.");
-        }
-    }
-
-    void signal(Response response) {
-        signal0(response);
-        if (response.getType() != ResponseType.PARTIAL) {
-            endOfResponses = true;
-        }
-    }
-
-    void signal(RequestTimeoutException e) {
-        signal0(e);
-        endOfResponses = true;
-    }
-
-    private void signal0(Object answer) {
-        if (responses != null) {
-            responses.add(answer);
-        }
-    }
-
-    @Override
-    public int hashCode() {
-        return getId().hashCode();
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (o == this) {
-            return true;
-        }
-
-        if (o == null) {
-            return false;
-        }
-
-        if (!(o instanceof Request)) {
-            return false;
-        }
-
-        Request that = (Request) o;
-        return this.getId().equals(that.getId());
-    }
-
-    @Override
-    public String toString() {
-        String timeout = getTimeoutMillis() == Long.MAX_VALUE ? "max" : String.valueOf(getTimeoutMillis());
-
-        return "request: { id=" + getId() + ", timeout=" + timeout + ", message=" + getMessage() + " }";
-    }
-
-    Runnable getTimeoutTask() {
-        return timeoutTask;
-    }
-
-    void setTimeoutTask(Runnable timeoutTask) {
-        this.timeoutTask = timeoutTask;
-    }
-
-    ScheduledFuture<?> getTimeoutFuture() {
-        return timeoutFuture;
-    }
-
-    void setTimeoutFuture(ScheduledFuture<?> timeoutFuture) {
-        this.timeoutFuture = timeoutFuture;
-    }
-}
diff --git a/mina-core/src/main/java/org/apache/mina/filter/reqres/RequestResponseFilter.java b/mina-core/src/main/java/org/apache/mina/filter/reqres/RequestResponseFilter.java
deleted file mode 100644
index 3479ac7..0000000
--- a/mina-core/src/main/java/org/apache/mina/filter/reqres/RequestResponseFilter.java
+++ /dev/null
@@ -1,354 +0,0 @@
-/*
- *  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.mina.filter.reqres;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ScheduledFuture;
-import java.util.concurrent.TimeUnit;
-
-import org.apache.mina.core.filterchain.IoFilterChain;
-import org.apache.mina.core.session.AttributeKey;
-import org.apache.mina.core.session.IoSession;
-import org.apache.mina.core.write.WriteRequest;
-import org.apache.mina.filter.util.WriteRequestFilter;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * TODO Add documentation
- * 
- * @author <a href="http://mina.apache.org">Apache MINA Project</a>
- * @org.apache.xbean.XBean
- */
-public class RequestResponseFilter extends WriteRequestFilter {
-
-    private final AttributeKey RESPONSE_INSPECTOR = new AttributeKey(getClass(), "responseInspector");
-
-    private final AttributeKey REQUEST_STORE = new AttributeKey(getClass(), "requestStore");
-
-    private final AttributeKey UNRESPONDED_REQUEST_STORE = new AttributeKey(getClass(), "unrespondedRequestStore");
-
-    private final ResponseInspectorFactory responseInspectorFactory;
-
-    private final ScheduledExecutorService timeoutScheduler;
-
-    private final static Logger LOGGER = LoggerFactory.getLogger(RequestResponseFilter.class);
-
-    public RequestResponseFilter(final ResponseInspector responseInspector, ScheduledExecutorService timeoutScheduler) {
-        if (responseInspector == null) {
-            throw new IllegalArgumentException("responseInspector");
-        }
-        if (timeoutScheduler == null) {
-            throw new IllegalArgumentException("timeoutScheduler");
-        }
-        this.responseInspectorFactory = new ResponseInspectorFactory() {
-            public ResponseInspector getResponseInspector() {
-                return responseInspector;
-            }
-        };
-        this.timeoutScheduler = timeoutScheduler;
-    }
-
-    public RequestResponseFilter(ResponseInspectorFactory responseInspectorFactory,
-            ScheduledExecutorService timeoutScheduler) {
-        if (responseInspectorFactory == null) {
-            throw new IllegalArgumentException("responseInspectorFactory");
-        }
-        if (timeoutScheduler == null) {
-            throw new IllegalArgumentException("timeoutScheduler");
-        }
-        this.responseInspectorFactory = responseInspectorFactory;
-        this.timeoutScheduler = timeoutScheduler;
-    }
-
-    @Override
-    public void onPreAdd(IoFilterChain parent, String name, NextFilter nextFilter) throws Exception {
-        if (parent.contains(this)) {
-            throw new IllegalArgumentException(
-                    "You can't add the same filter instance more than once.  Create another instance and add it.");
-        }
-
-        IoSession session = parent.getSession();
-        session.setAttribute(RESPONSE_INSPECTOR, responseInspectorFactory.getResponseInspector());
-        session.setAttribute(REQUEST_STORE, createRequestStore(session));
-        session.setAttribute(UNRESPONDED_REQUEST_STORE, createUnrespondedRequestStore(session));
-    }
-
-    @Override
-    public void onPostRemove(IoFilterChain parent, String name, NextFilter nextFilter) throws Exception {
-        IoSession session = parent.getSession();
-
-        destroyUnrespondedRequestStore(getUnrespondedRequestStore(session));
-        destroyRequestStore(getRequestStore(session));
-
-        session.removeAttribute(UNRESPONDED_REQUEST_STORE);
-        session.removeAttribute(REQUEST_STORE);
-        session.removeAttribute(RESPONSE_INSPECTOR);
-    }
-
-    @Override
-    public void messageReceived(NextFilter nextFilter, IoSession session, Object message) throws Exception {
-        ResponseInspector responseInspector = (ResponseInspector) session.getAttribute(RESPONSE_INSPECTOR);
-        Object requestId = responseInspector.getRequestId(message);
-        
-        if (requestId == null) {
-            // Not a response message.  Ignore.
-            nextFilter.messageReceived(session, message);
-            return;
-        }
-
-        // Retrieve (or remove) the corresponding request.
-        ResponseType type = responseInspector.getResponseType(message);
-        
-        if (type == null) {
-            nextFilter.exceptionCaught(session, new IllegalStateException(responseInspector.getClass().getName()
-                    + "#getResponseType() may not return null."));
-            
-            return;
-        }
-
-        Map<Object, Request> requestStore = getRequestStore(session);
-
-        Request request;
-        
-        switch (type) {
-            case WHOLE:
-            case PARTIAL_LAST:
-                synchronized (requestStore) {
-                    request = requestStore.remove(requestId);
-                }
-                break;
-                
-            case PARTIAL:
-                synchronized (requestStore) {
-                    request = requestStore.get(requestId);
-                }
-                break;
-                
-            default:
-                throw new InternalError();
-        }
-
-        if (request == null) {
-            // A response message without request. Swallow the event because
-            // the response might have arrived too late.
-            if (LOGGER.isWarnEnabled()) {
-                LOGGER.warn("Unknown request ID '" + requestId + "' for the response message. Timed out already?: "
-                        + message);
-            }
-        } else {
-            // Found a matching request.
-            // Cancel the timeout task if needed.
-            if (type != ResponseType.PARTIAL) {
-                ScheduledFuture<?> scheduledFuture = request.getTimeoutFuture();
-                if (scheduledFuture != null) {
-                    scheduledFuture.cancel(false);
-                    Set<Request> unrespondedRequests = getUnrespondedRequestStore(session);
-                    synchronized (unrespondedRequests) {
-                        unrespondedRequests.remove(request);
-                    }
-                }
-            }
-
-            // And forward the event.
-            Response response = new Response(request, message, type);
-            request.signal(response);
-            nextFilter.messageReceived(session, response);
-        }
-    }
-
-    @Override
-    protected Object doFilterWrite(final NextFilter nextFilter, IoSession session, WriteRequest writeRequest)
-            throws Exception {
-        Object message = writeRequest.getMessage();
-        if (!(message instanceof Request)) {
-            return null;
-        }
-
-        final Request request = (Request) message;
-        if (request.getTimeoutFuture() != null) {
-            throw new IllegalArgumentException("Request can not be reused.");
-        }
-
-        Map<Object, Request> requestStore = getRequestStore(session);
-        Object oldValue = null;
-        Object requestId = request.getId();
-        synchronized (requestStore) {
-            oldValue = requestStore.get(requestId);
-            if (oldValue == null) {
-                requestStore.put(requestId, request);
-            }
-        }
-        if (oldValue != null) {
-            throw new IllegalStateException("Duplicate request ID: " + request.getId());
-        }
-
-        // Schedule a task to be executed on timeout.
-        TimeoutTask timeoutTask = new TimeoutTask(nextFilter, request, session);
-        ScheduledFuture<?> timeoutFuture = timeoutScheduler.schedule(timeoutTask, request.getTimeoutMillis(),
-                TimeUnit.MILLISECONDS);
-        request.setTimeoutTask(timeoutTask);
-        request.setTimeoutFuture(timeoutFuture);
-
-        // Add the timeout task to the unfinished task set.
-        Set<Request> unrespondedRequests = getUnrespondedRequestStore(session);
-        synchronized (unrespondedRequests) {
-            unrespondedRequests.add(request);
-        }
-
-        return request.getMessage();
-    }
-
-    @Override
-    public void sessionClosed(NextFilter nextFilter, IoSession session) throws Exception {
-        // Copy the unfinished task set to avoid unnecessary lock acquisition.
-        // Copying will be cheap because there won't be that many requests queued.
-        Set<Request> unrespondedRequests = getUnrespondedRequestStore(session);
-        List<Request> unrespondedRequestsCopy;
-        synchronized (unrespondedRequests) {
-            unrespondedRequestsCopy = new ArrayList<Request>(unrespondedRequests);
-            unrespondedRequests.clear();
-        }
-
-        // Generate timeout artificially.
-        for (Request r : unrespondedRequestsCopy) {
-            if (r.getTimeoutFuture().cancel(false)) {
-                r.getTimeoutTask().run();
-            }
-        }
-
-        // Clear the request store just in case we missed something, though it's unlikely.
-        Map<Object, Request> requestStore = getRequestStore(session);
-        synchronized (requestStore) {
-            requestStore.clear();
-        }
-
-        // Now tell the main subject.
-        nextFilter.sessionClosed(session);
-    }
-
-    @SuppressWarnings("unchecked")
-    private Map<Object, Request> getRequestStore(IoSession session) {
-        return (Map<Object, Request>) session.getAttribute(REQUEST_STORE);
-    }
-
-    @SuppressWarnings("unchecked")
-    private Set<Request> getUnrespondedRequestStore(IoSession session) {
-        return (Set<Request>) session.getAttribute(UNRESPONDED_REQUEST_STORE);
-    }
-
-    /**
-     * Returns a {@link Map} which stores {@code messageId}-{@link Request}
-     * pairs whose {@link Response}s are not received yet.  Please override
-     * this method if you need to use other {@link Map} implementation
-     * than the default one ({@link HashMap}).
-     */
-    protected Map<Object, Request> createRequestStore(IoSession session) {
-        return new ConcurrentHashMap<Object, Request>();
-    }
-
-    /**
-     * Returns a {@link Set} which stores {@link Request} whose
-     * {@link Response}s are not received yet. Please override
-     * this method if you need to use other {@link Set} implementation
-     * than the default one ({@link LinkedHashSet}).  Please note that
-     * the {@link Iterator} of the returned {@link Set} have to iterate
-     * its elements in the insertion order to ensure that
-     * {@link RequestTimeoutException}s are thrown in the order which
-     * {@link Request}s were written.  If you don't need to guarantee
-     * the order of thrown exceptions, any {@link Set} implementation
-     * can be used.
-     */
-    protected Set<Request> createUnrespondedRequestStore(IoSession session) {
-        return new LinkedHashSet<Request>();
-    }
-
-    /**
-     * Releases any resources related with the {@link Map} created by
-     * {@link #createRequestStore(IoSession)}.  This method is useful
-     * if you override {@link #createRequestStore(IoSession)}.
-     *
-     * @param requestStore what you returned in {@link #createRequestStore(IoSession)}
-     */
-    protected void destroyRequestStore(Map<Object, Request> requestStore) {
-        // Do nothing
-    }
-
-    /**
-     * Releases any resources related with the {@link Set} created by
-     * {@link #createUnrespondedRequestStore(IoSession)}.  This method is
-     * useful if you override {@link #createUnrespondedRequestStore(IoSession)}.
-     *
-     * @param unrespondedRequestStore what you returned in {@link #createUnrespondedRequestStore(IoSession)}
-     */
-    protected void destroyUnrespondedRequestStore(Set<Request> unrespondedRequestStore) {
-        // Do nothing
-    }
-
-    private class TimeoutTask implements Runnable {
-        private final NextFilter filter;
-
-        private final Request request;
-
-        private final IoSession session;
-
-        private TimeoutTask(NextFilter filter, Request request, IoSession session) {
-            this.filter = filter;
-            this.request = request;
-            this.session = session;
-        }
-
-        public void run() {
-            Set<Request> unrespondedRequests = getUnrespondedRequestStore(session);
-            if (unrespondedRequests != null) {
-                synchronized (unrespondedRequests) {
-                    unrespondedRequests.remove(request);
-                }
-            }
-
-            Map<Object, Request> requestStore = getRequestStore(session);
-            Object requestId = request.getId();
-            boolean timedOut;
-            synchronized (requestStore) {
-                if (requestStore.get(requestId) == request) {
-                    requestStore.remove(requestId);
-                    timedOut = true;
-                } else {
-                    timedOut = false;
-                }
-            }
-
-            if (timedOut) {
-                // Throw the exception only when it's really timed out.
-                RequestTimeoutException e = new RequestTimeoutException(request);
-                request.signal(e);
-                filter.exceptionCaught(session, e);
-            }
-        }
-    }
-}
diff --git a/mina-core/src/main/java/org/apache/mina/filter/reqres/RequestTimeoutException.java b/mina-core/src/main/java/org/apache/mina/filter/reqres/RequestTimeoutException.java
deleted file mode 100644
index 37095d2..0000000
--- a/mina-core/src/main/java/org/apache/mina/filter/reqres/RequestTimeoutException.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- *  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.mina.filter.reqres;
-
-import org.apache.mina.core.RuntimeIoException;
-
-/**
- * An {@link RuntimeIoException} which is thrown when a {@link Request} is timed out.
- *
- * @author <a href="http://mina.apache.org">Apache MINA Project</a>
- */
-public class RequestTimeoutException extends RuntimeException {
-    private static final long serialVersionUID = 5546784978950631652L;
-
-    private final Request request;
-
-    /**
-     * Creates a new exception.
-     */
-    public RequestTimeoutException(Request request) {
-        if (request == null) {
-            throw new IllegalArgumentException("request");
-        }
-        this.request = request;
-    }
-
-    /**
-     * Creates a new exception.
-     */
-    public RequestTimeoutException(Request request, String s) {
-        super(s);
-        if (request == null) {
-            throw new IllegalArgumentException("request");
-        }
-        this.request = request;
-    }
-
-    /**
-     * Creates a new exception.
-     */
-    public RequestTimeoutException(Request request, String message, Throwable cause) {
-        super(message);
-        initCause(cause);
-        if (request == null) {
-            throw new IllegalArgumentException("request");
-        }
-        this.request = request;
-    }
-
-    /**
-     * Creates a new exception.
-     */
-    public RequestTimeoutException(Request request, Throwable cause) {
-        initCause(cause);
-        if (request == null) {
-            throw new IllegalArgumentException("request");
-        }
-        this.request = request;
-    }
-
-    /**
-     * Returns the request which has timed out.
-     */
-    public Request getRequest() {
-        return request;
-    }
-}
\ No newline at end of file
diff --git a/mina-core/src/main/java/org/apache/mina/filter/reqres/Response.java b/mina-core/src/main/java/org/apache/mina/filter/reqres/Response.java
deleted file mode 100644
index ffc10e5..0000000
--- a/mina-core/src/main/java/org/apache/mina/filter/reqres/Response.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- *  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.mina.filter.reqres;
-
-/**
- * TODO Add documentation
- * 
- * @author <a href="http://mina.apache.org">Apache MINA Project</a>
- */
-public class Response {
-    private final Request request;
-
-    private final ResponseType type;
-
-    private final Object message;
-
-    public Response(Request request, Object message, ResponseType type) {
-        if (request == null) {
-            throw new IllegalArgumentException("request");
-        }
-
-        if (message == null) {
-            throw new IllegalArgumentException("message");
-        }
-
-        if (type == null) {
-            throw new IllegalArgumentException("type");
-        }
-
-        this.request = request;
-        this.type = type;
-        this.message = message;
-    }
-
-    public Request getRequest() {
-        return request;
-    }
-
-    public ResponseType getType() {
-        return type;
-    }
-
-    public Object getMessage() {
-        return message;
-    }
-
-    @Override
-    public int hashCode() {
-        return getRequest().getId().hashCode();
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (o == this) {
-            return true;
-        }
-
-        if (o == null) {
-            return false;
-        }
-
-        if (!(o instanceof Response)) {
-            return false;
-        }
-
-        Response that = (Response) o;
-        if (!this.getRequest().equals(that.getRequest())) {
-            return false;
-        }
-
-        return this.getType().equals(that.getType());
-    }
-
-    @Override
-    public String toString() {
-        return "response: { requestId=" + getRequest().getId() + ", type=" + getType() + ", message=" + getMessage()
-                + " }";
-    }
-}
diff --git a/mina-core/src/main/java/org/apache/mina/filter/reqres/ResponseInspector.java b/mina-core/src/main/java/org/apache/mina/filter/reqres/ResponseInspector.java
deleted file mode 100644
index 089122e..0000000
--- a/mina-core/src/main/java/org/apache/mina/filter/reqres/ResponseInspector.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- *  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.mina.filter.reqres;
-
-/**
- * TODO Add documentation
- * 
- * @author <a href="http://mina.apache.org">Apache MINA Project</a>
- */
-public interface ResponseInspector {
-    Object getRequestId(Object message);
-
-    ResponseType getResponseType(Object message);
-}
diff --git a/mina-core/src/main/java/org/apache/mina/filter/reqres/ResponseInspectorFactory.java b/mina-core/src/main/java/org/apache/mina/filter/reqres/ResponseInspectorFactory.java
deleted file mode 100644
index f9ecebf..0000000
--- a/mina-core/src/main/java/org/apache/mina/filter/reqres/ResponseInspectorFactory.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- *  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.mina.filter.reqres;
-
-/**
- * TODO Add documentation
- * 
- * @author <a href="http://mina.apache.org">Apache MINA Project</a>
- */
-public interface ResponseInspectorFactory {
-    /**
-     * Returns a {@link ResponseInspector}.
-     */
-    ResponseInspector getResponseInspector();
-}
diff --git a/mina-core/src/main/java/org/apache/mina/filter/reqres/ResponseType.java b/mina-core/src/main/java/org/apache/mina/filter/reqres/ResponseType.java
deleted file mode 100644
index 1ca2dc2..0000000
--- a/mina-core/src/main/java/org/apache/mina/filter/reqres/ResponseType.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- *  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.mina.filter.reqres;
-
-/**
- * Type of Response contained within the {@code Response} class
- *
- * Response can be either a single entity or a multiple partial messages, in which
- * case PARTIAL_LAST signifies the end of partial messages
- *
- * For response contained within a single message/entity the ResponseType shall be
- * WHOLE
- *
- * For response with multiple partial messages, we have respnse type sepcified as
- *
- * [PARTIAL]+ PARTIAL_LAST
- *
- * meaning, we have One or more PARTIAL response type with one PARTIAL_LAST which
- * signifies end of partial messages or completion of response message
- * 
- * @author <a href="http://mina.apache.org">Apache MINA Project</a>
- */
-public enum ResponseType {
-    WHOLE, PARTIAL, PARTIAL_LAST;
-}
diff --git a/mina-core/src/test/java/org/apache/mina/filter/reqres/RequestResponseFilterTest.java b/mina-core/src/test/java/org/apache/mina/filter/reqres/RequestResponseFilterTest.java
deleted file mode 100644
index ea66c7e..0000000
--- a/mina-core/src/test/java/org/apache/mina/filter/reqres/RequestResponseFilterTest.java
+++ /dev/null
@@ -1,340 +0,0 @@
-/*
- *  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.mina.filter.reqres;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.util.NoSuchElementException;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-
-import org.apache.mina.core.filterchain.IoFilterChain;
-import org.apache.mina.core.filterchain.IoFilter.NextFilter;
-import org.apache.mina.core.session.DummySession;
-import org.apache.mina.core.session.IoSession;
-import org.apache.mina.core.write.DefaultWriteRequest;
-import org.apache.mina.core.write.WriteRequest;
-import org.easymock.AbstractMatcher;
-import org.easymock.MockControl;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * Tests {@link RequestResponseFilter}.
- *
- * @author <a href="http://mina.apache.org">Apache MINA Project</a>
- */
-public class RequestResponseFilterTest {
-
-    private ScheduledExecutorService scheduler;
-
-    private RequestResponseFilter filter;
-
-    private IoSession session;
-
-    private IoFilterChain chain;
-
-    private NextFilter nextFilter;
-
-    private MockControl nextFilterControl;
-
-    private final WriteRequestMatcher matcher = new WriteRequestMatcher();
-
-    @Before
-    public void setUp() throws Exception {
-        scheduler = Executors.newScheduledThreadPool(1);
-        filter = new RequestResponseFilter(new MessageInspector(), scheduler);
-
-        // Set up mock objects.
-        session = new DummySession();
-        chain = session.getFilterChain();
-        nextFilterControl = MockControl.createControl(NextFilter.class);
-        nextFilter = (NextFilter) nextFilterControl.getMock();
-
-        // Initialize the filter.
-        filter.onPreAdd(chain, "reqres", nextFilter);
-        filter.onPostAdd(chain, "reqres", nextFilter);
-        assertFalse(session.getAttributeKeys().isEmpty());
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        // Destroy the filter.
-        filter.onPreRemove(chain, "reqres", nextFilter);
-        filter.onPostRemove(chain, "reqres", nextFilter);
-        filter.destroy();
-        filter = null;
-        scheduler.shutdown();
-    }
-
-    @Test
-    public void testWholeResponse() throws Exception {
-        Request req = new Request(1, new Object(), Long.MAX_VALUE);
-        Response res = new Response(req, new Message(1, ResponseType.WHOLE), ResponseType.WHOLE);
-        WriteRequest rwr = new DefaultWriteRequest(req);
-
-        // Record
-        nextFilter.filterWrite(session, new DefaultWriteRequest(req.getMessage()));
-        nextFilterControl.setMatcher(matcher);
-        nextFilter.messageSent(session, rwr);
-        nextFilter.messageReceived(session, res);
-
-        // Replay
-        nextFilterControl.replay();
-        filter.filterWrite(nextFilter, session, rwr);
-        filter.messageSent(nextFilter, session, matcher.getLastWriteRequest());
-        filter.messageReceived(nextFilter, session, res.getMessage());
-        filter.messageReceived(nextFilter, session, res.getMessage()); // Ignored
-
-        // Verify
-        nextFilterControl.verify();
-        assertEquals(res, req.awaitResponse());
-        assertNoSuchElementException(req);
-    }
-
-    private void assertNoSuchElementException(Request req) throws InterruptedException {
-        // Make sure if an exception is thrown if a user waits one more time.
-        try {
-            req.awaitResponse();
-            fail();
-        } catch (NoSuchElementException e) {
-            // Signifies a successful test execution
-            assertTrue(true);
-        }
-    }
-
-    @Test
-    public void testPartialResponse() throws Exception {
-        Request req = new Request(1, new Object(), Long.MAX_VALUE);
-        Response res1 = new Response(req, new Message(1, ResponseType.PARTIAL), ResponseType.PARTIAL);
-        Response res2 = new Response(req, new Message(1, ResponseType.PARTIAL_LAST), ResponseType.PARTIAL_LAST);
-        WriteRequest rwr = new DefaultWriteRequest(req);
-
-        // Record
-        nextFilter.filterWrite(session, new DefaultWriteRequest(req.getMessage()));
-        nextFilterControl.setMatcher(matcher);
-        nextFilter.messageSent(session, rwr);
-        nextFilter.messageReceived(session, res1);
-        nextFilter.messageReceived(session, res2);
-
-        // Replay
-        nextFilterControl.replay();
-        filter.filterWrite(nextFilter, session, rwr);
-        filter.messageSent(nextFilter, session, matcher.getLastWriteRequest());
-        filter.messageReceived(nextFilter, session, res1.getMessage());
-        filter.messageReceived(nextFilter, session, res2.getMessage());
-        filter.messageReceived(nextFilter, session, res1.getMessage()); // Ignored
-        filter.messageReceived(nextFilter, session, res2.getMessage()); // Ignored
-
-        // Verify
-        nextFilterControl.verify();
-        assertEquals(res1, req.awaitResponse());
-        assertEquals(res2, req.awaitResponse());
-        assertNoSuchElementException(req);
-    }
-
-    @Test
-    public void testWholeResponseTimeout() throws Exception {
-        Request req = new Request(1, new Object(), 10); // 10ms timeout
-        Response res = new Response(req, new Message(1, ResponseType.WHOLE), ResponseType.WHOLE);
-        WriteRequest rwr = new DefaultWriteRequest(req);
-
-        // Record
-        nextFilter.filterWrite(session, new DefaultWriteRequest(req.getMessage()));
-        nextFilterControl.setMatcher(matcher);
-        nextFilter.messageSent(session, rwr);
-        nextFilter.exceptionCaught(session, new RequestTimeoutException(req));
-        nextFilterControl.setMatcher(new ExceptionMatcher());
-
-        // Replay
-        nextFilterControl.replay();
-        filter.filterWrite(nextFilter, session, rwr);
-        filter.messageSent(nextFilter, session, matcher.getLastWriteRequest());
-        Thread.sleep(300); // Wait until the request times out.
-        filter.messageReceived(nextFilter, session, res.getMessage()); // Ignored
-
-        // Verify
-        nextFilterControl.verify();
-        assertRequestTimeoutException(req);
-        assertNoSuchElementException(req);
-    }
-
-    private void assertRequestTimeoutException(Request req) throws InterruptedException {
-        try {
-            req.awaitResponse();
-            fail();
-        } catch (RequestTimeoutException e) {
-            // Signifies a successful test execution
-            assertTrue(true);
-        }
-    }
-
-    @Test
-    public void testPartialResponseTimeout() throws Exception {
-        Request req = new Request(1, new Object(), 10); // 10ms timeout
-        Response res1 = new Response(req, new Message(1, ResponseType.PARTIAL), ResponseType.PARTIAL);
-        Response res2 = new Response(req, new Message(1, ResponseType.PARTIAL_LAST), ResponseType.PARTIAL_LAST);
-        WriteRequest rwr = new DefaultWriteRequest(req);
-
-        // Record
-        nextFilter.filterWrite(session, new DefaultWriteRequest(req.getMessage()));
-        nextFilterControl.setMatcher(matcher);
-        nextFilter.messageSent(session, rwr);
-        nextFilter.messageReceived(session, res1);
-        nextFilter.exceptionCaught(session, new RequestTimeoutException(req));
-        nextFilterControl.setMatcher(new ExceptionMatcher());
-
-        // Replay
-        nextFilterControl.replay();
-        filter.filterWrite(nextFilter, session, rwr);
-        filter.messageSent(nextFilter, session, matcher.getLastWriteRequest());
-        filter.messageReceived(nextFilter, session, res1.getMessage());
-        Thread.sleep(300); // Wait until the request times out.
-        filter.messageReceived(nextFilter, session, res2.getMessage()); // Ignored
-        filter.messageReceived(nextFilter, session, res1.getMessage()); // Ignored
-
-        // Verify
-        nextFilterControl.verify();
-        assertEquals(res1, req.awaitResponse());
-        assertRequestTimeoutException(req);
-        assertNoSuchElementException(req);
-    }
-
-    @Test
-    public void testTimeoutByDisconnection() throws Exception {
-        // We run a test case that doesn't raise a timeout to make sure
-        // the timeout is not raised again by disconnection.
-        testWholeResponse();
-        nextFilterControl.reset();
-
-        Request req1 = new Request(1, new Object(), Long.MAX_VALUE);
-        Request req2 = new Request(2, new Object(), Long.MAX_VALUE);
-        WriteRequest rwr1 = new DefaultWriteRequest(req1);
-        WriteRequest rwr2 = new DefaultWriteRequest(req2);
-
-        // Record
-        nextFilter.filterWrite(session, new DefaultWriteRequest(req1.getMessage()));
-        nextFilterControl.setMatcher(matcher);
-        nextFilter.messageSent(session, rwr1);
-        nextFilter.filterWrite(session, new DefaultWriteRequest(req2.getMessage()));
-        nextFilter.messageSent(session, rwr2);
-        nextFilter.exceptionCaught(session, new RequestTimeoutException(req1));
-        nextFilterControl.setMatcher(new ExceptionMatcher());
-        nextFilter.exceptionCaught(session, new RequestTimeoutException(req2));
-        nextFilter.sessionClosed(session);
-
-        // Replay
-        nextFilterControl.replay();
-        filter.filterWrite(nextFilter, session, rwr1);
-        filter.messageSent(nextFilter, session, matcher.getLastWriteRequest());
-        filter.filterWrite(nextFilter, session, rwr2);
-        filter.messageSent(nextFilter, session, matcher.getLastWriteRequest());
-        filter.sessionClosed(nextFilter, session);
-
-        // Verify
-        nextFilterControl.verify();
-        assertRequestTimeoutException(req1);
-        assertRequestTimeoutException(req2);
-    }
-
-    static class Message {
-        private final int id;
-
-        private final ResponseType type;
-
-        Message(int id, ResponseType type) {
-            this.id = id;
-            this.type = type;
-        }
-
-        public int getId() {
-            return id;
-        }
-
-        public ResponseType getType() {
-            return type;
-        }
-    }
-
-    private static class MessageInspector implements ResponseInspector {
-        /**
-         * Default constructor
-         */
-        public MessageInspector() {
-            super();
-        }
-
-        public Object getRequestId(Object message) {
-            if (!(message instanceof Message)) {
-                return null;
-            }
-
-            return ((Message) message).getId();
-        }
-
-        public ResponseType getResponseType(Object message) {
-            if (!(message instanceof Message)) {
-                return null;
-            }
-
-            return ((Message) message).getType();
-        }
-    }
-
-    private static class WriteRequestMatcher extends AbstractMatcher {
-        private WriteRequest lastWriteRequest;
-
-        /**
-         * Default constructor
-         */
-        public WriteRequestMatcher() {
-            super();
-        }
-
-        public WriteRequest getLastWriteRequest() {
-            return lastWriteRequest;
-        }
-
-        @Override
-        protected boolean argumentMatches(Object expected, Object actual) {
-            if (actual instanceof WriteRequest && expected instanceof WriteRequest) {
-                boolean answer = ((WriteRequest) expected).getMessage().equals(((WriteRequest) actual).getMessage());
-                lastWriteRequest = (WriteRequest) actual;
-                return answer;
-            }
-            return super.argumentMatches(expected, actual);
-        }
-    }
-
-    static class ExceptionMatcher extends AbstractMatcher {
-        @Override
-        protected boolean argumentMatches(Object expected, Object actual) {
-            if (actual instanceof RequestTimeoutException && expected instanceof RequestTimeoutException) {
-                return ((RequestTimeoutException) expected).getRequest().equals(
-                        ((RequestTimeoutException) actual).getRequest());
-            }
-            return super.argumentMatches(expected, actual);
-        }
-    }
-}
