public static Object[] parseKey(HollowReadStateEngine readStateEngine, PrimaryKey primaryKey, String keyString) {
        /**
         * Split by the number of fields of the primary key. This ensures correct extraction of an empty value for the last field.
         * Escape the delimiter if it is preceded by a backslash.
         */
        String fields[] = keyString.split("(?<!\\\\)" + MULTI_FIELD_KEY_DELIMITER, primaryKey.numFields());

        Object key[] = new Object[fields.length];

        for(int i=0;i<fields.length;i++) {
            switch(primaryKey.getFieldType(readStateEngine, i)) {
                case BOOLEAN:
                    key[i] = Boolean.parseBoolean(fields[i]);
                    break;
                case STRING:
                    key[i] = fields[i].replaceAll(ESCAPED_MULTI_FIELD_KEY_DELIMITER, MULTI_FIELD_KEY_DELIMITER);
                    break;
                case INT:
                case REFERENCE:
                    key[i] = Integer.parseInt(fields[i]);
                    break;
                case LONG:
                    key[i] = Long.parseLong(fields[i]);
                    break;
                case DOUBLE:
                    key[i] = Double.parseDouble(fields[i]);
                    break;
                case FLOAT:
                    key[i] = Float.parseFloat(fields[i]);
                    break;
                case BYTES:
                    throw new IllegalArgumentException("Primary key contains a field of type BYTES");
            }
        }
        return key;
    }
@Test
    public void testParseKey() {
        String keyString = "a:b";
        Object[] key = SearchUtils.parseKey(stateEngine, primaryKey, keyString);
        assertEquals(2, key.length);
        assertEquals("a", key[0]);
        assertEquals("b", key[1]);

        // two fields, where the second field contains a ':' char
        // NOTE that this split based on delimiter works even without escaping the delimiter because
        // string split is performed based on no. of fields in the key. So if delimiter exists in the
        // last field then the parsing logic doesn't break
        keyString = "a:b1:b2";
        key = SearchUtils.parseKey(stateEngine, primaryKey, keyString);
        assertEquals(2, key.length);
        assertEquals("a", key[0]);
        assertEquals("b1:b2", key[1]);

        // again two fields, where the second field contains a ':' char
        keyString = "a:b1\\:b2";
        key = SearchUtils.parseKey(stateEngine, primaryKey, keyString);
        assertEquals(2, key.length);
        assertEquals("a", key[0]);
        assertEquals("b1:b2", key[1]);

        // two fields, where the first field contains a ':' char
        keyString = "a1\\:a2:b";
        key = SearchUtils.parseKey(stateEngine, primaryKey, keyString);
        assertEquals(2, key.length);
        assertEquals("a1:a2", key[0]);
        assertEquals("b", key[1]);
    }