// Path: src/main/java/com/groupon/vertx/memcache/MemcacheException.java
// public class MemcacheException extends RuntimeException {
//     private static final long serialVersionUID = -386882705199382789L;
// 
//     public MemcacheException(String message) {
//         super(message);
//     }
// }
// 
// Path: src/main/java/com/groupon/vertx/memcache/client/JsendStatus.java
// public enum JsendStatus {
//     success,
//     error,
//     fail;
// }
// 
// Path: src/main/java/com/groupon/vertx/memcache/client/response/RetrieveCommandResponse.java
// public final class RetrieveCommandResponse extends MemcacheCommandResponse {
//     private final Map<String, String> data;
// 
//     private RetrieveCommandResponse(Builder builder) {
//         super(builder);
//         data = Collections.unmodifiableMap(new HashMap<>(builder.data));
//     }
// 
//     public Map<String, String> getData() {
//         return data;
//     }
// 
//     /**
//      * Builder for the RetrieveCommandResponse
//      */
//     public static class Builder extends AbstractBuilder<Builder, RetrieveCommandResponse> {
//         private Map<String, String> data = new HashMap<>();
// 
//         @Override
//         protected Builder self() {
//             return this;
//         }
// 
//         public Builder setData(Map<String, String> value) {
//             if (value == null) {
//                 data = new HashMap<>();
//             } else {
//                 data = value;
//             }
//             return self();
//         }
// 
//         public Builder addData(String key, String value) {
//             data.put(key, value);
//             return self();
//         }
// 
//         @Override
//         public RetrieveCommandResponse build() {
//             return new RetrieveCommandResponse(this);
//         }
//     }
// }
// 
// Path: src/main/java/com/groupon/vertx/memcache/stream/MemcacheResponseType.java
// public enum MemcacheResponseType {
//     VALUE("VALUE ", false),
//     STORED("STORED", true),
//     DELETED("DELETED", true),
//     TOUCHED("TOUCHED", true),
//     NOT_STORED("NOT_STORED", true),
//     EXISTS("EXISTS", true),
//     NOT_FOUND("NOT_FOUND", true),
//     END("END", true),
//     ERROR("ERROR", true),
//     CLIENT_ERROR("CLIENT ERROR", false),
//     SERVER_ERROR("SERVER ERROR", false);
// 
//     public final String type;
//     public final boolean exact;
// 
//     MemcacheResponseType(String type, boolean exact) {
//         this.type = type;
//         this.exact = exact;
//     }
// 
//     public boolean matches(ByteArrayOutputStream line) {
//         boolean match;
//         try {
//             if (!exact) {
//                 match = line.toString("UTF-8").startsWith(type);
//             } else {
//                 match = line.toString("UTF-8").equals(type);
//             }
//         } catch (UnsupportedEncodingException e) {
//             match = false;
//         }
//         return match;
//     }
// }


import java.io.ByteArrayOutputStream;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import com.groupon.vertx.memcache.MemcacheException;
import com.groupon.vertx.memcache.client.JsendStatus;
import com.groupon.vertx.memcache.client.response.RetrieveCommandResponse;
import com.groupon.vertx.memcache.stream.MemcacheResponseType;
import com.groupon.vertx.utils.Logger;
    private static final int VALUE_KEY_INDEX = 1;
    private static final int VALUE_LENGTH_INDEX = 3;

    private String expectedKey;
    private byte[] expectedBytes;
    private int bytesRetrieved = 0;

    private RetrieveCommandResponse.Builder builder;

    public RetrieveLineParser() {
        builder = new RetrieveCommandResponse.Builder();
    }

    @Override
    protected RetrieveCommandResponse.Builder getResponseBuilder() {
        return builder;
    }

    @Override
    public boolean isResponseEnd(ByteArrayOutputStream line) {
        boolean match = super.isResponseEnd(line);
        if (match) {
            return true;
        }

        MemcacheResponseType type = getResponseType(RESPONSE_TYPES, line);
        if (type != null) {
            switch (type) {
                case END:
                    builder.setStatus(JsendStatus.success);
// Path: src/main/java/com/groupon/vertx/memcache/MemcacheException.java
// public class MemcacheException extends RuntimeException {
//     private static final long serialVersionUID = -386882705199382789L;
// 
//     public MemcacheException(String message) {
//         super(message);
//     }
// }
// 
// Path: src/main/java/com/groupon/vertx/memcache/client/JsendStatus.java
// public enum JsendStatus {
//     success,
//     error,
//     fail;
// }
// 
// Path: src/main/java/com/groupon/vertx/memcache/client/response/RetrieveCommandResponse.java
// public final class RetrieveCommandResponse extends MemcacheCommandResponse {
//     private final Map<String, String> data;
// 
//     private RetrieveCommandResponse(Builder builder) {
//         super(builder);
//         data = Collections.unmodifiableMap(new HashMap<>(builder.data));
//     }
// 
//     public Map<String, String> getData() {
//         return data;
//     }
// 
//     /**
//      * Builder for the RetrieveCommandResponse
//      */
//     public static class Builder extends AbstractBuilder<Builder, RetrieveCommandResponse> {
//         private Map<String, String> data = new HashMap<>();
// 
//         @Override
//         protected Builder self() {
//             return this;
//         }
// 
//         public Builder setData(Map<String, String> value) {
//             if (value == null) {
//                 data = new HashMap<>();
//             } else {
//                 data = value;
//             }
//             return self();
//         }
// 
//         public Builder addData(String key, String value) {
//             data.put(key, value);
//             return self();
//         }
// 
//         @Override
//         public RetrieveCommandResponse build() {
//             return new RetrieveCommandResponse(this);
//         }
//     }
// }
// 
// Path: src/main/java/com/groupon/vertx/memcache/stream/MemcacheResponseType.java
// public enum MemcacheResponseType {
//     VALUE("VALUE ", false),
//     STORED("STORED", true),
//     DELETED("DELETED", true),
//     TOUCHED("TOUCHED", true),
//     NOT_STORED("NOT_STORED", true),
//     EXISTS("EXISTS", true),
//     NOT_FOUND("NOT_FOUND", true),
//     END("END", true),
//     ERROR("ERROR", true),
//     CLIENT_ERROR("CLIENT ERROR", false),
//     SERVER_ERROR("SERVER ERROR", false);
// 
//     public final String type;
//     public final boolean exact;
// 
//     MemcacheResponseType(String type, boolean exact) {
//         this.type = type;
//         this.exact = exact;
//     }
// 
//     public boolean matches(ByteArrayOutputStream line) {
//         boolean match;
//         try {
//             if (!exact) {
//                 match = line.toString("UTF-8").startsWith(type);
//             } else {
//                 match = line.toString("UTF-8").equals(type);
//             }
//         } catch (UnsupportedEncodingException e) {
//             match = false;
//         }
//         return match;
//     }
// }


// Path: src/main/java/com/groupon/vertx/memcache/parser/RetrieveLineParser.java
import java.io.ByteArrayOutputStream;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import com.groupon.vertx.memcache.MemcacheException;
import com.groupon.vertx.memcache.client.JsendStatus;
import com.groupon.vertx.memcache.client.response.RetrieveCommandResponse;
import com.groupon.vertx.memcache.stream.MemcacheResponseType;
import com.groupon.vertx.utils.Logger;

    private static final int VALUE_KEY_INDEX = 1;
    private static final int VALUE_LENGTH_INDEX = 3;

    private String expectedKey;
    private byte[] expectedBytes;
    private int bytesRetrieved = 0;

    private RetrieveCommandResponse.Builder builder;

    public RetrieveLineParser() {
        builder = new RetrieveCommandResponse.Builder();
    }

    @Override
    protected RetrieveCommandResponse.Builder getResponseBuilder() {
        return builder;
    }

    @Override
    public boolean isResponseEnd(ByteArrayOutputStream line) {
        boolean match = super.isResponseEnd(line);
        if (match) {
            return true;
        }

        MemcacheResponseType type = getResponseType(RESPONSE_TYPES, line);
        if (type != null) {
            switch (type) {
                case END:
                    builder.setStatus(JsendStatus.success);
                    match = true;