@Override
    public List<ClusterNodeInfo> decode(ByteBuf buf, State state) throws IOException {
        String response = buf.toString(CharsetUtil.UTF_8);
        
        List<ClusterNodeInfo> nodes = new ArrayList<>();
        for (String nodeInfo : response.split("\n")) {
            ClusterNodeInfo node = new ClusterNodeInfo(nodeInfo);
            String[] params = nodeInfo.split(" ");

            String nodeId = params[0];
            node.setNodeId(nodeId);

            String flags = params[2];
            for (String flag : flags.split(",")) {
                for (Flag nodeInfoFlag : ClusterNodeInfo.Flag.values()) {
                    if (nodeInfoFlag.getValue().equalsIgnoreCase(flag)) {
                        node.addFlag(nodeInfoFlag);
                        break;
                    }
                }
            }
            
            if (!node.containsFlag(Flag.NOADDR)) {
                String protocol = "redis://";
                if (ssl) {
                    protocol = "rediss://";
                }
                
                String addr = params[1].split("@")[0];
                String name = addr.substring(0, addr.lastIndexOf(":"));
                if (name.isEmpty()) {
                    // skip nodes with empty address
                    continue;
                }
                String uri = protocol + addr;
                node.setAddress(uri);
            }

            String slaveOf = params[3];
            if (!"-".equals(slaveOf)) {
                node.setSlaveOf(slaveOf);
            }

            if (params.length > 8) {
                for (int i = 0; i < params.length - 8; i++) {
                    String slots = params[i + 8];
                    if (slots.contains("-<-") || slots.contains("->-")) {
                        continue;
                    }

                    String[] parts = slots.split("-");
                    if (parts.length == 1) {
                        node.addSlotRange(new ClusterSlotRange(Integer.valueOf(parts[0]), Integer.valueOf(parts[0])));
                    } else if (parts.length == 2) {
                        node.addSlotRange(new ClusterSlotRange(Integer.valueOf(parts[0]), Integer.valueOf(parts[1])));
                    }
                }
            }
            nodes.add(node);
        }
        return nodes;
    }
@Test
    public void test() throws IOException {
        ClusterNodesDecoder decoder = new ClusterNodesDecoder(false);
        ByteBuf buf = Unpooled.buffer();
        
        String info = "7af253f8c20a3b3fbd481801bd361ec6643c6f0b 192.168.234.129:7001@17001 master - 0 1478865073260 8 connected 5461-10922\n" +
        "a0d6a300f9f3b139c89cf45b75dbb7e4a01bb6b5 192.168.234.131:7005@17005 slave 5b00efb410f14ba5bb0a153c057e431d9ee4562e 0 1478865072251 5 connected\n" +
        "454b8aaab7d8687822923da37a91fc0eecbe7a88 192.168.234.130:7002@17002 slave 7af253f8c20a3b3fbd481801bd361ec6643c6f0b 0 1478865072755 8 connected\n" +
        "5b00efb410f14ba5bb0a153c057e431d9ee4562e 192.168.234.131:7004@17004 master - 0 1478865071746 5 connected 10923-16383\n" +
        "14edcdebea55853533a24d5cdc560ecc06ec5295 192.168.234.130:7003@17003 myself,master - 0 0 7 connected 0-5460\n" +
        "58d9f7c6d801aeebaf0e04e1aacb991e7e0ca8ff 192.168.234.129:7000@17000 slave 14edcdebea55853533a24d5cdc560ecc06ec5295 0 1478865071241 7 connected\n";
        
        byte[] src = info.getBytes();
        buf.writeBytes(src);
        List<ClusterNodeInfo> nodes = decoder.decode(buf, null);
        ClusterNodeInfo node = nodes.get(0);
        Assertions.assertEquals("192.168.234.129", node.getAddress().getHost());
        Assertions.assertEquals(7001, node.getAddress().getPort());
    }