if (_addReplyToBuffer(c,obj->ptr,sdslen(obj->ptr)) != REDIS_OK)
             _addReplyObjectToList(c,obj);
     } else {
+        /* FIXME: convert the long into string and use _addReplyToBuffer()
+         * instead of calling getDecodedObject. As this place in the
+         * code is too performance critical. */
         obj = getDecodedObject(obj);
         if (_addReplyToBuffer(c,obj->ptr,sdslen(obj->ptr)) != REDIS_OK)
             _addReplyObjectToList(c,obj);
     }
 }
 
+/* Add a duble as a bulk reply */
 void addReplyDouble(redisClient *c, double d) {
     char dbuf[128], sbuf[128];
     int dlen, slen;
     addReplyString(c,sbuf,slen);
 }
 
+/* Add a long long as integer reply or bulk len / multi bulk count.
+ * Basically this is used to output <prefix><long long><crlf>. */
 void _addReplyLongLong(redisClient *c, long long ll, char prefix) {
     char buf[128];
     int len;
     _addReplyLongLong(c,length,'*');
 }
 
+/* Create the length prefix of a bulk reply, example: $2234 */
 void addReplyBulkLen(redisClient *c, robj *obj) {
     size_t len;
 
     _addReplyLongLong(c,len,'$');
 }
 
+/* Add a Redis Object as a bulk reply */
 void addReplyBulk(redisClient *c, robj *obj) {
     addReplyBulkLen(c,obj);
     addReply(c,obj);
     addReply(c,shared.crlf);
 }
 
-/* In the CONFIG command we need to add vanilla C string as bulk replies */
+/* Add a C buffer as bulk reply */
+void addReplyBulkCBuffer(redisClient *c, void *p, size_t len) {
+    _addReplyLongLong(c,len,'$');
+    addReplyString(c,p,len);
+    addReply(c,shared.crlf);
+}
+
+/* Add a C nul term string as bulk reply */
 void addReplyBulkCString(redisClient *c, char *s) {
     if (s == NULL) {
         addReply(c,shared.nullbulk);
     } else {
-        robj *o = createStringObject(s,strlen(s));
-        addReplyBulk(c,o);
-        decrRefCount(o);
+        addReplyBulkCBuffer(c,s,strlen(s));
     }
 }
 
+/* Add a long long as a bulk reply */
+void addReplyBulkLongLong(redisClient *c, long long ll) {
+    char buf[64];
+    int len;
+
+    len = ll2string(buf,64,ll);
+    addReplyBulkCBuffer(c,buf,len);
+}
+
 static void acceptCommonHandler(int fd) {
     redisClient *c;
     if ((c = createClient(fd)) == NULL) {
 
 void readQueryFromClient(aeEventLoop *el, int fd, void *privdata, int mask);
 void addReplyBulk(redisClient *c, robj *obj);
 void addReplyBulkCString(redisClient *c, char *s);
+void addReplyBulkCBuffer(redisClient *c, void *p, size_t len);
+void addReplyBulkLongLong(redisClient *c, long long ll);
 void acceptHandler(aeEventLoop *el, int fd, void *privdata, int mask);
 void addReply(redisClient *c, robj *obj);
 void addReplySds(redisClient *c, sds s);
 
 }
 
 void lrangeCommand(redisClient *c) {
-    robj *o, *value;
+    robj *o;
     int start = atoi(c->argv[2]->ptr);
     int end = atoi(c->argv[3]->ptr);
     int llen;
-    int rangelen, j;
-    listTypeEntry entry;
+    int rangelen;
 
     if ((o = lookupKeyReadOrReply(c,c->argv[1],shared.emptymultibulk)) == NULL
          || checkType(c,o,REDIS_LIST)) return;
 
     /* Return the result in form of a multi-bulk reply */
     addReplyMultiBulkLen(c,rangelen);
-    listTypeIterator *li = listTypeInitIterator(o,start,REDIS_TAIL);
-    for (j = 0; j < rangelen; j++) {
-        redisAssert(listTypeNext(li,&entry));
-        value = listTypeGet(&entry);
-        addReplyBulk(c,value);
-        decrRefCount(value);
+    if (o->encoding == REDIS_ENCODING_ZIPLIST) {
+        unsigned char *p = ziplistIndex(o->ptr,start);
+        unsigned char *vstr;
+        unsigned int vlen;
+        long long vlong;
+
+        while(rangelen--) {
+            ziplistGet(p,&vstr,&vlen,&vlong);
+            if (vstr) {
+                addReplyBulkCBuffer(c,vstr,vlen);
+            } else {
+                addReplyBulkLongLong(c,vlong);
+            }
+            p = ziplistNext(o->ptr,p);
+        }
+    } else if (o->encoding == REDIS_ENCODING_LINKEDLIST) {
+        listNode *ln = listIndex(o->ptr,start);
+
+        while(rangelen--) {
+            addReplyBulk(c,ln->value);
+            ln = ln->next;
+        }
+    } else {
+        redisPanic("List encoding is not LINKEDLIST nor ZIPLIST!");
     }
-    listTypeReleaseIterator(li);
 }
 
 void ltrimCommand(redisClient *c) {