[infinispan-commits] Infinispan SVN: r1337 - in trunk/server/memcached/src: main/java/org/infinispan/server/core and 4 other directories.

infinispan-commits at lists.jboss.org infinispan-commits at lists.jboss.org
Wed Dec 30 12:58:16 EST 2009


Author: galder.zamarreno at jboss.com
Date: 2009-12-30 12:58:15 -0500 (Wed, 30 Dec 2009)
New Revision: 1337

Added:
   trunk/server/memcached/src/main/java/org/infinispan/server/core/
   trunk/server/memcached/src/main/java/org/infinispan/server/core/Channel.java
   trunk/server/memcached/src/main/java/org/infinispan/server/core/ChannelBuffer.java
   trunk/server/memcached/src/main/java/org/infinispan/server/core/ChannelBuffers.java
   trunk/server/memcached/src/main/java/org/infinispan/server/core/ChannelFuture.java
   trunk/server/memcached/src/main/java/org/infinispan/server/core/ChannelHandlerContext.java
   trunk/server/memcached/src/main/java/org/infinispan/server/core/Command.java
   trunk/server/memcached/src/main/java/org/infinispan/server/core/CommandDecoder.java
   trunk/server/memcached/src/main/java/org/infinispan/server/core/CommandFactory.java
   trunk/server/memcached/src/main/java/org/infinispan/server/core/CommandHandler.java
   trunk/server/memcached/src/main/java/org/infinispan/server/core/CommandInterceptor.java
   trunk/server/memcached/src/main/java/org/infinispan/server/core/InterceptorChain.java
   trunk/server/memcached/src/main/java/org/infinispan/server/core/InterceptorChainFactory.java
   trunk/server/memcached/src/main/java/org/infinispan/server/core/MessageEvent.java
   trunk/server/memcached/src/main/java/org/infinispan/server/core/ServerBootstrap.java
   trunk/server/memcached/src/main/java/org/infinispan/server/core/netty/
   trunk/server/memcached/src/main/java/org/infinispan/server/core/netty/NettyChannel.java
   trunk/server/memcached/src/main/java/org/infinispan/server/core/netty/NettyChannelBuffer.java
   trunk/server/memcached/src/main/java/org/infinispan/server/core/netty/NettyChannelBuffers.java
   trunk/server/memcached/src/main/java/org/infinispan/server/core/netty/NettyChannelFuture.java
   trunk/server/memcached/src/main/java/org/infinispan/server/core/netty/NettyChannelHandlerContext.java
   trunk/server/memcached/src/main/java/org/infinispan/server/core/netty/NettyChannelPipelineFactory.java
   trunk/server/memcached/src/main/java/org/infinispan/server/core/netty/NettyChannelUpstreamHandler.java
   trunk/server/memcached/src/main/java/org/infinispan/server/core/netty/NettyMessageEvent.java
   trunk/server/memcached/src/main/java/org/infinispan/server/core/netty/NettyServerBootstrap.java
   trunk/server/memcached/src/main/java/org/infinispan/server/core/netty/memcached/
   trunk/server/memcached/src/main/java/org/infinispan/server/core/netty/memcached/NettyMemcachedDecoder.java
   trunk/server/memcached/src/main/java/org/infinispan/server/memcached/TextCommand.java
   trunk/server/memcached/src/main/java/org/infinispan/server/memcached/TextCommandInterceptor.java
   trunk/server/memcached/src/main/java/org/infinispan/server/memcached/TextCommandInterceptorImpl.java
   trunk/server/memcached/src/main/java/org/infinispan/server/memcached/TextProtocolInterceptorChain.java
   trunk/server/memcached/src/main/java/org/infinispan/server/memcached/TextProtocolInterceptorChainFactory.java
   trunk/server/memcached/src/main/java/org/infinispan/server/memcached/TextProtocolVisitor.java
Removed:
   trunk/server/memcached/src/main/java/org/infinispan/server/memcached/Command.java
   trunk/server/memcached/src/main/java/org/infinispan/server/memcached/CommandInterceptor.java
   trunk/server/memcached/src/main/java/org/infinispan/server/memcached/DeleteDelayed.java
   trunk/server/memcached/src/main/java/org/infinispan/server/memcached/DeleteDelayedEntry.java
   trunk/server/memcached/src/main/java/org/infinispan/server/memcached/InterceptorChainFactory.java
   trunk/server/memcached/src/main/java/org/infinispan/server/memcached/RetrievalReply.java
   trunk/server/memcached/src/main/java/org/infinispan/server/memcached/TextCommandDecoder.java
   trunk/server/memcached/src/main/java/org/infinispan/server/memcached/TextProtocolPipelineFactory.java
   trunk/server/memcached/src/main/java/org/infinispan/server/memcached/Visitor.java
Modified:
   trunk/server/memcached/src/main/java/org/infinispan/server/memcached/AbstractVisitor.java
   trunk/server/memcached/src/main/java/org/infinispan/server/memcached/AddCommand.java
   trunk/server/memcached/src/main/java/org/infinispan/server/memcached/AppendCommand.java
   trunk/server/memcached/src/main/java/org/infinispan/server/memcached/CallInterceptor.java
   trunk/server/memcached/src/main/java/org/infinispan/server/memcached/CasCommand.java
   trunk/server/memcached/src/main/java/org/infinispan/server/memcached/CommandFactory.java
   trunk/server/memcached/src/main/java/org/infinispan/server/memcached/CommandType.java
   trunk/server/memcached/src/main/java/org/infinispan/server/memcached/DecrementCommand.java
   trunk/server/memcached/src/main/java/org/infinispan/server/memcached/DeleteCommand.java
   trunk/server/memcached/src/main/java/org/infinispan/server/memcached/FlushAllCommand.java
   trunk/server/memcached/src/main/java/org/infinispan/server/memcached/GetCommand.java
   trunk/server/memcached/src/main/java/org/infinispan/server/memcached/IncrementCommand.java
   trunk/server/memcached/src/main/java/org/infinispan/server/memcached/InterceptorChain.java
   trunk/server/memcached/src/main/java/org/infinispan/server/memcached/MemcachedStats.java
   trunk/server/memcached/src/main/java/org/infinispan/server/memcached/MemcachedStatsImpl.java
   trunk/server/memcached/src/main/java/org/infinispan/server/memcached/MemcachedTextServer.java
   trunk/server/memcached/src/main/java/org/infinispan/server/memcached/NumericCommand.java
   trunk/server/memcached/src/main/java/org/infinispan/server/memcached/PrependCommand.java
   trunk/server/memcached/src/main/java/org/infinispan/server/memcached/QuitCommand.java
   trunk/server/memcached/src/main/java/org/infinispan/server/memcached/ReplaceCommand.java
   trunk/server/memcached/src/main/java/org/infinispan/server/memcached/RetrievalCommand.java
   trunk/server/memcached/src/main/java/org/infinispan/server/memcached/RetrievalParameters.java
   trunk/server/memcached/src/main/java/org/infinispan/server/memcached/SetCommand.java
   trunk/server/memcached/src/main/java/org/infinispan/server/memcached/StatsCommand.java
   trunk/server/memcached/src/main/java/org/infinispan/server/memcached/StatsInterceptor.java
   trunk/server/memcached/src/main/java/org/infinispan/server/memcached/StorageCommand.java
   trunk/server/memcached/src/main/java/org/infinispan/server/memcached/StorageParameters.java
   trunk/server/memcached/src/main/java/org/infinispan/server/memcached/TextCommandHandler.java
   trunk/server/memcached/src/main/java/org/infinispan/server/memcached/TextProtocolUtil.java
   trunk/server/memcached/src/main/java/org/infinispan/server/memcached/Value.java
   trunk/server/memcached/src/main/java/org/infinispan/server/memcached/VersionCommand.java
   trunk/server/memcached/src/test/java/org/infinispan/server/memcached/FunctionalTest.java
   trunk/server/memcached/src/test/java/org/infinispan/server/memcached/StatsTest.java
Log:
[ISPN-173] (Build memcached server module) Create a core set of interfaces so that netty and memcached are more decoupled.

Added: trunk/server/memcached/src/main/java/org/infinispan/server/core/Channel.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/core/Channel.java	                        (rev 0)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/core/Channel.java	2009-12-30 17:58:15 UTC (rev 1337)
@@ -0,0 +1,35 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat, Inc. and/or its affiliates, and
+ * individual contributors as indicated by the @author tags. See the
+ * copyright.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.server.core;
+
+
+/**
+ * Channel.
+ * 
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+public interface Channel extends Comparable<Channel> {
+   ChannelFuture write(Object message);
+   ChannelFuture disconnect();
+}

Added: trunk/server/memcached/src/main/java/org/infinispan/server/core/ChannelBuffer.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/core/ChannelBuffer.java	                        (rev 0)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/core/ChannelBuffer.java	2009-12-30 17:58:15 UTC (rev 1337)
@@ -0,0 +1,34 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat, Inc. and/or its affiliates, and
+ * individual contributors as indicated by the @author tags. See the
+ * copyright.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.server.core;
+
+/**
+ * ChannelBuffer.
+ * 
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+public interface ChannelBuffer {
+   byte readByte();
+   void readBytes(byte[] dst, int dstIndex, int length);
+}

Added: trunk/server/memcached/src/main/java/org/infinispan/server/core/ChannelBuffers.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/core/ChannelBuffers.java	                        (rev 0)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/core/ChannelBuffers.java	2009-12-30 17:58:15 UTC (rev 1337)
@@ -0,0 +1,34 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat, Inc. and/or its affiliates, and
+ * individual contributors as indicated by the @author tags. See the
+ * copyright.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.server.core;
+
+/**
+ * ChannelBuffers.
+ * 
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+public interface ChannelBuffers {
+   ChannelBuffer wrappedBuffer(ChannelBuffer... buffers);
+   ChannelBuffer wrappedBuffer(byte[] array);
+}

Added: trunk/server/memcached/src/main/java/org/infinispan/server/core/ChannelFuture.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/core/ChannelFuture.java	                        (rev 0)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/core/ChannelFuture.java	2009-12-30 17:58:15 UTC (rev 1337)
@@ -0,0 +1,45 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat, Inc. and/or its affiliates, and
+ * individual contributors as indicated by the @author tags. See the
+ * copyright.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.server.core;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * ChannelFuture.
+ * 
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+public interface ChannelFuture {
+   Channel getChannel();
+   boolean isDone();
+   boolean isCancelled();
+   boolean setSuccess();
+   boolean setFailure(Throwable cause);
+   ChannelFuture await() throws InterruptedException;
+   ChannelFuture awaitUninterruptibly();
+   boolean await(long timeout, TimeUnit unit) throws InterruptedException;
+   boolean await(long timeoutMillis) throws InterruptedException;
+   boolean awaitUninterruptibly(long timeout, TimeUnit unit);
+   boolean awaitUninterruptibly(long timeoutMillis);
+}

Added: trunk/server/memcached/src/main/java/org/infinispan/server/core/ChannelHandlerContext.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/core/ChannelHandlerContext.java	                        (rev 0)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/core/ChannelHandlerContext.java	2009-12-30 17:58:15 UTC (rev 1337)
@@ -0,0 +1,34 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat, Inc. and/or its affiliates, and
+ * individual contributors as indicated by the @author tags. See the
+ * copyright.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.server.core;
+
+/**
+ * ChannelHandlerContext.
+ * 
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+public interface ChannelHandlerContext {
+   Channel getChannel();
+   ChannelBuffers getChannelBuffers();
+}

Added: trunk/server/memcached/src/main/java/org/infinispan/server/core/Command.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/core/Command.java	                        (rev 0)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/core/Command.java	2009-12-30 17:58:15 UTC (rev 1337)
@@ -0,0 +1,35 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat, Inc. and/or its affiliates, and
+ * individual contributors as indicated by the @author tags. See the
+ * copyright.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.server.core;
+
+/**
+ * Command.
+ * 
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+public interface Command {
+
+   Object perform(ChannelHandlerContext ctx) throws Throwable;
+
+}

Added: trunk/server/memcached/src/main/java/org/infinispan/server/core/CommandDecoder.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/core/CommandDecoder.java	                        (rev 0)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/core/CommandDecoder.java	2009-12-30 17:58:15 UTC (rev 1337)
@@ -0,0 +1,33 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat, Inc. and/or its affiliates, and
+ * individual contributors as indicated by the @author tags. See the
+ * copyright.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.server.core;
+
+/**
+ * CommandDecoder.
+ * 
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+public interface CommandDecoder {
+
+}

Added: trunk/server/memcached/src/main/java/org/infinispan/server/core/CommandFactory.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/core/CommandFactory.java	                        (rev 0)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/core/CommandFactory.java	2009-12-30 17:58:15 UTC (rev 1337)
@@ -0,0 +1,35 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat, Inc. and/or its affiliates, and
+ * individual contributors as indicated by the @author tags. See the
+ * copyright.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.server.core;
+
+import java.io.IOException;
+
+/**
+ * CommandFactory.
+ * 
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+public interface CommandFactory {
+   Command createCommand(String line) throws IOException;
+}

Added: trunk/server/memcached/src/main/java/org/infinispan/server/core/CommandHandler.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/core/CommandHandler.java	                        (rev 0)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/core/CommandHandler.java	2009-12-30 17:58:15 UTC (rev 1337)
@@ -0,0 +1,33 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat, Inc. and/or its affiliates, and
+ * individual contributors as indicated by the @author tags. See the
+ * copyright.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.server.core;
+
+/**
+ * CommandHandler.
+ * 
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+public interface CommandHandler {
+   void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Throwable;
+}

Added: trunk/server/memcached/src/main/java/org/infinispan/server/core/CommandInterceptor.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/core/CommandInterceptor.java	                        (rev 0)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/core/CommandInterceptor.java	2009-12-30 17:58:15 UTC (rev 1337)
@@ -0,0 +1,33 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat, Inc. and/or its affiliates, and
+ * individual contributors as indicated by the @author tags. See the
+ * copyright.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.server.core;
+
+/**
+ * CommandInterceptor.
+ * 
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+public interface CommandInterceptor {
+   CommandInterceptor getNext();
+}

Added: trunk/server/memcached/src/main/java/org/infinispan/server/core/InterceptorChain.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/core/InterceptorChain.java	                        (rev 0)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/core/InterceptorChain.java	2009-12-30 17:58:15 UTC (rev 1337)
@@ -0,0 +1,36 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat, Inc. and/or its affiliates, and
+ * individual contributors as indicated by the @author tags. See the
+ * copyright.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.server.core;
+
+import java.util.List;
+
+/**
+ * InterceptorChain.
+ * 
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+public interface InterceptorChain {
+   Object invoke(ChannelHandlerContext ctx, Command command) throws Throwable;
+   List<CommandInterceptor> getInterceptorsWhichExtend(Class<? extends CommandInterceptor> interceptorClass);
+}

Added: trunk/server/memcached/src/main/java/org/infinispan/server/core/InterceptorChainFactory.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/core/InterceptorChainFactory.java	                        (rev 0)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/core/InterceptorChainFactory.java	2009-12-30 17:58:15 UTC (rev 1337)
@@ -0,0 +1,33 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat, Inc. and/or its affiliates, and
+ * individual contributors as indicated by the @author tags. See the
+ * copyright.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.server.core;
+
+/**
+ * InterceptorChainFactory.
+ * 
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+public interface InterceptorChainFactory {
+   InterceptorChain buildInterceptorChain();
+}

Added: trunk/server/memcached/src/main/java/org/infinispan/server/core/MessageEvent.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/core/MessageEvent.java	                        (rev 0)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/core/MessageEvent.java	2009-12-30 17:58:15 UTC (rev 1337)
@@ -0,0 +1,36 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat, Inc. and/or its affiliates, and
+ * individual contributors as indicated by the @author tags. See the
+ * copyright.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.server.core;
+
+import java.net.SocketAddress;
+
+/**
+ * MessageEvent.
+ * 
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+public interface MessageEvent {
+   Object getMessage();
+   SocketAddress getRemoteAddress();
+}

Added: trunk/server/memcached/src/main/java/org/infinispan/server/core/ServerBootstrap.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/core/ServerBootstrap.java	                        (rev 0)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/core/ServerBootstrap.java	2009-12-30 17:58:15 UTC (rev 1337)
@@ -0,0 +1,34 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat, Inc. and/or its affiliates, and
+ * individual contributors as indicated by the @author tags. See the
+ * copyright.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.server.core;
+
+/**
+ * ChannelFactory.
+ * 
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+public interface ServerBootstrap {
+   void start();
+   void stop();
+}

Added: trunk/server/memcached/src/main/java/org/infinispan/server/core/netty/NettyChannel.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/core/netty/NettyChannel.java	                        (rev 0)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/core/netty/NettyChannel.java	2009-12-30 17:58:15 UTC (rev 1337)
@@ -0,0 +1,56 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat, Inc. and/or its affiliates, and
+ * individual contributors as indicated by the @author tags. See the
+ * copyright.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.server.core.netty;
+
+import org.infinispan.server.core.Channel;
+import org.infinispan.server.core.ChannelFuture;
+
+/**
+ * NettyChannel.
+ * 
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+public class NettyChannel implements Channel {
+   final org.jboss.netty.channel.Channel ch;
+
+   public NettyChannel(org.jboss.netty.channel.Channel ch) {
+      this.ch = ch;
+   }
+   
+   @Override
+   public ChannelFuture disconnect() {
+      return new NettyChannelFuture(ch.disconnect(), this);
+   }
+
+   @Override
+   public ChannelFuture write(Object message) {
+      return new NettyChannelFuture(ch.write(message), this);
+   }
+
+   @Override
+   public int compareTo(Channel o) {
+      return ch.compareTo(((NettyChannel) o).ch);
+   }
+
+}

Added: trunk/server/memcached/src/main/java/org/infinispan/server/core/netty/NettyChannelBuffer.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/core/netty/NettyChannelBuffer.java	                        (rev 0)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/core/netty/NettyChannelBuffer.java	2009-12-30 17:58:15 UTC (rev 1337)
@@ -0,0 +1,560 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat, Inc. and/or its affiliates, and
+ * individual contributors as indicated by the @author tags. See the
+ * copyright.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.server.core.netty;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.channels.GatheringByteChannel;
+import java.nio.channels.ScatteringByteChannel;
+
+import org.infinispan.server.core.ChannelBuffer;
+import org.jboss.netty.buffer.ChannelBufferFactory;
+import org.jboss.netty.buffer.ChannelBufferIndexFinder;
+
+/**
+ * NettyChannelBuffer.
+ * 
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+public class NettyChannelBuffer implements ChannelBuffer, org.jboss.netty.buffer.ChannelBuffer {
+   final org.jboss.netty.buffer.ChannelBuffer buffer;
+
+   public NettyChannelBuffer(org.jboss.netty.buffer.ChannelBuffer buffer) {
+      this.buffer = buffer;
+   }
+   
+   @Override
+   public byte readByte() {
+      return buffer.readByte();
+   }
+
+   @Override
+   public void readBytes(byte[] dst, int dstIndex, int length) {
+      buffer.readBytes(dst, dstIndex, length);
+   }
+
+   @Override
+   public int compareTo(org.jboss.netty.buffer.ChannelBuffer o) {
+      return buffer.compareTo(o);
+   }
+
+   @Override
+   public int capacity() {
+      return buffer.capacity();
+   }
+
+   @Override
+   public void clear() {
+      buffer.clear();
+   }
+
+   @Override
+   public org.jboss.netty.buffer.ChannelBuffer copy() {
+      return buffer.copy();
+   }
+
+   @Override
+   public org.jboss.netty.buffer.ChannelBuffer copy(int index, int length) {
+      return buffer.copy(index, length);
+   }
+
+   @Override
+   public void discardReadBytes() {
+      buffer.discardReadBytes();
+   }
+
+   @Override
+   public org.jboss.netty.buffer.ChannelBuffer duplicate() {
+      return buffer.duplicate();
+   }
+
+   @Override
+   public ChannelBufferFactory factory() {
+      return buffer.factory();
+   }
+
+   @Override
+   public byte getByte(int index) {
+      return buffer.getByte(index);
+   }
+
+   @Override
+   public void getBytes(int index, org.jboss.netty.buffer.ChannelBuffer dst) {
+      buffer.getBytes(index, dst);
+   }
+
+   @Override
+   public void getBytes(int index, byte[] dst) {
+      buffer.getBytes(index, dst);
+   }
+
+   @Override
+   public void getBytes(int index, ByteBuffer dst) {
+      buffer.getBytes(index, dst);
+   }
+
+   @Override
+   public void getBytes(int index, org.jboss.netty.buffer.ChannelBuffer dst, int length) {
+      buffer.getBytes(index, dst, length);
+   }
+
+   @Override
+   public void getBytes(int index, OutputStream out, int length) throws IOException {
+      buffer.getBytes(index, out, length);
+   }
+
+   @Override
+   public int getBytes(int index, GatheringByteChannel out, int length) throws IOException {
+      return buffer.getBytes(index, out, length);
+   }
+
+   @Override
+   public void getBytes(int index, org.jboss.netty.buffer.ChannelBuffer dst, int dstIndex, int length) {
+      buffer.getBytes(index, dst, dstIndex, length);
+   }
+
+   @Override
+   public void getBytes(int index, byte[] dst, int dstIndex, int length) {
+      buffer.getBytes(index, dst, dstIndex, length);
+   }
+
+   @Override
+   public int getInt(int index) {
+      return buffer.getInt(index);
+   }
+
+   @Override
+   public long getLong(int index) {
+      return buffer.getLong(index);
+   }
+
+   @Override
+   public int getMedium(int index) {
+      return buffer.getMedium(index);
+   }
+
+   @Override
+   public short getShort(int index) {
+      return buffer.getShort(index);
+   }
+
+   @Override
+   public short getUnsignedByte(int index) {
+      return buffer.getUnsignedByte(index);
+   }
+
+   @Override
+   public long getUnsignedInt(int index) {
+      return buffer.getUnsignedInt(index);
+   }
+
+   @Override
+   public int getUnsignedMedium(int index) {
+      return buffer.getUnsignedMedium(index);
+   }
+
+   @Override
+   public int getUnsignedShort(int index) {
+      return buffer.getUnsignedShort(index);
+   }
+
+   @Override
+   public int indexOf(int fromIndex, int toIndex, byte value) {
+      return buffer.indexOf(fromIndex, toIndex, value);
+   }
+
+   @Override
+   public int indexOf(int fromIndex, int toIndex, ChannelBufferIndexFinder indexFinder) {
+      return buffer.indexOf(fromIndex, toIndex, indexFinder);
+   }
+
+   @Override
+   public void markReaderIndex() {
+      buffer.markReaderIndex();
+   }
+
+   @Override
+   public void markWriterIndex() {
+      buffer.markWriterIndex();
+   }
+
+   @Override
+   public ByteOrder order() {
+      return buffer.order();
+   }
+
+   @Override
+   public org.jboss.netty.buffer.ChannelBuffer readBytes(int length) {
+      return buffer.readBytes(length);
+   }
+
+   @Override
+   public org.jboss.netty.buffer.ChannelBuffer readBytes(ChannelBufferIndexFinder indexFinder) {
+      return buffer.readBytes(indexFinder);
+   }
+
+   @Override
+   public void readBytes(org.jboss.netty.buffer.ChannelBuffer dst) {
+      buffer.readBytes(dst);
+   }
+
+   @Override
+   public void readBytes(byte[] dst) {
+      buffer.readBytes(dst);
+   }
+
+   @Override
+   public void readBytes(ByteBuffer dst) {
+      buffer.readBytes(dst);
+   }
+
+   @Override
+   public void readBytes(org.jboss.netty.buffer.ChannelBuffer dst, int length) {
+      buffer.readBytes(dst, length);
+   }
+
+   @Override
+   public void readBytes(OutputStream out, int length) throws IOException {
+      buffer.readBytes(out, length);
+   }
+
+   @Override
+   public int readBytes(GatheringByteChannel out, int length) throws IOException {
+      return buffer.readBytes(out, length);
+   }
+
+   @Override
+   public void readBytes(org.jboss.netty.buffer.ChannelBuffer dst, int dstIndex, int length) {
+      buffer.readBytes(dst, dstIndex, length);
+   }
+
+   @Override
+   public int readInt() {
+      return buffer.readInt();
+   }
+
+   @Override
+   public long readLong() {
+      return buffer.readLong();
+   }
+
+   @Override
+   public int readMedium() {
+      return buffer.readMedium();
+   }
+
+   @Override
+   public short readShort() {
+      return buffer.readShort();
+   }
+
+   @Override
+   public org.jboss.netty.buffer.ChannelBuffer readSlice(int length) {
+      return buffer.readSlice(length);
+   }
+
+   @Override
+   public org.jboss.netty.buffer.ChannelBuffer readSlice(ChannelBufferIndexFinder indexFinder) {
+      return buffer.readSlice(indexFinder);
+   }
+
+   @Override
+   public short readUnsignedByte() {
+      return buffer.readUnsignedByte();
+   }
+
+   @Override
+   public long readUnsignedInt() {
+      return buffer.readUnsignedInt();
+   }
+
+   @Override
+   public int readUnsignedMedium() {
+      return buffer.readUnsignedMedium();
+   }
+
+   @Override
+   public int readUnsignedShort() {
+      return buffer.readUnsignedShort();
+   }
+
+   @Override
+   public boolean readable() {
+      return buffer.readable();
+   }
+
+   @Override
+   public int readableBytes() {
+      return buffer.readableBytes();
+   }
+
+   @Override
+   public int readerIndex() {
+      return buffer.readerIndex();
+   }
+
+   @Override
+   public void readerIndex(int readerIndex) {
+      buffer.readerIndex(readerIndex);
+   }
+
+   @Override
+   public void resetReaderIndex() {
+      buffer.resetReaderIndex();
+   }
+
+   @Override
+   public void resetWriterIndex() {
+      buffer.resetWriterIndex();
+   }
+
+   @Override
+   public void setByte(int index, byte value) {
+      buffer.setByte(index, value);
+   }
+
+   @Override
+   public void setBytes(int index, org.jboss.netty.buffer.ChannelBuffer src) {
+      buffer.setBytes(index, src);
+   }
+
+   @Override
+   public void setBytes(int index, byte[] src) {
+      buffer.setBytes(index, src);
+   }
+
+   @Override
+   public void setBytes(int index, ByteBuffer src) {
+      buffer.setBytes(index, src);
+   }
+
+   @Override
+   public void setBytes(int index, org.jboss.netty.buffer.ChannelBuffer src, int length) {
+      buffer.setBytes(index, src, length);
+   }
+
+   @Override
+   public int setBytes(int index, InputStream in, int length) throws IOException {
+      return buffer.setBytes(index, in, length);
+   }
+
+   @Override
+   public int setBytes(int index, ScatteringByteChannel in, int length) throws IOException {
+      return buffer.setBytes(index, in, length);
+   }
+
+   @Override
+   public void setBytes(int index, org.jboss.netty.buffer.ChannelBuffer src, int srcIndex, int length) {
+      buffer.setBytes(index, src, srcIndex, length);
+   }
+
+   @Override
+   public void setBytes(int index, byte[] src, int srcIndex, int length) {
+      buffer.setBytes(index, src, srcIndex, length);
+   }
+
+   @Override
+   public void setIndex(int readerIndex, int writerIndex) {
+      buffer.setIndex(readerIndex, writerIndex);
+   }
+
+   @Override
+   public void setInt(int index, int value) {
+      buffer.setInt(index, value);
+   }
+
+   @Override
+   public void setLong(int index, long value) {
+      buffer.setLong(index, value);
+   }
+
+   @Override
+   public void setMedium(int index, int value) {
+      buffer.setMedium(index, value);
+   }
+
+   @Override
+   public void setShort(int index, short value) {
+      buffer.setShort(index, value);
+   }
+
+   @Override
+   public void setZero(int index, int length) {
+      buffer.setZero(index, length);
+   }
+
+   @Override
+   public void skipBytes(int length) {
+      buffer.skipBytes(length);
+   }
+
+   @Override
+   public int skipBytes(ChannelBufferIndexFinder indexFinder) {
+      return buffer.skipBytes(indexFinder);
+   }
+
+   @Override
+   public org.jboss.netty.buffer.ChannelBuffer slice() {
+      return buffer.slice();
+   }
+
+   @Override
+   public org.jboss.netty.buffer.ChannelBuffer slice(int index, int length) {
+      return buffer.slice(index, length);
+   }
+
+   @Override
+   public ByteBuffer toByteBuffer() {
+      return buffer.toByteBuffer();
+   }
+
+   @Override
+   public ByteBuffer toByteBuffer(int index, int length) {
+      return buffer.toByteBuffer(index, length);
+   }
+
+   @Override
+   public ByteBuffer[] toByteBuffers() {
+      return buffer.toByteBuffers();
+   }
+
+   @Override
+   public ByteBuffer[] toByteBuffers(int index, int length) {
+      return buffer.toByteBuffers(index, length);
+   }
+
+   @Override
+   public String toString(String charsetName) {
+      return buffer.toString(charsetName);
+   }
+
+   @Override
+   public String toString(String charsetName, ChannelBufferIndexFinder terminatorFinder) {
+      return buffer.toString(charsetName, terminatorFinder);
+   }
+
+   @Override
+   public String toString(int index, int length, String charsetName) {
+      return buffer.toString(index, length, charsetName);
+   }
+
+   @Override
+   public String toString(int index, int length, String charsetName, ChannelBufferIndexFinder terminatorFinder) {
+      return buffer.toString(charsetName, terminatorFinder);
+   }
+
+   @Override
+   public boolean writable() {
+      return buffer.writable();
+   }
+
+   @Override
+   public int writableBytes() {
+      return buffer.writableBytes();
+   }
+
+   @Override
+   public void writeByte(byte value) {
+      buffer.writeByte(value);
+   }
+
+   @Override
+   public void writeBytes(org.jboss.netty.buffer.ChannelBuffer src) {
+      buffer.writeBytes(src);
+   }
+
+   @Override
+   public void writeBytes(byte[] src) {
+      buffer.writeBytes(src);
+   }
+
+   @Override
+   public void writeBytes(ByteBuffer src) {
+      buffer.writeBytes(src);
+   }
+
+   @Override
+   public void writeBytes(org.jboss.netty.buffer.ChannelBuffer src, int length) {
+      buffer.writeBytes(src, length);
+   }
+
+   @Override
+   public int writeBytes(InputStream in, int length) throws IOException {
+      return buffer.writeBytes(in, length);
+   }
+
+   @Override
+   public int writeBytes(ScatteringByteChannel in, int length) throws IOException {
+      return buffer.writeBytes(in, length);
+   }
+
+   @Override
+   public void writeBytes(org.jboss.netty.buffer.ChannelBuffer src, int srcIndex, int length) {
+      buffer.writeBytes(src, srcIndex, length);
+   }
+
+   @Override
+   public void writeBytes(byte[] src, int srcIndex, int length) {
+      buffer.writeBytes(src, srcIndex, length);
+   }
+
+   @Override
+   public void writeInt(int value) {
+      buffer.writeInt(value);
+   }
+
+   @Override
+   public void writeLong(long value) {
+      buffer.writeLong(value);
+   }
+
+   @Override
+   public void writeMedium(int value) {
+      buffer.writeMedium(value);
+   }
+
+   @Override
+   public void writeShort(short value) {
+      buffer.writeShort(value);
+   }
+
+   @Override
+   public void writeZero(int length) {
+      buffer.writeZero(length);
+   }
+
+   @Override
+   public int writerIndex() {
+      return buffer.writerIndex();
+   }
+
+   @Override
+   public void writerIndex(int writerIndex) {
+      buffer.writerIndex(writerIndex);
+   }
+
+}

Added: trunk/server/memcached/src/main/java/org/infinispan/server/core/netty/NettyChannelBuffers.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/core/netty/NettyChannelBuffers.java	                        (rev 0)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/core/netty/NettyChannelBuffers.java	2009-12-30 17:58:15 UTC (rev 1337)
@@ -0,0 +1,54 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat, Inc. and/or its affiliates, and
+ * individual contributors as indicated by the @author tags. See the
+ * copyright.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.server.core.netty;
+
+import org.infinispan.server.core.ChannelBuffer;
+import org.infinispan.server.core.ChannelBuffers;
+
+/**
+ * NettyChannelBuffers.
+ * 
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+public enum NettyChannelBuffers implements ChannelBuffers {
+   INSTANCE;
+
+   @Override
+   public ChannelBuffer wrappedBuffer(byte[] array) {
+      return new NettyChannelBuffer(org.jboss.netty.buffer.ChannelBuffers.wrappedBuffer(array));
+   }
+
+   @Override
+   public ChannelBuffer wrappedBuffer(ChannelBuffer... buffers) {
+      org.jboss.netty.buffer.ChannelBuffer[] nettyBuffers = new org.jboss.netty.buffer.ChannelBuffer[buffers.length];
+      for (int i =0; i < buffers.length; i++) {
+         nettyBuffers[i] = ((NettyChannelBuffer) buffers[i]).buffer;
+      }
+      return new NettyChannelBuffer(org.jboss.netty.buffer.ChannelBuffers.wrappedBuffer(nettyBuffers));
+   }
+
+   public static NettyChannelBuffers getInstance() {
+      return INSTANCE;
+   }
+}

Added: trunk/server/memcached/src/main/java/org/infinispan/server/core/netty/NettyChannelFuture.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/core/netty/NettyChannelFuture.java	                        (rev 0)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/core/netty/NettyChannelFuture.java	2009-12-30 17:58:15 UTC (rev 1337)
@@ -0,0 +1,102 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat, Inc. and/or its affiliates, and
+ * individual contributors as indicated by the @author tags. See the
+ * copyright.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.server.core.netty;
+
+import java.util.concurrent.TimeUnit;
+
+import org.infinispan.server.core.Channel;
+import org.infinispan.server.core.ChannelFuture;
+
+/**
+ * NettyChannelFuture.
+ * 
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+public class NettyChannelFuture implements ChannelFuture {
+   final org.jboss.netty.channel.ChannelFuture future;
+   final Channel ch;
+
+   public NettyChannelFuture(org.jboss.netty.channel.ChannelFuture future, Channel ch) {
+      this.future = future;
+      this.ch = ch;
+   }
+
+   @Override
+   public ChannelFuture await() throws InterruptedException {
+      future.await();
+      return this;
+   }
+
+   @Override
+   public boolean await(long timeout, TimeUnit unit) throws InterruptedException {
+      return future.await(timeout, unit);
+   }
+
+   @Override
+   public boolean await(long timeoutMillis) throws InterruptedException {
+      return future.await(timeoutMillis);
+   }
+
+   @Override
+   public ChannelFuture awaitUninterruptibly() {
+      future.awaitUninterruptibly();
+      return this;
+   }
+
+   @Override
+   public boolean awaitUninterruptibly(long timeout, TimeUnit unit) {
+      return future.awaitUninterruptibly(timeout, unit);
+   }
+
+   @Override
+   public boolean awaitUninterruptibly(long timeoutMillis) {
+      return future.awaitUninterruptibly(timeoutMillis);
+   }
+
+   @Override
+   public Channel getChannel() {
+      return ch;
+   }
+
+   @Override
+   public boolean isCancelled() {
+      return future.isCancelled();
+   }
+
+   @Override
+   public boolean isDone() {
+      return future.isDone();
+   }
+
+   @Override
+   public boolean setFailure(Throwable cause) {
+      return future.setFailure(cause);
+   }
+
+   @Override
+   public boolean setSuccess() {
+      return future.setSuccess();
+   }
+
+}

Added: trunk/server/memcached/src/main/java/org/infinispan/server/core/netty/NettyChannelHandlerContext.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/core/netty/NettyChannelHandlerContext.java	                        (rev 0)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/core/netty/NettyChannelHandlerContext.java	2009-12-30 17:58:15 UTC (rev 1337)
@@ -0,0 +1,52 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat, Inc. and/or its affiliates, and
+ * individual contributors as indicated by the @author tags. See the
+ * copyright.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.server.core.netty;
+
+import org.infinispan.server.core.Channel;
+import org.infinispan.server.core.ChannelBuffers;
+import org.infinispan.server.core.ChannelHandlerContext;
+
+/**
+ * NettyChannelHandlerContext.
+ * 
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+public class NettyChannelHandlerContext implements ChannelHandlerContext {
+   final org.jboss.netty.channel.ChannelHandlerContext ctx;
+   final Channel ch;
+
+   public NettyChannelHandlerContext(org.jboss.netty.channel.ChannelHandlerContext ctx) {
+      this.ctx = ctx;
+      this.ch = new NettyChannel(ctx.getChannel());
+   }
+
+   @Override
+   public Channel getChannel() {
+      return ch;
+   }
+
+   public ChannelBuffers getChannelBuffers() {
+      return NettyChannelBuffers.INSTANCE;
+   }
+}

Added: trunk/server/memcached/src/main/java/org/infinispan/server/core/netty/NettyChannelPipelineFactory.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/core/netty/NettyChannelPipelineFactory.java	                        (rev 0)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/core/netty/NettyChannelPipelineFactory.java	2009-12-30 17:58:15 UTC (rev 1337)
@@ -0,0 +1,55 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat, Inc. and/or its affiliates, and
+ * individual contributors as indicated by the @author tags. See the
+ * copyright.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.server.core.netty;
+
+import static org.jboss.netty.channel.Channels.pipeline;
+
+import org.jboss.netty.channel.ChannelHandler;
+import org.jboss.netty.channel.ChannelPipeline;
+import org.jboss.netty.channel.ChannelPipelineFactory;
+
+/**
+ * NettyChannelPipelineFactory.
+ * 
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+public class NettyChannelPipelineFactory implements ChannelPipelineFactory {
+   private final ChannelHandler decoder;
+   private final ChannelHandler handler;
+
+   public NettyChannelPipelineFactory(ChannelHandler decoder, ChannelHandler handler) {
+      this.decoder = decoder;
+      this.handler = handler;
+   }
+
+   @Override
+   public ChannelPipeline getPipeline() throws Exception {
+      // Create a default pipeline implementation.
+      ChannelPipeline pipeline = pipeline();
+      pipeline.addLast("decoder", decoder);
+      pipeline.addLast("handler", handler);
+      return pipeline;
+   }
+
+}

Added: trunk/server/memcached/src/main/java/org/infinispan/server/core/netty/NettyChannelUpstreamHandler.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/core/netty/NettyChannelUpstreamHandler.java	                        (rev 0)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/core/netty/NettyChannelUpstreamHandler.java	2009-12-30 17:58:15 UTC (rev 1337)
@@ -0,0 +1,57 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat, Inc. and/or its affiliates, and
+ * individual contributors as indicated by the @author tags. See the
+ * copyright.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.server.core.netty;
+
+import org.infinispan.CacheException;
+import org.infinispan.server.core.CommandHandler;
+import org.jboss.netty.channel.ChannelHandlerContext;
+import org.jboss.netty.channel.ChannelPipelineCoverage;
+import org.jboss.netty.channel.MessageEvent;
+import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
+
+/**
+ * NettyUpstreamHandler.
+ * 
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+ at ChannelPipelineCoverage("one")
+public class NettyChannelUpstreamHandler extends SimpleChannelUpstreamHandler {
+   final CommandHandler handler;
+
+   public NettyChannelUpstreamHandler(CommandHandler handler) {
+      this.handler = handler;
+   }
+   
+   @Override
+   public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
+      try {
+         handler.messageReceived(new NettyChannelHandlerContext(ctx), new NettyMessageEvent(e));
+      } catch (Exception ee) {
+         throw ee;
+      } catch (Throwable t) {
+         throw new CacheException(t);
+      }
+   }
+
+}

Added: trunk/server/memcached/src/main/java/org/infinispan/server/core/netty/NettyMessageEvent.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/core/netty/NettyMessageEvent.java	                        (rev 0)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/core/netty/NettyMessageEvent.java	2009-12-30 17:58:15 UTC (rev 1337)
@@ -0,0 +1,52 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat, Inc. and/or its affiliates, and
+ * individual contributors as indicated by the @author tags. See the
+ * copyright.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.server.core.netty;
+
+import java.net.SocketAddress;
+
+import org.infinispan.server.core.MessageEvent;
+
+/**
+ * NettyMessageEvent.
+ * 
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+public class NettyMessageEvent implements MessageEvent {
+   final org.jboss.netty.channel.MessageEvent event;
+
+   public NettyMessageEvent(org.jboss.netty.channel.MessageEvent event) {
+      this.event = event;
+   }
+
+   @Override
+   public Object getMessage() {
+      return event.getMessage();
+   }
+
+   @Override
+   public SocketAddress getRemoteAddress() {
+      return event.getRemoteAddress();
+   }
+
+}

Added: trunk/server/memcached/src/main/java/org/infinispan/server/core/netty/NettyServerBootstrap.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/core/netty/NettyServerBootstrap.java	                        (rev 0)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/core/netty/NettyServerBootstrap.java	2009-12-30 17:58:15 UTC (rev 1337)
@@ -0,0 +1,66 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat, Inc. and/or its affiliates, and
+ * individual contributors as indicated by the @author tags. See the
+ * copyright.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.server.core.netty;
+
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
+import java.util.concurrent.Executors;
+
+import org.jboss.netty.bootstrap.ServerBootstrap;
+import org.jboss.netty.channel.ChannelFactory;
+import org.jboss.netty.channel.ChannelPipelineFactory;
+import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
+
+/**
+ * NettyChannelFactory.
+ * 
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+public class NettyServerBootstrap implements org.infinispan.server.core.ServerBootstrap {
+   final ChannelPipelineFactory pipeline;
+   final SocketAddress address;
+   
+   public NettyServerBootstrap(ChannelPipelineFactory pipeline, SocketAddress address) {
+      this.pipeline = pipeline;
+      this.address = address;
+   }
+
+   @Override
+   public void start() {
+      ChannelFactory factory = new NioServerSocketChannelFactory(Executors.newCachedThreadPool(), Executors.newCachedThreadPool());
+      ServerBootstrap bootstrap = new ServerBootstrap(factory);
+      bootstrap.setPipelineFactory(pipeline);
+      bootstrap.bind(address);
+   }
+
+   @Override
+   public void stop() {
+      // TODO how to close shutdown the nettty server?
+   }
+
+   public static NettyServerBootstrap newNettyServerBootstrap(ChannelPipelineFactory pipeline, SocketAddress address) {
+      return new NettyServerBootstrap(pipeline, address);
+   }
+
+}

Added: trunk/server/memcached/src/main/java/org/infinispan/server/core/netty/memcached/NettyMemcachedDecoder.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/core/netty/memcached/NettyMemcachedDecoder.java	                        (rev 0)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/core/netty/memcached/NettyMemcachedDecoder.java	2009-12-30 17:58:15 UTC (rev 1337)
@@ -0,0 +1,148 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat, Inc. and/or its affiliates, and
+ * individual contributors as indicated by the @author tags. See the
+ * copyright.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.server.core.netty.memcached;
+
+import static org.infinispan.server.memcached.TextProtocolUtil.CR;
+import static org.infinispan.server.memcached.TextProtocolUtil.CRLF;
+import static org.infinispan.server.memcached.TextProtocolUtil.LF;
+import static org.jboss.netty.buffer.ChannelBuffers.wrappedBuffer;
+
+import java.io.IOException;
+import java.io.StreamCorruptedException;
+import java.util.concurrent.ScheduledExecutorService;
+
+import org.infinispan.Cache;
+import org.infinispan.server.core.Command;
+import org.infinispan.server.core.InterceptorChain;
+import org.infinispan.server.memcached.CommandFactory;
+import org.infinispan.server.memcached.Reply;
+import org.infinispan.server.memcached.StorageCommand;
+import org.infinispan.server.memcached.TextCommand;
+import org.infinispan.server.memcached.UnknownCommandException;
+import org.infinispan.util.logging.Log;
+import org.infinispan.util.logging.LogFactory;
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.jboss.netty.channel.Channel;
+import org.jboss.netty.channel.ChannelHandlerContext;
+import org.jboss.netty.channel.ExceptionEvent;
+import org.jboss.netty.handler.codec.replay.ReplayingDecoder;
+
+/**
+ * NettyMemcachedDecoder.
+ * 
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+public class NettyMemcachedDecoder extends ReplayingDecoder<NettyMemcachedDecoder.State> {
+   private static final Log log = LogFactory.getLog(NettyMemcachedDecoder.class);
+   
+   private final CommandFactory factory;
+   private volatile TextCommand command;
+
+   protected enum State {
+      READ_COMMAND, READ_UNSTRUCTURED_DATA;
+   }
+
+   public NettyMemcachedDecoder(Cache cache, InterceptorChain chain, ScheduledExecutorService scheduler) {
+      super(State.READ_COMMAND, true);
+      factory = new CommandFactory(cache, chain, scheduler);
+   }
+
+   @Override
+   protected Object decode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer, State state) throws Exception {
+      switch (state) {
+         case READ_COMMAND:
+            command = factory.createCommand(readLine(buffer));
+            if (command.getType().isStorage())
+               checkpoint(State.READ_UNSTRUCTURED_DATA);
+            else
+               return command;
+            break;
+         case READ_UNSTRUCTURED_DATA:
+            StorageCommand storageCmd = (StorageCommand) command;
+            byte[] data= new byte[storageCmd.getParams().getBytes()];
+            buffer.readBytes(data, 0, data.length);
+            byte next = buffer.readByte();
+            if (next == CR) {
+               next = buffer.readByte();
+               if (next == LF) {
+                  try {
+                     return reset(storageCmd.setData(data));
+                  } catch (IOException ioe) {
+                     checkpoint(State.READ_COMMAND);
+                     throw ioe;
+                  }
+               } else {
+                  throw new StreamCorruptedException("Expecting \r\n after data block");
+               }
+            } else {
+               throw new StreamCorruptedException("Expecting \r\n after data block");
+            }
+      }
+      return null;
+   }
+
+   @Override
+   public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception {
+      Throwable t = e.getCause();
+      log.error("Unexpected exception", t);
+      Channel ch = ctx.getChannel();
+      if (t instanceof UnknownCommandException) {
+         ch.write(wrappedBuffer(wrappedBuffer(Reply.ERROR.bytes()), wrappedBuffer(CRLF)));
+      } else if (t instanceof IOException) {
+         StringBuilder sb = new StringBuilder();
+         sb.append(Reply.CLIENT_ERROR).append(' ').append(t);
+         ch.write(wrappedBuffer(wrappedBuffer(sb.toString().getBytes()), wrappedBuffer(CRLF)));
+      } else {
+         StringBuilder sb = new StringBuilder();
+         sb.append(Reply.SERVER_ERROR).append(' ').append(t);
+         ch.write(wrappedBuffer(wrappedBuffer(sb.toString().getBytes()), wrappedBuffer(CRLF)));
+      }
+   }
+
+   private Object reset(Command c) {
+      this.command = null;
+      checkpoint(State.READ_COMMAND);
+      return c;
+  }
+
+   private String readLine(ChannelBuffer buffer) {
+      StringBuilder sb = new StringBuilder(64);
+      int lineLength = 0;
+      while (true) {
+         byte next = buffer.readByte();
+         if (next == CR) {
+            next = buffer.readByte();
+            if (next == LF) {
+               return sb.toString();
+            }
+         } else if (next == LF) {
+            return sb.toString();
+         } else {
+            lineLength++;
+            sb.append((char) next);
+         }
+      }
+   }
+
+}

Modified: trunk/server/memcached/src/main/java/org/infinispan/server/memcached/AbstractVisitor.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/memcached/AbstractVisitor.java	2009-12-29 20:45:06 UTC (rev 1336)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/memcached/AbstractVisitor.java	2009-12-30 17:58:15 UTC (rev 1337)
@@ -22,7 +22,7 @@
  */
 package org.infinispan.server.memcached;
 
-import org.jboss.netty.channel.Channel;
+import org.infinispan.server.core.ChannelHandlerContext;
 
 /**
  * CommandInterceptor.
@@ -30,84 +30,84 @@
  * @author Galder Zamarreño
  * @since 4.0
  */
-public abstract class AbstractVisitor implements Visitor {
+public abstract class AbstractVisitor implements TextProtocolVisitor {
 
    @Override
-   public Object visitAdd(Channel ch, AddCommand command) throws Exception {
-      return handleDefault(ch, command);
+   public Object visitAdd(ChannelHandlerContext ctx, AddCommand command) throws Throwable {
+      return handleDefault(ctx, command);
    }
 
    @Override
-   public Object visitAppend(Channel ch, AppendCommand command) throws Exception {
-      return handleDefault(ch, command);
+   public Object visitAppend(ChannelHandlerContext ctx, AppendCommand command) throws Throwable {
+      return handleDefault(ctx, command);
    }
 
    @Override
-   public Object visitCas(Channel ch, CasCommand command) throws Exception {
-      return handleDefault(ch, command);
+   public Object visitCas(ChannelHandlerContext ctx, CasCommand command) throws Throwable {
+      return handleDefault(ctx, command);
    }
 
    @Override
-   public Object visitDecrement(Channel ch, DecrementCommand command) throws Exception {
-      return handleDefault(ch, command);
+   public Object visitDecrement(ChannelHandlerContext ctx, DecrementCommand command) throws Throwable {
+      return handleDefault(ctx, command);
    }
 
    @Override
-   public Object visitDelete(Channel ch, DeleteCommand command) throws Exception {
-      return handleDefault(ch, command);
+   public Object visitDelete(ChannelHandlerContext ctx, DeleteCommand command) throws Throwable {
+      return handleDefault(ctx, command);
    }
 
    @Override
-   public Object visitGet(Channel ch, GetCommand command) throws Exception {
-      return handleDefault(ch, command);
+   public Object visitGet(ChannelHandlerContext ctx, GetCommand command) throws Throwable {
+      return handleDefault(ctx, command);
    }
 
    @Override
-   public Object visitGets(Channel ch, GetsCommand command) throws Exception {
-      return handleDefault(ch, command);
+   public Object visitGets(ChannelHandlerContext ctx, GetsCommand command) throws Throwable {
+      return handleDefault(ctx, command);
    }
 
    @Override
-   public Object visitIncrement(Channel ch, IncrementCommand command) throws Exception {
-      return handleDefault(ch, command);
+   public Object visitIncrement(ChannelHandlerContext ctx, IncrementCommand command) throws Throwable {
+      return handleDefault(ctx, command);
    }
 
    @Override
-   public Object visitPrepend(Channel ch, PrependCommand command) throws Exception {
-      return handleDefault(ch, command);
+   public Object visitPrepend(ChannelHandlerContext ctx, PrependCommand command) throws Throwable {
+      return handleDefault(ctx, command);
    }
 
    @Override
-   public Object visitReplace(Channel ch, ReplaceCommand command) throws Exception {
-      return handleDefault(ch, command);
+   public Object visitReplace(ChannelHandlerContext ctx, ReplaceCommand command) throws Throwable {
+      return handleDefault(ctx, command);
    }
 
    @Override
-   public Object visitSet(Channel ch, SetCommand command) throws Exception {
-      return handleDefault(ch, command);
+   public Object visitSet(ChannelHandlerContext ctx, SetCommand command) throws Throwable {
+      return handleDefault(ctx, command);
    }
 
    @Override
-   public Object visitStats(Channel ch, StatsCommand command) throws Exception {
-      return handleDefault(ch, command);
+   public Object visitStats(ChannelHandlerContext ctx, StatsCommand command) throws Throwable {
+      return handleDefault(ctx, command);
    }
 
    @Override
-   public Object visitFlushAll(Channel ch, FlushAllCommand command) throws Exception {
-      return handleDefault(ch, command);
+   public Object visitFlushAll(ChannelHandlerContext ctx, FlushAllCommand command) throws Throwable {
+      return handleDefault(ctx, command);
    }
 
    @Override
-   public Object visitVersion(Channel ch, VersionCommand command) throws Exception {
-      return handleDefault(ch, command);
+   public Object visitVersion(ChannelHandlerContext ctx, VersionCommand command) throws Throwable {
+      return handleDefault(ctx, command);
    }
 
    @Override
-   public Object visitQuit(Channel ch, QuitCommand command) throws Exception {
-      return handleDefault(ch, command);
+   public Object visitQuit(ChannelHandlerContext ctx, QuitCommand command) throws Throwable {
+      return handleDefault(ctx, command);
    }
 
-   protected Object handleDefault(Channel ch, Command command) throws Exception {
+   protected Object handleDefault(ChannelHandlerContext ctx, TextCommand command) throws Throwable {
       return null;
    }
 }

Modified: trunk/server/memcached/src/main/java/org/infinispan/server/memcached/AddCommand.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/memcached/AddCommand.java	2009-12-29 20:45:06 UTC (rev 1336)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/memcached/AddCommand.java	2009-12-30 17:58:15 UTC (rev 1337)
@@ -25,7 +25,7 @@
 import java.util.concurrent.TimeUnit;
 
 import org.infinispan.Cache;
-import org.jboss.netty.channel.Channel;
+import org.infinispan.server.core.ChannelHandlerContext;
 
 /**
  * AddCommand.
@@ -35,23 +35,23 @@
  */
 public class AddCommand extends SetCommand {
 
-   AddCommand(Cache cache, CommandType type, StorageParameters params, byte[] data) {
+   AddCommand(Cache<String, Value> cache, CommandType type, StorageParameters params, byte[] data) {
       super(cache, type, params, data);
    }
 
    @Override
-   public Object acceptVisitor(Channel ch, CommandInterceptor next) throws Exception {
-      return next.visitAdd(ch, this);
+   public Object acceptVisitor(ChannelHandlerContext ctx, TextProtocolVisitor next) throws Throwable {
+      return next.visitAdd(ctx, this);
    }
 
    @Override
    protected Reply put(String key, int flags, byte[] data, long expiry) {
-      Value value = new Value(flags, data);
-      Object prev = cache.putIfAbsent(key, value, expiry, TimeUnit.MILLISECONDS);
+      Value value = new Value(flags, data, System.currentTimeMillis());
+      Value prev = cache.putIfAbsent(key, value, expiry, TimeUnit.MILLISECONDS);
       return reply(prev);
    }
 
-   private Reply reply(Object prev) {
+   private Reply reply(Value prev) {
       if (prev == null)
          return Reply.STORED;
       else 

Modified: trunk/server/memcached/src/main/java/org/infinispan/server/memcached/AppendCommand.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/memcached/AppendCommand.java	2009-12-29 20:45:06 UTC (rev 1336)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/memcached/AppendCommand.java	2009-12-30 17:58:15 UTC (rev 1337)
@@ -23,7 +23,7 @@
 package org.infinispan.server.memcached;
 
 import org.infinispan.Cache;
-import org.jboss.netty.channel.Channel;
+import org.infinispan.server.core.ChannelHandlerContext;
 
 /**
  * AppendCommand.
@@ -33,26 +33,25 @@
  */
 public class AppendCommand extends SetCommand {
 
-   AppendCommand(Cache cache, StorageParameters params, byte[] data) {
+   AppendCommand(Cache<String, Value> cache, StorageParameters params, byte[] data) {
       super(cache, CommandType.APPEND, params, data);
    }
 
-   AppendCommand(Cache cache, CommandType type, StorageParameters params, byte[] data) {
+   AppendCommand(Cache<String, Value> cache, CommandType type, StorageParameters params, byte[] data) {
       super(cache, type, params, data);
    }
 
    @Override
-   public Object acceptVisitor(Channel ch, CommandInterceptor next) throws Exception {
-      return next.visitAppend(ch, this);
+   public Object acceptVisitor(ChannelHandlerContext ctx, TextProtocolVisitor next) throws Throwable {
+      return next.visitAppend(ctx, this);
    }
 
    @Override
    protected Reply put(String key, int flags, byte[] data) {
-      Value append = new Value(flags, data);
-      Value current = (Value) cache.get(key);
+      Value current = cache.get(key);
       if (current != null) {
-         byte[] concatenated = concat(current.getData(), append.getData());
-         Value next = new Value(current.getFlags(), concatenated);
+         byte[] concatenated = concat(current.getData(), data);
+         Value next = new Value(current.getFlags(), concatenated, current.getCas() + 1);
          boolean replaced = cache.replace(key, current, next);
          if (replaced)
             return Reply.STORED;

Modified: trunk/server/memcached/src/main/java/org/infinispan/server/memcached/CallInterceptor.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/memcached/CallInterceptor.java	2009-12-29 20:45:06 UTC (rev 1336)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/memcached/CallInterceptor.java	2009-12-30 17:58:15 UTC (rev 1337)
@@ -22,7 +22,7 @@
  */
 package org.infinispan.server.memcached;
 
-import org.jboss.netty.channel.Channel;
+import org.infinispan.server.core.ChannelHandlerContext;
 
 /**
  * CallInterceptor.
@@ -30,14 +30,14 @@
  * @author Galder Zamarreño
  * @since 4.0
  */
-public class CallInterceptor extends CommandInterceptor {
+public class CallInterceptor extends TextCommandInterceptorImpl {
 
-   public CallInterceptor(CommandInterceptor next) {
+   public CallInterceptor(TextCommandInterceptor next) {
       super(next);
    }
 
    @Override
-   protected Object handleDefault(Channel ch, Command command) throws Exception {
-      return command.perform(ch);
+   protected Object handleDefault(ChannelHandlerContext ctx, TextCommand command) throws Throwable {
+      return command.perform(ctx);
    }
 }

Modified: trunk/server/memcached/src/main/java/org/infinispan/server/memcached/CasCommand.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/memcached/CasCommand.java	2009-12-29 20:45:06 UTC (rev 1336)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/memcached/CasCommand.java	2009-12-30 17:58:15 UTC (rev 1337)
@@ -25,7 +25,8 @@
 import java.io.IOException;
 
 import org.infinispan.Cache;
-import org.jboss.netty.channel.Channel;
+import org.infinispan.server.core.ChannelHandlerContext;
+import org.infinispan.server.core.Command;
 
 /**
  * CasCommand.
@@ -42,8 +43,8 @@
    }
 
    @Override
-   public Object acceptVisitor(Channel ch, CommandInterceptor next) throws Exception {
-      return next.visitCas(ch, this);
+   public Object acceptVisitor(ChannelHandlerContext ctx, TextProtocolVisitor next) throws Throwable {
+      return next.visitCas(ctx, this);
    }
 
    @Override
@@ -56,7 +57,7 @@
       Value old = (Value) cache.get(key);
       if (old != null) {
          if (old.getCas() == cas) {
-            Value value = new Value(flags, data);
+            Value value = new Value(flags, data, old.getCas() + 1);
             boolean replaced = cache.replace(key, old, value);
             if (replaced)
                return Reply.STORED;

Deleted: trunk/server/memcached/src/main/java/org/infinispan/server/memcached/Command.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/memcached/Command.java	2009-12-29 20:45:06 UTC (rev 1336)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/memcached/Command.java	2009-12-30 17:58:15 UTC (rev 1337)
@@ -1,40 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2009, Red Hat, Inc. and/or its affiliates, and
- * individual contributors as indicated by the @author tags. See the
- * copyright.txt file in the distribution for a full listing of
- * individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.infinispan.server.memcached;
-
-import org.jboss.netty.channel.Channel;
-
-/**
- * Command.
- * 
- * @author Galder Zamarreño
- * @since 4.0
- */
-public interface Command {
-
-   Object perform(Channel ch) throws Exception;
-   
-   Object acceptVisitor(Channel ch, CommandInterceptor next) throws Exception;
-
-   CommandType getType();
-}

Modified: trunk/server/memcached/src/main/java/org/infinispan/server/memcached/CommandFactory.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/memcached/CommandFactory.java	2009-12-29 20:45:06 UTC (rev 1336)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/memcached/CommandFactory.java	2009-12-30 17:58:15 UTC (rev 1337)
@@ -28,17 +28,15 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
 import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
 
 import org.infinispan.Cache;
 import org.infinispan.util.logging.Log;
 import org.infinispan.util.logging.LogFactory;
 import org.jboss.util.NotImplementedException;
 
+import org.infinispan.server.core.InterceptorChain;
+
 /**
  * CommandFactory.
  * 
@@ -58,7 +56,7 @@
       this.scheduler = scheduler;
    }
 
-   public Command createCommand(String line) throws IOException {
+   public TextCommand createCommand(String line) throws IOException {
       if (log.isTraceEnabled()) log.trace("Command line: " + line);
       String[] args = line.trim().split(" +");
 

Deleted: trunk/server/memcached/src/main/java/org/infinispan/server/memcached/CommandInterceptor.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/memcached/CommandInterceptor.java	2009-12-29 20:45:06 UTC (rev 1336)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/memcached/CommandInterceptor.java	2009-12-30 17:58:15 UTC (rev 1337)
@@ -1,53 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2009, Red Hat, Inc. and/or its affiliates, and
- * individual contributors as indicated by the @author tags. See the
- * copyright.txt file in the distribution for a full listing of
- * individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.infinispan.server.memcached;
-
-import org.jboss.netty.channel.Channel;
-
-
-/**
- * CommandInterceptor.
- * 
- * @author Galder Zamarreño
- * @since 4.0
- */
-public class CommandInterceptor extends AbstractVisitor {
-   private final CommandInterceptor next;
-   
-   public CommandInterceptor(CommandInterceptor next) {
-      this.next = next;
-   }
-
-   public CommandInterceptor getNext() {
-      return next;
-   }
-
-   public final Object invokeNextInterceptor(Channel ch, Command command) throws Exception {
-      return command.acceptVisitor(ch, next);
-   }
-
-   protected Object handleDefault(Channel ch, Command command) throws Exception {
-      return invokeNextInterceptor(ch, command);
-   }
-
-}

Modified: trunk/server/memcached/src/main/java/org/infinispan/server/memcached/CommandType.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/memcached/CommandType.java	2009-12-29 20:45:06 UTC (rev 1336)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/memcached/CommandType.java	2009-12-30 17:58:15 UTC (rev 1337)
@@ -23,7 +23,6 @@
 package org.infinispan.server.memcached;
 
 import java.io.IOException;
-import java.io.StreamCorruptedException;
 
 /**
  * Command.
@@ -31,7 +30,7 @@
  * @author Galder Zamarreño
  * @since 4.0
  */
-enum CommandType {
+public enum CommandType {
    SET, ADD, REPLACE, APPEND, PREPEND, CAS,
    GET, GETS,
    DELETE,
@@ -42,7 +41,7 @@
    QUIT
    ;
    
-   boolean isStorage() {
+   public boolean isStorage() {
       switch(this) {
          case SET:
          case ADD:

Modified: trunk/server/memcached/src/main/java/org/infinispan/server/memcached/DecrementCommand.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/memcached/DecrementCommand.java	2009-12-29 20:45:06 UTC (rev 1336)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/memcached/DecrementCommand.java	2009-12-30 17:58:15 UTC (rev 1337)
@@ -25,9 +25,9 @@
 import java.math.BigInteger;
 
 import org.infinispan.Cache;
+import org.infinispan.server.core.ChannelHandlerContext;
 import org.infinispan.util.logging.Log;
 import org.infinispan.util.logging.LogFactory;
-import org.jboss.netty.channel.Channel;
 
 /**
  * DecrementCommand.
@@ -43,8 +43,8 @@
    }
 
    @Override
-   public Object acceptVisitor(Channel ch, CommandInterceptor next) throws Exception {
-      return next.visitDecrement(ch, this);
+   public Object acceptVisitor(ChannelHandlerContext ctx, TextProtocolVisitor next) throws Throwable {
+      return next.visitDecrement(ctx, this);
    }
 
    @Override

Modified: trunk/server/memcached/src/main/java/org/infinispan/server/memcached/DeleteCommand.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/memcached/DeleteCommand.java	2009-12-29 20:45:06 UTC (rev 1336)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/memcached/DeleteCommand.java	2009-12-30 17:58:15 UTC (rev 1337)
@@ -23,13 +23,11 @@
 package org.infinispan.server.memcached;
 
 import static org.infinispan.server.memcached.TextProtocolUtil.CRLF;
-import static org.jboss.netty.buffer.ChannelBuffers.wrappedBuffer;
 
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.Delayed;
-
 import org.infinispan.Cache;
-import org.jboss.netty.channel.Channel;
+import org.infinispan.server.core.Channel;
+import org.infinispan.server.core.ChannelBuffers;
+import org.infinispan.server.core.ChannelHandlerContext;
 
 /**
  * DeleteCommand.
@@ -37,7 +35,7 @@
  * @author Galder Zamarreño
  * @since 4.0
  */
-public class DeleteCommand implements Command {
+public class DeleteCommand implements TextCommand {
 
    final Cache cache;
    final String key;
@@ -53,17 +51,19 @@
    }
 
    @Override
-   public Object acceptVisitor(Channel ch, CommandInterceptor next) throws Exception {
-      return next.visitDelete(ch, this);
+   public Object acceptVisitor(ChannelHandlerContext ctx, TextProtocolVisitor next) throws Throwable {
+      return next.visitDelete(ctx, this);
    }
 
    @Override
-   public Object perform(Channel ch) throws Exception {
+   public Object perform(ChannelHandlerContext ctx) throws Throwable {
+      Channel ch = ctx.getChannel();
       Reply reply;
       Object prev = cache.remove(key);
       reply = reply(prev);
-      ch.write(wrappedBuffer(wrappedBuffer(reply.bytes()), wrappedBuffer(CRLF)));
-      return null;
+      ChannelBuffers buffers = ctx.getChannelBuffers();
+      ch.write(buffers.wrappedBuffer(buffers.wrappedBuffer(reply.bytes()), buffers.wrappedBuffer(CRLF)));
+      return reply;
    }
 
    private Reply reply(Object prev) {

Deleted: trunk/server/memcached/src/main/java/org/infinispan/server/memcached/DeleteDelayed.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/memcached/DeleteDelayed.java	2009-12-29 20:45:06 UTC (rev 1336)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/memcached/DeleteDelayed.java	2009-12-30 17:58:15 UTC (rev 1337)
@@ -1,61 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2009, Red Hat, Inc. and/or its affiliates, and
- * individual contributors as indicated by the @author tags. See the
- * copyright.txt file in the distribution for a full listing of
- * individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.infinispan.server.memcached;
-
-import java.util.concurrent.BlockingQueue;
-
-import org.infinispan.Cache;
-import org.infinispan.util.logging.Log;
-import org.infinispan.util.logging.LogFactory;
-
-/**
- * DelayedDelete.
- * 
- * @author Galder Zamarreño
- * @since 4.0
- * @deprecated No longer in memcached spec: http://github.com/memcached/memcached/blob/master/doc/protocol.txt
- */
- at Deprecated
-public class DeleteDelayed implements Runnable {
-   private static final Log log = LogFactory.getLog(DeleteDelayed.class);
-
-   private final Cache cache;
-   private final BlockingQueue<DeleteDelayedEntry> queue;
-
-   DeleteDelayed(Cache cache, BlockingQueue<DeleteDelayedEntry> queue) {
-      this.queue = queue;
-      this.cache = cache;
-   }
-
-   @Override
-   public void run() {
-      try {
-         while (!Thread.currentThread().isInterrupted()) {
-            DeleteDelayedEntry entry = queue.take();
-            cache.remove(entry.key);
-         }
-      } catch (InterruptedException e) {
-         log.debug("Interrupted, so allow thread to exit"); /*  Allow thread to exit  */
-      }
-   }
-}

Deleted: trunk/server/memcached/src/main/java/org/infinispan/server/memcached/DeleteDelayedEntry.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/memcached/DeleteDelayedEntry.java	2009-12-29 20:45:06 UTC (rev 1336)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/memcached/DeleteDelayedEntry.java	2009-12-30 17:58:15 UTC (rev 1337)
@@ -1,70 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2009, Red Hat, Inc. and/or its affiliates, and
- * individual contributors as indicated by the @author tags. See the
- * copyright.txt file in the distribution for a full listing of
- * individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.infinispan.server.memcached;
-
-import java.util.concurrent.Delayed;
-import java.util.concurrent.TimeUnit;
-
-/**
- * DelayedDeleteEntry.
- * 
- * @author Galder Zamarreño
- * @since 4.0
- * @deprecated No longer in memcached spec: http://github.com/memcached/memcached/blob/master/doc/protocol.txt
- */
- at Deprecated
-public class DeleteDelayedEntry implements Delayed {
-
-   final String key;
-   private final long time;
-   private final boolean isUnix;
-
-   DeleteDelayedEntry(String key, long time) {
-      this.time = time;
-      this.key = key;
-      this.isUnix = time > TextProtocolUtil.SECONDS_IN_A_MONTH;
-   }
-
-   @Override
-   public long getDelay(TimeUnit unit) {
-      long now = TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis());
-      return unit.convert(time - now, TimeUnit.SECONDS);
-   }
-
-   @Override
-   public int compareTo(Delayed o) {
-      if (o == this)
-         return 0;
-
-      if (o instanceof DeleteDelayedEntry) {
-         DeleteDelayedEntry x = (DeleteDelayedEntry) o;
-         long diff = time - x.time;
-         if (diff < 0) return -1;
-         else if (diff > 0) return 1;
-         else return 0;
-      } else {
-         throw new ClassCastException(o.getClass() + " is not of type " + DeleteDelayedEntry.class);
-      }
-   }
-
-}

Modified: trunk/server/memcached/src/main/java/org/infinispan/server/memcached/FlushAllCommand.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/memcached/FlushAllCommand.java	2009-12-29 20:45:06 UTC (rev 1336)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/memcached/FlushAllCommand.java	2009-12-30 17:58:15 UTC (rev 1337)
@@ -24,14 +24,15 @@
 
 import static org.infinispan.server.memcached.Reply.OK;
 import static org.infinispan.server.memcached.TextProtocolUtil.CRLF;
-import static org.jboss.netty.buffer.ChannelBuffers.wrappedBuffer;
 
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.TimeUnit;
 
 import org.infinispan.Cache;
 import org.infinispan.context.Flag;
-import org.jboss.netty.channel.Channel;
+import org.infinispan.server.core.Channel;
+import org.infinispan.server.core.ChannelBuffers;
+import org.infinispan.server.core.ChannelHandlerContext;
 
 /**
  * FlushAllCommand.
@@ -39,7 +40,7 @@
  * @author Galder Zamarreño
  * @since 4.0
  */
-public class FlushAllCommand implements Command {
+public class FlushAllCommand implements TextCommand {
    final Cache cache;
    final long delay;
    final ScheduledExecutorService scheduler;
@@ -51,8 +52,8 @@
    }
 
    @Override
-   public Object acceptVisitor(Channel ch, CommandInterceptor next) throws Exception {
-      return next.visitFlushAll(ch, this);
+   public Object acceptVisitor(ChannelHandlerContext ctx, TextProtocolVisitor next) throws Throwable {
+      return next.visitFlushAll(ctx, this);
    }
 
    @Override
@@ -61,14 +62,16 @@
    }
 
    @Override
-   public Object perform(Channel ch) throws Exception {
+   public Object perform(ChannelHandlerContext ctx) throws Throwable {
+      Channel ch = ctx.getChannel();
       if (delay == 0) {
          cache.getAdvancedCache().withFlags(Flag.CACHE_MODE_LOCAL, Flag.SKIP_CACHE_STORE).clear();
       } else {
          scheduler.schedule(new FlushAllDelayed(cache), delay, TimeUnit.SECONDS);
       }
-      ch.write(wrappedBuffer(wrappedBuffer(OK.toString().getBytes()), wrappedBuffer(CRLF)));
-      return null;
+      ChannelBuffers buffers = ctx.getChannelBuffers();
+      ch.write(buffers.wrappedBuffer(buffers.wrappedBuffer(OK.bytes()), buffers.wrappedBuffer(CRLF)));
+      return OK;
    }
 
    public static FlushAllCommand newFlushAllCommand(Cache cache, long delay, ScheduledExecutorService scheduler) {

Modified: trunk/server/memcached/src/main/java/org/infinispan/server/memcached/GetCommand.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/memcached/GetCommand.java	2009-12-29 20:45:06 UTC (rev 1336)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/memcached/GetCommand.java	2009-12-30 17:58:15 UTC (rev 1337)
@@ -23,11 +23,12 @@
 package org.infinispan.server.memcached;
 
 import org.infinispan.Cache;
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.jboss.netty.channel.Channel;
+import org.infinispan.server.core.Channel;
+import org.infinispan.server.core.ChannelBuffer;
+import org.infinispan.server.core.ChannelBuffers;
+import org.infinispan.server.core.ChannelHandlerContext;
 
 import static org.infinispan.server.memcached.TextProtocolUtil.CRLF;
-import static org.jboss.netty.buffer.ChannelBuffers.*;
 import static org.infinispan.server.memcached.Reply.VALUE;
 import static org.infinispan.server.memcached.Reply.END;
 
@@ -39,30 +40,32 @@
  */
 public class GetCommand extends RetrievalCommand {
 
-   GetCommand(Cache cache, CommandType type, RetrievalParameters params) {
+   GetCommand(Cache<String, Value> cache, CommandType type, RetrievalParameters params) {
       super(cache, type, params);
    }
 
    @Override
-   public Object acceptVisitor(Channel ch, CommandInterceptor next) throws Exception {
-      return next.visitGet(ch, this);
+   public Object acceptVisitor(ChannelHandlerContext ctx, TextProtocolVisitor next) throws Throwable {
+      return next.visitGet(ctx, this);
    }
    
    @Override
-   public Object perform(Channel ch) throws Exception {
+   public Object perform(ChannelHandlerContext ctx) throws Throwable {
+      Channel ch = ctx.getChannel();
       ChannelBuffer buffer;
+      ChannelBuffers buffers = ctx.getChannelBuffers();
       for (String key : params.keys) {
-         Value value = (Value) cache.get(key);
+         Value value = cache.get(key);
          if (value != null) {
             StringBuilder sb = constructValue(key, value);
-            buffer = wrappedBuffer(wrappedBuffer(sb.toString().getBytes()), wrappedBuffer(CRLF),
-                     wrappedBuffer(value.getData()), wrappedBuffer(CRLF));
+            buffer = buffers.wrappedBuffer(buffers.wrappedBuffer(sb.toString().getBytes()), buffers.wrappedBuffer(CRLF),
+                     buffers.wrappedBuffer(value.getData()), buffers.wrappedBuffer(CRLF));
             ch.write(buffer);
          }
       }
       
-      ch.write(wrappedBuffer(wrappedBuffer(END.toString().getBytes()), wrappedBuffer(CRLF)));
-      return null;
+      ch.write(buffers.wrappedBuffer(buffers.wrappedBuffer(END.bytes()), buffers.wrappedBuffer(CRLF)));
+      return END;
    }
 
    protected StringBuilder constructValue(String key, Value value) {

Modified: trunk/server/memcached/src/main/java/org/infinispan/server/memcached/IncrementCommand.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/memcached/IncrementCommand.java	2009-12-29 20:45:06 UTC (rev 1336)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/memcached/IncrementCommand.java	2009-12-30 17:58:15 UTC (rev 1337)
@@ -25,9 +25,9 @@
 import java.math.BigInteger;
 
 import org.infinispan.Cache;
+import org.infinispan.server.core.ChannelHandlerContext;
 import org.infinispan.util.logging.Log;
 import org.infinispan.util.logging.LogFactory;
-import org.jboss.netty.channel.Channel;
 
 /**
  * IncrementCommand.
@@ -43,8 +43,8 @@
    }
 
    @Override
-   public Object acceptVisitor(Channel ch, CommandInterceptor next) throws Exception {
-      return next.visitIncrement(ch, this);
+   public Object acceptVisitor(ChannelHandlerContext ctx, TextProtocolVisitor next) throws Throwable {
+      return next.visitIncrement(ctx, this);
    }
 
    @Override

Modified: trunk/server/memcached/src/main/java/org/infinispan/server/memcached/InterceptorChain.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/memcached/InterceptorChain.java	2009-12-29 20:45:06 UTC (rev 1336)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/memcached/InterceptorChain.java	2009-12-30 17:58:15 UTC (rev 1337)
@@ -27,7 +27,8 @@
 import java.util.LinkedList;
 import java.util.List;
 
-import org.jboss.netty.channel.Channel;
+import org.infinispan.server.core.ChannelHandlerContext;
+import org.infinispan.server.core.CommandInterceptor;
 
 /**
  * InterceptorChain.
@@ -37,14 +38,14 @@
  */
 public class InterceptorChain {
 
-   private final CommandInterceptor firstInChain;
+   private final TextCommandInterceptor firstInChain;
 
-   public InterceptorChain(CommandInterceptor firstInChain) {
+   public InterceptorChain(TextCommandInterceptor firstInChain) {
       this.firstInChain = firstInChain;
    }
 
-   public Object invoke(Channel ch, Command command) throws Exception {
-      return command.acceptVisitor(ch, firstInChain);
+   public Object invoke(ChannelHandlerContext ctx, TextCommand command) throws Throwable {
+      return command.acceptVisitor(ctx, firstInChain);
    }
 
    public List<CommandInterceptor> getInterceptorsWhichExtend(Class<? extends CommandInterceptor> interceptorClass) {
@@ -62,7 +63,7 @@
     * Returns an unmofiable list with all the interceptors in sequence. If first in chain is null an empty list is
     * returned.
     */
-   public List<CommandInterceptor> asList() {
+   private List<CommandInterceptor> asList() {
       if (firstInChain == null) return Collections.emptyList();
 
       List<CommandInterceptor> retval = new LinkedList<CommandInterceptor>();
@@ -74,4 +75,5 @@
       while (tmp != null);
       return Collections.unmodifiableList(retval);
    }
+
 }

Deleted: trunk/server/memcached/src/main/java/org/infinispan/server/memcached/InterceptorChainFactory.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/memcached/InterceptorChainFactory.java	2009-12-29 20:45:06 UTC (rev 1336)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/memcached/InterceptorChainFactory.java	2009-12-30 17:58:15 UTC (rev 1337)
@@ -1,57 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2009, Red Hat, Inc. and/or its affiliates, and
- * individual contributors as indicated by the @author tags. See the
- * copyright.txt file in the distribution for a full listing of
- * individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.infinispan.server.memcached;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.infinispan.Cache;
-
-/**
- * InterceptorChainFactory.
- * 
- * @author Galder Zamarreño
- * @since 4.0
- */
-public class InterceptorChainFactory {
-   final boolean statsEnabled;
-   
-   private InterceptorChainFactory(Cache cache) {
-      statsEnabled = cache.getConfiguration().isExposeJmxStatistics();
-   }
-
-   public InterceptorChain buildInterceptorChain() {
-      CommandInterceptor first;
-      if (statsEnabled) {
-         first = new StatsInterceptor(new CallInterceptor(null));
-      } else {
-         first = new CallInterceptor(null);
-      }
-      
-      return new InterceptorChain(first);
-   }
-
-   public static InterceptorChainFactory getInstance(Cache cache) {
-      return new InterceptorChainFactory(cache);
-   }
-}

Modified: trunk/server/memcached/src/main/java/org/infinispan/server/memcached/MemcachedStats.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/memcached/MemcachedStats.java	2009-12-29 20:45:06 UTC (rev 1336)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/memcached/MemcachedStats.java	2009-12-30 17:58:15 UTC (rev 1337)
@@ -22,8 +22,6 @@
  */
 package org.infinispan.server.memcached;
 
-import org.infinispan.stats.Stats;
-
 /**
  * MemcachedStats.
  * 

Modified: trunk/server/memcached/src/main/java/org/infinispan/server/memcached/MemcachedStatsImpl.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/memcached/MemcachedStatsImpl.java	2009-12-29 20:45:06 UTC (rev 1336)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/memcached/MemcachedStatsImpl.java	2009-12-30 17:58:15 UTC (rev 1337)
@@ -25,7 +25,8 @@
 import java.util.List;
 
 import org.infinispan.stats.Stats;
-import org.infinispan.server.memcached.InterceptorChain;
+import org.infinispan.server.core.CommandInterceptor;
+import org.infinispan.server.core.InterceptorChain;
 
 /**
  * MemcachedStats.

Modified: trunk/server/memcached/src/main/java/org/infinispan/server/memcached/MemcachedTextServer.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/memcached/MemcachedTextServer.java	2009-12-29 20:45:06 UTC (rev 1336)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/memcached/MemcachedTextServer.java	2009-12-30 17:58:15 UTC (rev 1337)
@@ -23,17 +23,17 @@
 package org.infinispan.server.memcached;
 
 import java.net.InetSocketAddress;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.DelayQueue;
-import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ScheduledExecutorService;
 
 import org.infinispan.Cache;
 import org.infinispan.manager.CacheManager;
-import org.jboss.netty.bootstrap.ServerBootstrap;
-import org.jboss.netty.channel.ChannelFactory;
-import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
+import org.infinispan.server.core.ServerBootstrap;
+import org.infinispan.server.core.netty.NettyChannelPipelineFactory;
+import org.infinispan.server.core.netty.NettyChannelUpstreamHandler;
+import org.infinispan.server.core.netty.NettyServerBootstrap;
+import org.infinispan.server.core.netty.memcached.NettyMemcachedDecoder;
+import org.infinispan.server.core.InterceptorChain;
 
 /**
  * TextServer.
@@ -45,6 +45,7 @@
    private final CacheManager manager;
    private final int port;
    private final ScheduledExecutorService scheduler;
+   private ServerBootstrap bootstrap;
    
    public MemcachedTextServer(CacheManager manager, int port) {
       this.manager = manager;
@@ -60,15 +61,17 @@
       // Configure Infinispan Cache instance
       Cache cache = manager.getCache();
 
-      // Configure the server.
-      ChannelFactory factory = new NioServerSocketChannelFactory(Executors.newCachedThreadPool(), Executors.newCachedThreadPool());
-      ServerBootstrap bootstrap = new ServerBootstrap(factory);
-      InterceptorChain chain = InterceptorChainFactory.getInstance(cache).buildInterceptorChain();
-      bootstrap.setPipelineFactory(new TextProtocolPipelineFactory(cache, chain, scheduler));
-      bootstrap.bind(new InetSocketAddress(port));
+      InterceptorChain chain = TextProtocolInterceptorChainFactory.getInstance(cache).buildInterceptorChain();
+      NettyMemcachedDecoder decoder = new NettyMemcachedDecoder(cache, chain, scheduler);
+      TextCommandHandler commandHandler = new TextCommandHandler(cache, chain);
+      NettyChannelUpstreamHandler handler = new NettyChannelUpstreamHandler(commandHandler);
+      NettyChannelPipelineFactory pipelineFactory = new NettyChannelPipelineFactory(decoder, handler);
+      bootstrap = new NettyServerBootstrap(pipelineFactory, new InetSocketAddress(port));
+      bootstrap.start();
    }
 
    public void stop() {
+      bootstrap.stop();
       manager.stop();
       scheduler.shutdown();
    }

Modified: trunk/server/memcached/src/main/java/org/infinispan/server/memcached/NumericCommand.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/memcached/NumericCommand.java	2009-12-29 20:45:06 UTC (rev 1336)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/memcached/NumericCommand.java	2009-12-30 17:58:15 UTC (rev 1337)
@@ -23,7 +23,6 @@
 package org.infinispan.server.memcached;
 
 import static org.infinispan.server.memcached.TextProtocolUtil.CRLF;
-import static org.jboss.netty.buffer.ChannelBuffers.wrappedBuffer;
 
 import java.io.IOException;
 import java.io.StreamCorruptedException;
@@ -33,7 +32,9 @@
 import org.infinispan.CacheException;
 import org.infinispan.util.logging.Log;
 import org.infinispan.util.logging.LogFactory;
-import org.jboss.netty.channel.Channel;
+import org.infinispan.server.core.ChannelBuffers;
+import org.infinispan.server.core.ChannelHandlerContext;
+import org.infinispan.server.core.Channel;
 
 /**
  * NumericCommand.
@@ -41,7 +42,7 @@
  * @author Galder Zamarreño
  * @since 4.0
  */
-public abstract class NumericCommand implements Command {
+public abstract class NumericCommand implements TextCommand {
    private static final Log log = LogFactory.getLog(NumericCommand.class);
    final Cache cache;
    private final CommandType type;
@@ -60,29 +61,31 @@
    }
 
    @Override
-   public Object perform(Channel ch) throws Exception {
+   public Object perform(ChannelHandlerContext ctx) throws Throwable {
+      Channel ch = ctx.getChannel();
+      ChannelBuffers buffers = ctx.getChannelBuffers();
       Value old = (Value) cache.get(key);
       if (old != null) {
          BigInteger oldBigInt = old.getData().length == 0 ? BigInteger.valueOf(0) : new BigInteger(old.getData());
          BigInteger newBigInt = operate(oldBigInt, value);
          byte[] newData = newBigInt.toByteArray();
-         Value curr = new Value(old.getFlags(), newData);
+         Value curr = new Value(old.getFlags(), newData, old.getCas() + 1);
          boolean replaced = cache.replace(key, old, curr);
          if (replaced) {
-            ch.write(wrappedBuffer(wrappedBuffer(newBigInt.toString().getBytes()), wrappedBuffer(CRLF)));
+            ch.write(buffers.wrappedBuffer(buffers.wrappedBuffer(newBigInt.toString().getBytes()), buffers.wrappedBuffer(CRLF)));
          } else {
             throw new CacheException("Value modified since we retrieved from the cache, old value was " + oldBigInt);
          }
          return curr;
       } else {
-         ch.write(wrappedBuffer(wrappedBuffer(Reply.NOT_FOUND.bytes()), wrappedBuffer(CRLF)));
-         return null;
+         ch.write(buffers.wrappedBuffer(buffers.wrappedBuffer(Reply.NOT_FOUND.bytes()), buffers.wrappedBuffer(CRLF)));
+         return Reply.NOT_FOUND;
       }
    }
 
    protected abstract BigInteger operate(BigInteger oldValue, BigInteger newValue);
 
-   public static Command newNumericCommand(Cache cache, CommandType type, String key, BigInteger value) throws IOException {
+   public static TextCommand newNumericCommand(Cache cache, CommandType type, String key, BigInteger value) throws IOException {
       switch(type) {
          case INCR: return new IncrementCommand(cache, type, key, value);
          case DECR: return new DecrementCommand(cache, type, key, value);

Modified: trunk/server/memcached/src/main/java/org/infinispan/server/memcached/PrependCommand.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/memcached/PrependCommand.java	2009-12-29 20:45:06 UTC (rev 1336)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/memcached/PrependCommand.java	2009-12-30 17:58:15 UTC (rev 1337)
@@ -23,7 +23,7 @@
 package org.infinispan.server.memcached;
 
 import org.infinispan.Cache;
-import org.jboss.netty.channel.Channel;
+import org.infinispan.server.core.ChannelHandlerContext;
 
 /**
  * PrependCommand.
@@ -38,8 +38,8 @@
    }
 
    @Override
-   public Object acceptVisitor(Channel ch, CommandInterceptor next) throws Exception {
-      return next.visitPrepend(ch, this);
+   public Object acceptVisitor(ChannelHandlerContext ctx, TextProtocolVisitor next) throws Throwable {
+      return next.visitPrepend(ctx, this);
    }
 
    @Override

Modified: trunk/server/memcached/src/main/java/org/infinispan/server/memcached/QuitCommand.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/memcached/QuitCommand.java	2009-12-29 20:45:06 UTC (rev 1336)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/memcached/QuitCommand.java	2009-12-30 17:58:15 UTC (rev 1337)
@@ -22,7 +22,8 @@
  */
 package org.infinispan.server.memcached;
 
-import org.jboss.netty.channel.Channel;
+import org.infinispan.server.core.Channel;
+import org.infinispan.server.core.ChannelHandlerContext;
 
 /**
  * QuitCommand.
@@ -30,12 +31,12 @@
  * @author Galder Zamarreño
  * @since 4.0
  */
-public enum QuitCommand implements Command {
+public enum QuitCommand implements TextCommand {
    INSTANCE;
    
    @Override
-   public Object acceptVisitor(Channel ch, CommandInterceptor next) throws Exception {
-      return next.visitQuit(ch, this);
+   public Object acceptVisitor(ChannelHandlerContext ctx, TextProtocolVisitor next) throws Throwable {
+      return next.visitQuit(ctx, this);
    }
 
    @Override
@@ -44,7 +45,8 @@
    }
 
    @Override
-   public Object perform(Channel ch) throws Exception {
+   public Object perform(ChannelHandlerContext ctx) throws Throwable {
+      Channel ch = ctx.getChannel();
       ch.disconnect();
       return null;
    }

Modified: trunk/server/memcached/src/main/java/org/infinispan/server/memcached/ReplaceCommand.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/memcached/ReplaceCommand.java	2009-12-29 20:45:06 UTC (rev 1336)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/memcached/ReplaceCommand.java	2009-12-30 17:58:15 UTC (rev 1337)
@@ -25,7 +25,7 @@
 import java.util.concurrent.TimeUnit;
 
 import org.infinispan.Cache;
-import org.jboss.netty.channel.Channel;
+import org.infinispan.server.core.ChannelHandlerContext;
 
 /**
  * ReplaceCommand.
@@ -35,27 +35,38 @@
  */
 public class ReplaceCommand extends SetCommand {
 
-   ReplaceCommand(Cache cache, CommandType type, StorageParameters params, byte[] data) {
+   ReplaceCommand(Cache<String, Value> cache, CommandType type, StorageParameters params, byte[] data) {
       super(cache, type, params, data);
    }
 
    @Override
-   public Object acceptVisitor(Channel ch, CommandInterceptor next) throws Exception {
-      return next.visitReplace(ch, this);
+   public Object acceptVisitor(ChannelHandlerContext ctx, TextProtocolVisitor next) throws Throwable {
+      return next.visitReplace(ctx, this);
    }
 
    @Override
    protected Reply put(String key, int flags, byte[] data, long expiry) {
-      Value value = new Value(flags, data);
-      Object prev = cache.replace(params.key, value, expiry, TimeUnit.MILLISECONDS);
-      return reply(prev);
+      Value old = cache.get(key);
+      if (old != null) {
+         Value value = new Value(flags, data, old.getCas() + 1);
+         boolean replaced = cache.replace(params.key, old, value, expiry, TimeUnit.MILLISECONDS);
+         return reply(replaced);
+      }
+      return reply(old);
    }
 
-   private Reply reply(Object prev) {
+   private Reply reply(Value prev) {
       if (prev == null)
          return Reply.NOT_STORED;
       else
          return Reply.STORED;
    }
 
+   private Reply reply(boolean replaced) {
+      if (!replaced)
+         return Reply.NOT_STORED;
+      else
+         return Reply.STORED;
+   }
+
 }

Modified: trunk/server/memcached/src/main/java/org/infinispan/server/memcached/RetrievalCommand.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/memcached/RetrievalCommand.java	2009-12-29 20:45:06 UTC (rev 1336)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/memcached/RetrievalCommand.java	2009-12-30 17:58:15 UTC (rev 1337)
@@ -30,12 +30,12 @@
  * @author Galder Zamarreño
  * @since 4.0
  */
-public abstract class RetrievalCommand implements Command {
-   final Cache cache;
+public abstract class RetrievalCommand implements TextCommand {
+   final Cache<String, Value> cache;
    private final CommandType type;
    final RetrievalParameters params;
    
-   RetrievalCommand(Cache cache, CommandType type, RetrievalParameters params) {
+   RetrievalCommand(Cache<String, Value> cache, CommandType type, RetrievalParameters params) {
       this.cache = cache;
       this.type = type;
       this.params = params;
@@ -46,7 +46,7 @@
       return type;
    }
 
-   public static Command newRetrievalCommand(Cache cache, CommandType type, RetrievalParameters params) {
+   public static TextCommand newRetrievalCommand(Cache<String, Value> cache, CommandType type, RetrievalParameters params) {
       switch(type) {
          case GET: return new GetCommand(cache, type, params);
          case GETS: return new GetsCommand(cache, type, params);

Modified: trunk/server/memcached/src/main/java/org/infinispan/server/memcached/RetrievalParameters.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/memcached/RetrievalParameters.java	2009-12-29 20:45:06 UTC (rev 1336)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/memcached/RetrievalParameters.java	2009-12-30 17:58:15 UTC (rev 1337)
@@ -32,7 +32,7 @@
  */
 public class RetrievalParameters {
    final List<String> keys;
-   
+
    RetrievalParameters(List<String> keys) {
       this.keys = keys;
    }

Deleted: trunk/server/memcached/src/main/java/org/infinispan/server/memcached/RetrievalReply.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/memcached/RetrievalReply.java	2009-12-29 20:45:06 UTC (rev 1336)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/memcached/RetrievalReply.java	2009-12-30 17:58:15 UTC (rev 1337)
@@ -1,33 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2009, Red Hat, Inc. and/or its affiliates, and
- * individual contributors as indicated by the @author tags. See the
- * copyright.txt file in the distribution for a full listing of
- * individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.infinispan.server.memcached;
-
-/**
- * RetrievalReply.
- * 
- * @author Galder Zamarreño
- * @since 4.0
- */
-public enum RetrievalReply {
-   , ;
-}

Modified: trunk/server/memcached/src/main/java/org/infinispan/server/memcached/SetCommand.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/memcached/SetCommand.java	2009-12-29 20:45:06 UTC (rev 1336)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/memcached/SetCommand.java	2009-12-30 17:58:15 UTC (rev 1337)
@@ -27,12 +27,13 @@
 
 import org.infinispan.Cache;
 import org.infinispan.CacheException;
+import org.infinispan.server.core.Channel;
+import org.infinispan.server.core.ChannelBuffers;
+import org.infinispan.server.core.ChannelHandlerContext;
 import org.infinispan.util.logging.Log;
 import org.infinispan.util.logging.LogFactory;
 
 import static org.infinispan.server.memcached.TextProtocolUtil.CRLF;
-import static org.jboss.netty.buffer.ChannelBuffers.*;
-import org.jboss.netty.channel.Channel;
 
 /**
  * SetCommand.
@@ -43,17 +44,18 @@
 public class SetCommand extends StorageCommand {
    private static final Log log = LogFactory.getLog(SetCommand.class);
 
-   SetCommand(Cache cache, CommandType type, StorageParameters params, byte[] data) {
+   SetCommand(Cache<String, Value> cache, CommandType type, StorageParameters params, byte[] data) {
       super(cache, type, params, data);
    }
 
    @Override
-   public Object acceptVisitor(Channel ch, CommandInterceptor next) throws Exception {
-      return next.visitSet(ch, this);
+   public Object acceptVisitor(ChannelHandlerContext ctx, TextProtocolVisitor next) throws Throwable {
+      return next.visitSet(ctx, this);
    }
 
    @Override
-   public Object perform(Channel ch) throws Exception {
+   public Object perform(ChannelHandlerContext ctx) throws Exception {
+      Channel ch = ctx.getChannel();
       Reply reply;
       try {
          if (params.expiry == 0) {
@@ -83,7 +85,8 @@
          log.error("Unexpected exception performing command", e);
          reply = Reply.NOT_STORED;
       }
-      ch.write(wrappedBuffer(wrappedBuffer(reply.bytes()), wrappedBuffer(CRLF)));
+      ChannelBuffers buffers = ctx.getChannelBuffers();
+      ch.write(buffers.wrappedBuffer(buffers.wrappedBuffer(reply.bytes()), buffers.wrappedBuffer(CRLF)));
       return reply;
    }
 
@@ -92,15 +95,30 @@
    }
 
    protected Reply put(String key, int flags, byte[] data, long expiry) {
-      Value value = new Value(flags, data);
-      cache.put(key, value, expiry, TimeUnit.MILLISECONDS);
-      return reply();
+      Value prev = cache.get(key);
+      Value value;
+      if (prev != null) {
+         value = new Value(flags, data, prev.getCas() + 1);
+         boolean replaced = cache.replace(key, prev, value, expiry, TimeUnit.MILLISECONDS);
+         return reply(replaced);
+      } else {
+         value = new Value(flags, data, System.currentTimeMillis());
+         prev = cache.putIfAbsent(key, value, expiry, TimeUnit.MILLISECONDS);
+         return reply(prev);
+      }
    }
 
-   private Reply reply() {
-      return Reply.STORED;
+   private Reply reply(boolean replaced) {
+      if (!replaced)
+         return Reply.NOT_STORED;
+      else
+         return Reply.STORED;
    }
 
-
-
+   private Reply reply(Value prev) {
+      if (prev == null)
+         return Reply.STORED;
+      else 
+         return Reply.NOT_STORED;
+   }
 }

Modified: trunk/server/memcached/src/main/java/org/infinispan/server/memcached/StatsCommand.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/memcached/StatsCommand.java	2009-12-29 20:45:06 UTC (rev 1336)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/memcached/StatsCommand.java	2009-12-30 17:58:15 UTC (rev 1337)
@@ -25,12 +25,14 @@
 import static org.infinispan.server.memcached.Reply.END;
 import static org.infinispan.server.memcached.Reply.STAT;
 import static org.infinispan.server.memcached.TextProtocolUtil.CRLF;
-import static org.jboss.netty.buffer.ChannelBuffers.wrappedBuffer;
 
 import java.util.concurrent.TimeUnit;
 
 import org.infinispan.Cache;
-import org.jboss.netty.channel.Channel;
+import org.infinispan.server.core.Channel;
+import org.infinispan.server.core.ChannelBuffers;
+import org.infinispan.server.core.ChannelHandlerContext;
+import org.infinispan.server.core.InterceptorChain;
 
 /**
  * StatsCommand.
@@ -38,7 +40,7 @@
  * @author Galder Zamarreño
  * @since 4.0
  */
-public class StatsCommand implements Command {
+public class StatsCommand implements TextCommand {
    final Cache cache;
    private final CommandType type;
    final InterceptorChain chain;
@@ -55,64 +57,68 @@
    }
 
    @Override
-   public Object acceptVisitor(Channel ch, CommandInterceptor next) throws Exception {
-      return next.visitStats(ch, this);
+   public Object acceptVisitor(ChannelHandlerContext ctx, TextProtocolVisitor next) throws Throwable {
+      return next.visitStats(ctx, this);
    }
 
    @Override
-   public Object perform(Channel ch) throws Exception {
+   public Object perform(ChannelHandlerContext ctx) throws Throwable {
       MemcachedStatsImpl stats = new MemcachedStatsImpl(cache.getAdvancedCache().getStats(), chain);
       
       StringBuilder sb = new StringBuilder();
-      writeStat("pid", 0, sb, ch); // Unsupported
-      writeStat("uptime", stats.getTimeSinceStart(), sb, ch);
-      writeStat("time", TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis()), sb, ch);
-      writeStat("version", cache.getVersion(), sb, ch);
-      writeStat("pointer_size", 0, sb, ch); // Unsupported
-      writeStat("rusage_user", 0, sb, ch); // Unsupported
-      writeStat("rusage_system", 0, sb, ch); // Unsupported
-      writeStat("curr_items", stats.getCurrentNumberOfEntries(), sb, ch);
-      writeStat("total_items", stats.getTotalNumberOfEntries(), sb, ch);
-      writeStat("bytes", 0, sb, ch); // Unsupported
-      writeStat("curr_connections", 0, sb, ch); // TODO: Through netty?
-      writeStat("total_connections", 0, sb, ch); // TODO: Through netty?
-      writeStat("connection_structures", 0, sb, ch); // Unsupported
-      writeStat("cmd_get", stats.getRetrievals(), sb, ch);
-      writeStat("cmd_set", stats.getStores(), sb, ch);
-      writeStat("get_hits", stats.getHits(), sb, ch);
-      writeStat("get_misses", stats.getMisses(), sb, ch);
-      writeStat("delete_misses", stats.getRemoveMisses(), sb, ch);
-      writeStat("delete_hits", stats.getRemoveHits(), sb, ch);
-      writeStat("incr_misses", stats.getIncrMisses(), sb, ch);
-      writeStat("incr_hits", stats.getIncrHits(), sb, ch);
-      writeStat("decr_misses", stats.getDecrMisses(), sb, ch);
-      writeStat("decr_hits", stats.getDecrHits(), sb, ch);
-      writeStat("cas_misses", stats.getCasMisses(), sb, ch);
-      writeStat("cas_hits", stats.getCasHits(), sb, ch);
-      writeStat("cas_badval", stats.getCasBadval(), sb, ch);
-      writeStat("auth_cmds", 0, sb, ch);  // Unsupported
-      writeStat("auth_errors", 0, sb, ch); // Unsupported
+      writeStat("pid", 0, sb, ctx); // Unsupported
+      writeStat("uptime", stats.getTimeSinceStart(), sb, ctx);
+      writeStat("time", TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis()), sb, ctx);
+      writeStat("version", cache.getVersion(), sb, ctx);
+      writeStat("pointer_size", 0, sb, ctx); // Unsupported
+      writeStat("rusage_user", 0, sb, ctx); // Unsupported
+      writeStat("rusage_system", 0, sb, ctx); // Unsupported
+      writeStat("curr_items", stats.getCurrentNumberOfEntries(), sb, ctx);
+      writeStat("total_items", stats.getTotalNumberOfEntries(), sb, ctx);
+      writeStat("bytes", 0, sb, ctx); // Unsupported
+      writeStat("curr_connections", 0, sb, ctx); // TODO: Through netty?
+      writeStat("total_connections", 0, sb, ctx); // TODO: Through netty?
+      writeStat("connection_structures", 0, sb, ctx); // Unsupported
+      writeStat("cmd_get", stats.getRetrievals(), sb, ctx);
+      writeStat("cmd_set", stats.getStores(), sb, ctx);
+      writeStat("get_hits", stats.getHits(), sb, ctx);
+      writeStat("get_misses", stats.getMisses(), sb, ctx);
+      writeStat("delete_misses", stats.getRemoveMisses(), sb, ctx);
+      writeStat("delete_hits", stats.getRemoveHits(), sb, ctx);
+      writeStat("incr_misses", stats.getIncrMisses(), sb, ctx);
+      writeStat("incr_hits", stats.getIncrHits(), sb, ctx);
+      writeStat("decr_misses", stats.getDecrMisses(), sb, ctx);
+      writeStat("decr_hits", stats.getDecrHits(), sb, ctx);
+      writeStat("cas_misses", stats.getCasMisses(), sb, ctx);
+      writeStat("cas_hits", stats.getCasHits(), sb, ctx);
+      writeStat("cas_badval", stats.getCasBadval(), sb, ctx);
+      writeStat("auth_cmds", 0, sb, ctx);  // Unsupported
+      writeStat("auth_errors", 0, sb, ctx); // Unsupported
       //TODO: Evictions are measure by evict calls, but not by nodes are that 
       //      are expired after the entry's lifespan has expired.
-      writeStat("evictions", stats.getEvictions(), sb, ch);
-      writeStat("bytes_read", 0, sb, ch); // TODO: Through netty?
-      writeStat("bytes_written", 0, sb, ch); // TODO: Through netty?
-      writeStat("limit_maxbytes", 0, sb, ch); // Unsupported
-      writeStat("threads", 0, sb, ch); // TODO: Through netty?
-      writeStat("conn_yields", 0, sb, ch); // Unsupported
+      writeStat("evictions", stats.getEvictions(), sb, ctx);
+      writeStat("bytes_read", 0, sb, ctx); // TODO: Through netty?
+      writeStat("bytes_written", 0, sb, ctx); // TODO: Through netty?
+      writeStat("limit_maxbytes", 0, sb, ctx); // Unsupported
+      writeStat("threads", 0, sb, ctx); // TODO: Through netty?
+      writeStat("conn_yields", 0, sb, ctx); // Unsupported
+
+      ChannelBuffers buffers = ctx.getChannelBuffers();
+      Channel ch = ctx.getChannel();
+      ch.write(buffers.wrappedBuffer(buffers.wrappedBuffer(END.bytes()), buffers.wrappedBuffer(CRLF)));
       
-      ch.write(wrappedBuffer(wrappedBuffer(END.toString().getBytes()), wrappedBuffer(CRLF)));
-      
-      return null;
+      return END;
    }
 
-   private void writeStat(String stat, Object value, StringBuilder sb, Channel ch) {
+   private void writeStat(String stat, Object value, StringBuilder sb, ChannelHandlerContext ctx) {
+      ChannelBuffers buffers = ctx.getChannelBuffers();
+      Channel ch = ctx.getChannel();
       sb.append(STAT).append(' ').append(stat).append(' ').append(value);
-      ch.write(wrappedBuffer(wrappedBuffer(sb.toString().getBytes()), wrappedBuffer(CRLF)));
+      ch.write(buffers.wrappedBuffer(buffers.wrappedBuffer(sb.toString().getBytes()), buffers.wrappedBuffer(CRLF)));
       sb.setLength(0);
    }
 
-   public static Command newStatsCommand(Cache cache, CommandType type, InterceptorChain chain) {
+   public static TextCommand newStatsCommand(Cache cache, CommandType type, InterceptorChain chain) {
       return new StatsCommand(cache, type, chain);
    }
 

Modified: trunk/server/memcached/src/main/java/org/infinispan/server/memcached/StatsInterceptor.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/memcached/StatsInterceptor.java	2009-12-29 20:45:06 UTC (rev 1336)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/memcached/StatsInterceptor.java	2009-12-30 17:58:15 UTC (rev 1337)
@@ -24,7 +24,7 @@
 
 import java.util.concurrent.atomic.AtomicLong;
 
-import org.jboss.netty.channel.Channel;
+import org.infinispan.server.core.ChannelHandlerContext;
 
 /**
  * StatsInterceptor.
@@ -32,7 +32,7 @@
  * @author Galder Zamarreño
  * @since 4.0
  */
-public class StatsInterceptor extends CommandInterceptor implements MemcachedStats {
+public class StatsInterceptor extends TextCommandInterceptorImpl implements MemcachedStats {
    private final AtomicLong incrMisses = new AtomicLong(0);
    private final AtomicLong incrHits = new AtomicLong(0);
    private final AtomicLong decrMisses = new AtomicLong(0);
@@ -41,14 +41,14 @@
    private final AtomicLong casHits = new AtomicLong(0);
    private final AtomicLong casBadval = new AtomicLong(0);
 
-   public StatsInterceptor(CommandInterceptor next) {
+   public StatsInterceptor(TextCommandInterceptor next) {
       super(next);
    }
 
    @Override
-   public Object visitIncrement(Channel ch, IncrementCommand command) throws Exception {
-      Object ret = invokeNextInterceptor(ch, command);
-      if (ret != null)
+   public Object visitIncrement(ChannelHandlerContext ctx, IncrementCommand command) throws Throwable {
+      Object ret = invokeNextInterceptor(ctx, command);
+      if (ret != Reply.NOT_FOUND)
          incrHits.incrementAndGet();
       else
          incrMisses.incrementAndGet();
@@ -56,9 +56,9 @@
    }
 
    @Override
-   public Object visitDecrement(Channel ch, DecrementCommand command) throws Exception {
-      Object ret = invokeNextInterceptor(ch, command);
-      if (ret != null)
+   public Object visitDecrement(ChannelHandlerContext ctx, DecrementCommand command) throws Throwable {
+      Object ret = invokeNextInterceptor(ctx, command);
+      if (ret != Reply.NOT_FOUND)
          decrHits.incrementAndGet();
       else
          decrMisses.incrementAndGet();
@@ -66,9 +66,9 @@
    }
 
    @Override
-   public Object visitCas(Channel ch, CasCommand command) throws Exception {
-      Reply ret = (Reply) invokeNextInterceptor(ch, command);
-      switch(ret) {
+   public Object visitCas(ChannelHandlerContext ctx, CasCommand command) throws Throwable {
+      Reply ret = (Reply) invokeNextInterceptor(ctx, command);
+      switch (ret) {
          case STORED:
             casHits.incrementAndGet();
             break;

Modified: trunk/server/memcached/src/main/java/org/infinispan/server/memcached/StorageCommand.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/memcached/StorageCommand.java	2009-12-29 20:45:06 UTC (rev 1336)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/memcached/StorageCommand.java	2009-12-30 17:58:15 UTC (rev 1337)
@@ -26,6 +26,7 @@
 import java.io.StreamCorruptedException;
 
 import org.infinispan.Cache;
+import org.infinispan.server.core.Command;
 
 /**
  * StorageCommand.
@@ -33,24 +34,16 @@
  * @author Galder Zamarreño
  * @since 4.0
  */
-public abstract class StorageCommand implements Command {
-   final Cache cache;
+public abstract class StorageCommand implements TextCommand {
    private final CommandType type;
+   final Cache<String, Value> cache;
    final StorageParameters params;
-//   final String key;
-//   final int flags;
-//   final long expiry;
-//   final int bytes;
    final byte[] data;
 
-   StorageCommand(Cache cache, CommandType type, StorageParameters params, byte[] data) {
+   StorageCommand(Cache<String, Value> cache, CommandType type, StorageParameters params, byte[] data) {
       this.type = type;
       this.params = params;
       this.cache = cache;
-//      this.key = key;
-//      this.flags = flags;
-//      this.expiry = expiry;
-//      this.bytes = bytes;
       this.data = data;
    }
 
@@ -62,7 +55,11 @@
       return newStorageCommand(cache, type, params, data);
    }
 
-   public static Command newStorageCommand(Cache cache, CommandType type, StorageParameters params, byte[] data) throws IOException {
+   public StorageParameters getParams() {
+      return params;
+   }
+
+   public static TextCommand newStorageCommand(Cache<String, Value> cache, CommandType type, StorageParameters params, byte[] data) throws IOException {
       switch(type) {
          case SET: return new SetCommand(cache, type, params, data);
          case ADD: return new AddCommand(cache, type, params, data);
@@ -72,8 +69,4 @@
          default: throw new StreamCorruptedException("Unable to build storage command for type: " + type);
       }
    }
-   
-//   public static Command buildCasCommand(String key, int flags, long expiry, int bytes, long unique) {
-//      return new CasCommand(key, flags, expiry, bytes, unique);
-//   }
 }

Modified: trunk/server/memcached/src/main/java/org/infinispan/server/memcached/StorageParameters.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/memcached/StorageParameters.java	2009-12-29 20:45:06 UTC (rev 1336)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/memcached/StorageParameters.java	2009-12-30 17:58:15 UTC (rev 1337)
@@ -41,4 +41,8 @@
       this.expiry = expiry;
       this.bytes = bytes;
    }
+
+   public int getBytes() {
+      return bytes;
+   }
 }

Added: trunk/server/memcached/src/main/java/org/infinispan/server/memcached/TextCommand.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/memcached/TextCommand.java	                        (rev 0)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/memcached/TextCommand.java	2009-12-30 17:58:15 UTC (rev 1337)
@@ -0,0 +1,37 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat, Inc. and/or its affiliates, and
+ * individual contributors as indicated by the @author tags. See the
+ * copyright.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.server.memcached;
+
+import org.infinispan.server.core.ChannelHandlerContext;
+import org.infinispan.server.core.Command;
+
+/**
+ * TextCommand.
+ * 
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+public interface TextCommand extends Command {
+   Object acceptVisitor(ChannelHandlerContext ctx, TextProtocolVisitor next) throws Throwable;
+   CommandType getType();
+}

Deleted: trunk/server/memcached/src/main/java/org/infinispan/server/memcached/TextCommandDecoder.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/memcached/TextCommandDecoder.java	2009-12-29 20:45:06 UTC (rev 1336)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/memcached/TextCommandDecoder.java	2009-12-30 17:58:15 UTC (rev 1337)
@@ -1,197 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2009, Red Hat, Inc. and/or its affiliates, and
- * individual contributors as indicated by the @author tags. See the
- * copyright.txt file in the distribution for a full listing of
- * individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.infinispan.server.memcached;
-
-import java.io.IOException;
-import java.io.StreamCorruptedException;
-import java.util.concurrent.ScheduledExecutorService;
-
-import org.infinispan.Cache;
-import org.infinispan.util.logging.Log;
-import org.infinispan.util.logging.LogFactory;
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.jboss.netty.channel.Channel;
-import org.jboss.netty.channel.ChannelHandlerContext;
-import org.jboss.netty.channel.ExceptionEvent;
-import org.jboss.netty.handler.codec.replay.ReplayingDecoder;
-import static org.infinispan.server.memcached.TextProtocolUtil.*;
-import static org.jboss.netty.buffer.ChannelBuffers.wrappedBuffer;
-
-/**
- * TextCommandDecoder.
- * 
- * @author Galder Zamarreño
- * @since 4.0
- */
-public class TextCommandDecoder extends ReplayingDecoder<TextCommandDecoder.State> {
-   private static final Log log = LogFactory.getLog(TextCommandDecoder.class);
-   
-   private final CommandFactory factory;
-   private volatile Command command;
-
-   protected enum State {
-      READ_COMMAND, READ_UNSTRUCTURED_DATA;
-   }
-
-   TextCommandDecoder(Cache cache, InterceptorChain chain, ScheduledExecutorService scheduler) {
-      super(State.READ_COMMAND, true);
-      factory = new CommandFactory(cache, chain, scheduler);
-   }
-
-   @Override
-   protected Object decode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer, State state) throws Exception {
-      switch (state) {
-         case READ_COMMAND:
-            String line = readLine(buffer);
-//            try {
-               command = factory.createCommand(line);
-//               corrupted.set(false);
-//            } catch (IOException ioe) {
-//               if (corrupted.get())
-//                  log.debug("Channel is corrupted and we're reading garbage, ignore read until we find a good command again");
-//               else
-//                  throw ioe;
-//            }
-            
-            if (command.getType().isStorage())
-               checkpoint(State.READ_UNSTRUCTURED_DATA);
-            else
-               return command;
-            break;
-         case READ_UNSTRUCTURED_DATA:
-            StorageCommand storageCmd = (StorageCommand) command;
-            byte[] data= new byte[storageCmd.params.bytes];
-            buffer.readBytes(data, 0, data.length);
-            byte next = buffer.readByte();
-            if (next == CR) {
-               next = buffer.readByte();
-               if (next == LF) {
-                  try {
-                     return reset(storageCmd.setData(data));
-                  } catch (IOException ioe) {
-                     checkpoint(State.READ_COMMAND);
-                     throw ioe;
-                  }
-               } else {
-                  throw new StreamCorruptedException("Expecting \r\n after data block");
-               }
-            } else {
-               throw new StreamCorruptedException("Expecting \r\n after data block");
-            }
-      }
-      return null;
-   }
-
-   @Override
-   public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception {
-//      corrupted.compareAndSet(false, true);
-      Throwable t = e.getCause();
-      log.error("Unexpected exception", t);
-      Channel ch = ctx.getChannel();
-      if (t instanceof UnknownCommandException) {
-         ch.write(wrappedBuffer(wrappedBuffer(Reply.ERROR.bytes()), wrappedBuffer(CRLF)));
-      } else if (t instanceof IOException) {
-         StringBuilder sb = new StringBuilder();
-         sb.append(Reply.CLIENT_ERROR).append(' ').append(t);
-         ch.write(wrappedBuffer(wrappedBuffer(sb.toString().getBytes()), wrappedBuffer(CRLF)));
-      } else {
-         StringBuilder sb = new StringBuilder();
-         sb.append(Reply.SERVER_ERROR).append(' ').append(t);
-         ch.write(wrappedBuffer(wrappedBuffer(sb.toString().getBytes()), wrappedBuffer(CRLF)));
-      }
-   }
-
-   private Object reset(Command c) {
-      this.command = null;
-      checkpoint(State.READ_COMMAND);
-      return c;
-  }
-
-   private String readLine(ChannelBuffer buffer) {
-      StringBuilder sb = new StringBuilder(64);
-      int lineLength = 0;
-      while (true) {
-         byte next = buffer.readByte();
-         if (next == CR) {
-            next = buffer.readByte();
-            if (next == LF) {
-               return sb.toString();
-            }
-         } else if (next == LF) {
-            return sb.toString();
-         } else {
-            lineLength++;
-            sb.append((char) next);
-         }
-      }
-   }
-
-   // private String readLine(ChannelBuffer buffer) {
-   // int minFrameLength = Integer.MAX_VALUE;
-   //
-   // ChannelBuffer minDelim = null;
-   // int frameLength = indexOf(buffer, CR);
-   // if (frameLength >= 0 && frameLength < minFrameLength) {
-   // minFrameLength = frameLength;
-   // minDelim = CR;
-   // }
-   //
-   // if (minDelim != null) {
-   // int minDelimLength = minDelim.capacity();
-   // ChannelBuffer frame = buffer.readBytes(minFrameLength);
-   // buffer.skipBytes(minDelimLength);
-   // return frame.toString(Charset.defaultCharset().name());
-   // } else {
-   // return null;
-   // }
-   // }
-   //
-   // /**
-   // * Returns the number of bytes between the readerIndex of the haystack and
-   // * the first needle found in the haystack. -1 is returned if no needle is
-   // * found in the haystack.
-   // */
-   // private static int indexOf(ChannelBuffer haystack, ChannelBuffer needle) {
-   // for (int i = haystack.readerIndex(); i < haystack.writerIndex(); i ++) {
-   // int haystackIndex = i;
-   // int needleIndex;
-   // for (needleIndex = 0; needleIndex < needle.capacity(); needleIndex ++) {
-   // if (haystack.getByte(haystackIndex) != needle.getByte(needleIndex)) {
-   // break;
-   // } else {
-   // haystackIndex ++;
-   // if (haystackIndex == haystack.writerIndex() &&
-   // needleIndex != needle.capacity() - 1) {
-   // return -1;
-   // }
-   // }
-   // }
-   //
-   // if (needleIndex == needle.capacity()) {
-   // // Found the needle from the haystack!
-   // return i - haystack.readerIndex();
-   // }
-   // }
-   // return -1;
-   // }
-}

Modified: trunk/server/memcached/src/main/java/org/infinispan/server/memcached/TextCommandHandler.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/memcached/TextCommandHandler.java	2009-12-29 20:45:06 UTC (rev 1336)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/memcached/TextCommandHandler.java	2009-12-30 17:58:15 UTC (rev 1337)
@@ -23,10 +23,10 @@
 package org.infinispan.server.memcached;
 
 import org.infinispan.Cache;
-import org.jboss.netty.channel.ChannelHandlerContext;
-import org.jboss.netty.channel.ChannelPipelineCoverage;
-import org.jboss.netty.channel.MessageEvent;
-import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
+import org.infinispan.server.core.ChannelHandlerContext;
+import org.infinispan.server.core.CommandHandler;
+import org.infinispan.server.core.MessageEvent;
+import org.infinispan.server.core.InterceptorChain;
 
 /**
  * TextProtocolServerHandler.
@@ -34,22 +34,18 @@
  * @author Galder Zamarreño
  * @since 4.0
  */
- at ChannelPipelineCoverage("one")
-class TextCommandHandler extends SimpleChannelUpstreamHandler {
+class TextCommandHandler implements CommandHandler {
    final Cache cache;
    final InterceptorChain chain;
 
-   TextCommandHandler(Cache cache, InterceptorChain chain) {
+   public TextCommandHandler(Cache cache, InterceptorChain chain) {
       this.cache = cache;
       this.chain = chain;
    }
 
    @Override
-   public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
-      chain.invoke(ctx.getChannel(), (Command) e.getMessage());
-//      Command c = (Command) e.getMessage();
-//      c.perform(ctx.getChannel());
+   public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Throwable {
+      chain.invoke(ctx, (TextCommand) e.getMessage());
    }
 
-   
 }

Added: trunk/server/memcached/src/main/java/org/infinispan/server/memcached/TextCommandInterceptor.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/memcached/TextCommandInterceptor.java	                        (rev 0)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/memcached/TextCommandInterceptor.java	2009-12-30 17:58:15 UTC (rev 1337)
@@ -0,0 +1,36 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat, Inc. and/or its affiliates, and
+ * individual contributors as indicated by the @author tags. See the
+ * copyright.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.server.memcached;
+
+import org.infinispan.server.core.ChannelHandlerContext;
+import org.infinispan.server.core.CommandInterceptor;
+
+/**
+ * TextCommandInterceptor.
+ * 
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+public interface TextCommandInterceptor extends CommandInterceptor, TextProtocolVisitor {
+   Object invokeNextInterceptor(ChannelHandlerContext ctx, TextCommand command) throws Throwable;
+}

Added: trunk/server/memcached/src/main/java/org/infinispan/server/memcached/TextCommandInterceptorImpl.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/memcached/TextCommandInterceptorImpl.java	                        (rev 0)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/memcached/TextCommandInterceptorImpl.java	2009-12-30 17:58:15 UTC (rev 1337)
@@ -0,0 +1,56 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat, Inc. and/or its affiliates, and
+ * individual contributors as indicated by the @author tags. See the
+ * copyright.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.server.memcached;
+
+import org.infinispan.server.core.ChannelHandlerContext;
+import org.infinispan.server.core.CommandInterceptor;
+
+/**
+ * TextCommandInterceptorImpl.
+ * 
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+public class TextCommandInterceptorImpl extends AbstractVisitor implements TextCommandInterceptor {
+   private final TextCommandInterceptor next;
+
+   TextCommandInterceptorImpl(TextCommandInterceptor next) {
+      this.next = next;
+   }
+
+   @Override
+   public Object invokeNextInterceptor(ChannelHandlerContext ctx, TextCommand command) throws Throwable {
+      return command.acceptVisitor(ctx, next);
+   }
+
+   @Override
+   public CommandInterceptor getNext() {
+      return next;
+   }
+
+   @Override
+   protected Object handleDefault(ChannelHandlerContext ctx, TextCommand command) throws Throwable {
+      return invokeNextInterceptor(ctx, command);
+   }
+
+}

Added: trunk/server/memcached/src/main/java/org/infinispan/server/memcached/TextProtocolInterceptorChain.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/memcached/TextProtocolInterceptorChain.java	                        (rev 0)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/memcached/TextProtocolInterceptorChain.java	2009-12-30 17:58:15 UTC (rev 1337)
@@ -0,0 +1,83 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat, Inc. and/or its affiliates, and
+ * individual contributors as indicated by the @author tags. See the
+ * copyright.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.server.memcached;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.infinispan.server.core.ChannelHandlerContext;
+import org.infinispan.server.core.Command;
+import org.infinispan.server.core.CommandInterceptor;
+import org.infinispan.server.core.InterceptorChain;
+
+/**
+ * TextProtocolInterceptorChain.
+ * 
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+public class TextProtocolInterceptorChain implements InterceptorChain {
+
+   private final TextCommandInterceptor firstInChain;
+
+   public TextProtocolInterceptorChain(TextCommandInterceptor firstInChain) {
+      this.firstInChain = firstInChain;
+   }
+   
+   @Override
+   public Object invoke(ChannelHandlerContext ctx, Command command) throws Throwable {
+      return ((TextCommand) command).acceptVisitor(ctx, firstInChain);
+   }
+
+   public List<CommandInterceptor> getInterceptorsWhichExtend(Class<? extends CommandInterceptor> interceptorClass) {
+      List<CommandInterceptor> result = new ArrayList<CommandInterceptor>();
+      for (CommandInterceptor interceptor : asList()) {
+         boolean isSubclass = interceptorClass.isAssignableFrom(interceptor.getClass());
+         if (isSubclass) {
+            result.add(interceptor);
+         }
+      }
+      return result;
+   }
+
+   /**
+    * Returns an unmofiable list with all the interceptors in sequence. If first in chain is null an empty list is
+    * returned.
+    */
+   private List<CommandInterceptor> asList() {
+      if (firstInChain == null) return Collections.emptyList();
+
+      List<CommandInterceptor> retval = new LinkedList<CommandInterceptor>();
+      CommandInterceptor tmp = firstInChain;
+      do {
+         retval.add(tmp);
+         tmp = tmp.getNext();
+      }
+      while (tmp != null);
+      return Collections.unmodifiableList(retval);
+   }
+
+
+}

Copied: trunk/server/memcached/src/main/java/org/infinispan/server/memcached/TextProtocolInterceptorChainFactory.java (from rev 1329, trunk/server/memcached/src/main/java/org/infinispan/server/memcached/InterceptorChainFactory.java)
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/memcached/TextProtocolInterceptorChainFactory.java	                        (rev 0)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/memcached/TextProtocolInterceptorChainFactory.java	2009-12-30 17:58:15 UTC (rev 1337)
@@ -0,0 +1,61 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat, Inc. and/or its affiliates, and
+ * individual contributors as indicated by the @author tags. See the
+ * copyright.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.server.memcached;
+
+import org.infinispan.Cache;
+import org.infinispan.server.core.InterceptorChainFactory;
+import org.infinispan.server.core.InterceptorChain;
+
+/**
+ * InterceptorChainFactory.
+ * 
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+public enum TextProtocolInterceptorChainFactory implements InterceptorChainFactory {
+   STATS_ENABLED(true), NOT_STATS_ENABLED(false);
+
+   private final boolean statsEnabled;
+
+   private TextProtocolInterceptorChainFactory(boolean statsEnabled) {
+      this.statsEnabled = statsEnabled;
+   }
+
+   public InterceptorChain buildInterceptorChain() {
+      TextCommandInterceptor first;
+      if (statsEnabled) {
+         first = new StatsInterceptor(new CallInterceptor(null));
+      } else {
+         first = new CallInterceptor(null);
+      }
+      
+      return new TextProtocolInterceptorChain(first);
+   }
+
+   public static TextProtocolInterceptorChainFactory getInstance(Cache cache) {
+      if (cache.getConfiguration().isExposeJmxStatistics())
+         return STATS_ENABLED;
+      else
+         return NOT_STATS_ENABLED;
+   }
+}

Deleted: trunk/server/memcached/src/main/java/org/infinispan/server/memcached/TextProtocolPipelineFactory.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/memcached/TextProtocolPipelineFactory.java	2009-12-29 20:45:06 UTC (rev 1336)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/memcached/TextProtocolPipelineFactory.java	2009-12-30 17:58:15 UTC (rev 1337)
@@ -1,71 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2009, Red Hat, Inc. and/or its affiliates, and
- * individual contributors as indicated by the @author tags. See the
- * copyright.txt file in the distribution for a full listing of
- * individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.infinispan.server.memcached;
-
-import static org.jboss.netty.channel.Channels.*;
-
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.ScheduledExecutorService;
-
-import org.infinispan.Cache;
-import org.jboss.netty.channel.ChannelHandler;
-import org.jboss.netty.channel.ChannelPipeline;
-import org.jboss.netty.channel.ChannelPipelineFactory;
-import org.jboss.netty.handler.codec.replay.ReplayingDecoder;
-
-/**
- * TextProtocolPipelineFactory.
- * 
- * @author Galder Zamarreño
- * @since 4.0
- */
-class TextProtocolPipelineFactory implements ChannelPipelineFactory {
-
-//   private final ChannelHandler handler;
-//
-//   public TextProtocolPipelineFactory(TextCommandHandler handler) {
-//      this.handler = handler;
-//   }
-
-//   private final Cache cache;
-   
-   private final ReplayingDecoder<TextCommandDecoder.State> decoder;
-   private final ChannelHandler handler;
-
-   public TextProtocolPipelineFactory(Cache cache, InterceptorChain chain, ScheduledExecutorService scheduler) {
-      this.decoder = new TextCommandDecoder(cache, chain, scheduler);
-      this.handler = new TextCommandHandler(cache, chain);
-   }
-
-   @Override
-   public ChannelPipeline getPipeline() throws Exception {
-      // Create a default pipeline implementation.
-      ChannelPipeline pipeline = pipeline();
-      pipeline.addLast("decoder", decoder);
-      pipeline.addLast("handler", handler);
-//      pipeline.addLast("encoder", new TextResponseEncoder());
-
-      return pipeline;
-   }
-
-}

Modified: trunk/server/memcached/src/main/java/org/infinispan/server/memcached/TextProtocolUtil.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/memcached/TextProtocolUtil.java	2009-12-29 20:45:06 UTC (rev 1336)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/memcached/TextProtocolUtil.java	2009-12-30 17:58:15 UTC (rev 1337)
@@ -29,9 +29,9 @@
  * @since 4.0
  */
 public class TextProtocolUtil {
-   static final byte CR = 13;
-   static final byte LF = 10;
-   static final byte[] CRLF = new byte[] { CR, LF };
+   public static final byte CR = 13;
+   public static final byte LF = 10;
+   public static final byte[] CRLF = new byte[] { CR, LF };
    static final long SECONDS_IN_A_MONTH = 60*60*24*30;
 
    public static byte[] concat(byte[] a, byte[] b) {

Copied: trunk/server/memcached/src/main/java/org/infinispan/server/memcached/TextProtocolVisitor.java (from rev 1329, trunk/server/memcached/src/main/java/org/infinispan/server/memcached/Visitor.java)
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/memcached/TextProtocolVisitor.java	                        (rev 0)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/memcached/TextProtocolVisitor.java	2009-12-30 17:58:15 UTC (rev 1337)
@@ -0,0 +1,49 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat, Inc. and/or its affiliates, and
+ * individual contributors as indicated by the @author tags. See the
+ * copyright.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.server.memcached;
+
+import org.infinispan.server.core.ChannelHandlerContext;
+
+/**
+ * CommandInterceptor.
+ * 
+ * @author Galder Zamarreño
+ * @since 4.0
+ */
+public interface TextProtocolVisitor {
+   Object visitSet(ChannelHandlerContext ctx, SetCommand command) throws Throwable;
+   Object visitAdd(ChannelHandlerContext ctx, AddCommand command) throws Throwable;
+   Object visitReplace(ChannelHandlerContext ctx, ReplaceCommand command) throws Throwable;
+   Object visitAppend(ChannelHandlerContext ctx, AppendCommand command) throws Throwable;
+   Object visitPrepend(ChannelHandlerContext ctx, PrependCommand command) throws Throwable;
+   Object visitCas(ChannelHandlerContext ctx, CasCommand command) throws Throwable;
+   Object visitGet(ChannelHandlerContext ctx, GetCommand command) throws Throwable;
+   Object visitGets(ChannelHandlerContext ctx, GetsCommand command) throws Throwable;
+   Object visitDelete(ChannelHandlerContext ctx, DeleteCommand command) throws Throwable;
+   Object visitIncrement(ChannelHandlerContext ctx, IncrementCommand command) throws Throwable;
+   Object visitDecrement(ChannelHandlerContext ctx, DecrementCommand command) throws Throwable;
+   Object visitStats(ChannelHandlerContext ctx, StatsCommand command) throws Throwable;
+   Object visitFlushAll(ChannelHandlerContext ctx, FlushAllCommand command) throws Throwable;
+   Object visitVersion(ChannelHandlerContext ctx, VersionCommand command) throws Throwable;
+   Object visitQuit(ChannelHandlerContext ctx, QuitCommand command) throws Throwable;
+}

Modified: trunk/server/memcached/src/main/java/org/infinispan/server/memcached/Value.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/memcached/Value.java	2009-12-29 20:45:06 UTC (rev 1336)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/memcached/Value.java	2009-12-30 17:58:15 UTC (rev 1337)
@@ -39,15 +39,10 @@
    private byte[] data;
    private long cas;
    
-   Value(int flags, byte[] data) {
+   Value(int flags, byte[] data, long cas) {
       this.flags = flags;
       this.data = data;
-      // Since nano time is an offset from an arbitrary time, it is very unlikely that 
-      // two threads running on different VMs will generate the same value, so even two 
-      // modifications on the same key on different VMs will generate different cas, 
-      // making it a safe option for cas unique id.
-      // Also, using nano time avoid issues after expiration and eviction.
-      cas = System.nanoTime();
+      this.cas = cas;
    }
 
    public int getFlags() {
@@ -84,6 +79,15 @@
    }
 
    @Override
+   public String toString() {
+      return getClass().getSimpleName() + "{" +
+         "data=" + Arrays.toString(data) +
+         ", flags=" + flags +
+         ", cas=" + cas +
+         "}";
+   }
+
+   @Override
    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
       flags = in.read();
       data = new byte[in.read()];

Modified: trunk/server/memcached/src/main/java/org/infinispan/server/memcached/VersionCommand.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/memcached/VersionCommand.java	2009-12-29 20:45:06 UTC (rev 1336)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/memcached/VersionCommand.java	2009-12-30 17:58:15 UTC (rev 1337)
@@ -23,24 +23,27 @@
 package org.infinispan.server.memcached;
 
 import static org.infinispan.server.memcached.Reply.VERSION;
+
 import static org.infinispan.server.memcached.TextProtocolUtil.CRLF;
-import static org.jboss.netty.buffer.ChannelBuffers.wrappedBuffer;
 
 import org.infinispan.Version;
-import org.jboss.netty.channel.Channel;
+import org.infinispan.server.core.Channel;
+import org.infinispan.server.core.ChannelBuffers;
+import org.infinispan.server.core.ChannelHandlerContext;
 
+
 /**
  * VersionCommand.
  * 
  * @author Galder Zamarreño
  * @since 4.0
  */
-public enum VersionCommand implements Command {
+public enum VersionCommand implements TextCommand {
    INSTANCE;
 
    @Override
-   public Object acceptVisitor(Channel ch, CommandInterceptor next) throws Exception {
-      return next.visitVersion(ch, this);
+   public Object acceptVisitor(ChannelHandlerContext ctx, TextProtocolVisitor next) throws Throwable {
+      return next.visitVersion(ctx, this);
    }
 
    @Override
@@ -49,10 +52,12 @@
    }
 
    @Override
-   public Object perform(Channel ch) throws Exception {
+   public Object perform(ChannelHandlerContext ctx) throws Exception {
+      Channel ch = ctx.getChannel();
       String version = ' ' + Version.version;
-      ch.write(wrappedBuffer(wrappedBuffer(VERSION.bytes()), wrappedBuffer(version.getBytes()), wrappedBuffer(CRLF)));
-      return null;
+      ChannelBuffers buffers = ctx.getChannelBuffers();
+      ch.write(buffers.wrappedBuffer(buffers.wrappedBuffer(VERSION.bytes()), buffers.wrappedBuffer(version.getBytes()), buffers.wrappedBuffer(CRLF)));
+      return VERSION;
    }
 
    public static VersionCommand newVersionCommand() {

Deleted: trunk/server/memcached/src/main/java/org/infinispan/server/memcached/Visitor.java
===================================================================
--- trunk/server/memcached/src/main/java/org/infinispan/server/memcached/Visitor.java	2009-12-29 20:45:06 UTC (rev 1336)
+++ trunk/server/memcached/src/main/java/org/infinispan/server/memcached/Visitor.java	2009-12-30 17:58:15 UTC (rev 1337)
@@ -1,49 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2009, Red Hat, Inc. and/or its affiliates, and
- * individual contributors as indicated by the @author tags. See the
- * copyright.txt file in the distribution for a full listing of
- * individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.infinispan.server.memcached;
-
-import org.jboss.netty.channel.Channel;
-
-/**
- * CommandInterceptor.
- * 
- * @author Galder Zamarreño
- * @since 4.0
- */
-public interface Visitor {
-   Object visitSet(Channel ch, SetCommand command) throws Exception;
-   Object visitAdd(Channel ch, AddCommand command) throws Exception;
-   Object visitReplace(Channel ch, ReplaceCommand command) throws Exception;
-   Object visitAppend(Channel ch, AppendCommand command) throws Exception;
-   Object visitPrepend(Channel ch, PrependCommand command) throws Exception;
-   Object visitCas(Channel ch, CasCommand command) throws Exception;
-   Object visitGet(Channel ch, GetCommand command) throws Exception;
-   Object visitGets(Channel ch, GetsCommand command) throws Exception;
-   Object visitDelete(Channel ch, DeleteCommand command) throws Exception;
-   Object visitIncrement(Channel ch, IncrementCommand command) throws Exception;
-   Object visitDecrement(Channel ch, DecrementCommand command) throws Exception;
-   Object visitStats(Channel ch, StatsCommand command) throws Exception;
-   Object visitFlushAll(Channel ch, FlushAllCommand command) throws Exception;
-   Object visitVersion(Channel ch, VersionCommand command) throws Exception;
-   Object visitQuit(Channel ch, QuitCommand command) throws Exception;
-}

Modified: trunk/server/memcached/src/test/java/org/infinispan/server/memcached/FunctionalTest.java
===================================================================
--- trunk/server/memcached/src/test/java/org/infinispan/server/memcached/FunctionalTest.java	2009-12-29 20:45:06 UTC (rev 1336)
+++ trunk/server/memcached/src/test/java/org/infinispan/server/memcached/FunctionalTest.java	2009-12-30 17:58:15 UTC (rev 1337)
@@ -60,7 +60,7 @@
       cacheManager = TestCacheManagerFactory.createLocalCacheManager();
       server = MemcachedTestingUtil.createMemcachedTextServer(cacheManager);
       server.start();
-      client = createMemcachedClient(5000, server.getPort());
+      client = createMemcachedClient(60000, server.getPort());
       return cacheManager;
    }
 
@@ -216,7 +216,7 @@
 
    public void testCasBasic(Method m) throws Exception {
       Future<Boolean> f = client.set(k(m), 0, v(m));
-      assert f.get(5, TimeUnit.SECONDS);
+      assert f.get(60, TimeUnit.SECONDS);
       CASValue<Object> value = client.gets(k(m));
       assert v(m).equals(value.getValue());
       assert value.getCas() != 0;

Modified: trunk/server/memcached/src/test/java/org/infinispan/server/memcached/StatsTest.java
===================================================================
--- trunk/server/memcached/src/test/java/org/infinispan/server/memcached/StatsTest.java	2009-12-29 20:45:06 UTC (rev 1336)
+++ trunk/server/memcached/src/test/java/org/infinispan/server/memcached/StatsTest.java	2009-12-30 17:58:15 UTC (rev 1337)
@@ -59,7 +59,7 @@
       cacheManager = TestCacheManagerFactory.createJmxEnabledCacheManager(JMX_DOMAIN);
       server = MemcachedTestingUtil.createMemcachedTextServer(cacheManager);
       server.start();
-      client = createMemcachedClient(5000, server.getPort());
+      client = createMemcachedClient(60000, server.getPort());
       return cacheManager;
    }
 
@@ -132,9 +132,9 @@
 
       stats = getStats();
       assert "2".equals(stats.get("cmd_set"));
-      assert "2".equals(stats.get("cmd_get"));
+      assert "4".equals(stats.get("cmd_get"));
       assert "2".equals(stats.get("get_hits"));
-      assert "0".equals(stats.get("get_misses"));
+      assert "2".equals(stats.get("get_misses"));
       assert "0".equals(stats.get("delete_hits"));
       assert "0".equals(stats.get("delete_misses"));
       assert "2".equals(stats.get("curr_items"));
@@ -151,7 +151,7 @@
       assert null == client.get(k(m, "k99-"));
       stats = getStats();
       assert "2".equals(stats.get("get_hits"));
-      assert "1".equals(stats.get("get_misses"));
+      assert "3".equals(stats.get("get_misses"));
 
       f = client.delete(k(m, "k99-"));
       assert !f.get(5, TimeUnit.SECONDS);



More information about the infinispan-commits mailing list