class RadixTree {

    public void insert(String key, String value) {
        if (key == null || key.isEmpty()) {
            throw new IllegalArgumentException(_strings.get("errorInEmptyNullKeyInstertion"));
        }
        char[] inputChars = key.toCharArray();
        int noOfMatchedChars = 0;
        RadixTreeNode node = _rootNode;
        RadixTreeNode newNode = null;
        int keyLength = inputChars.length;
        OUTER_LOOP : while (noOfMatchedChars < keyLength) {
            String nodeKey = node.getKey();
            int i = 0;
            int maxLoop = nodeKey.length() > (keyLength - noOfMatchedChars) ? keyLength - noOfMatchedChars :
                nodeKey.length();
            for (; i < maxLoop ; i++) {
                if (nodeKey.charAt(i) != inputChars[noOfMatchedChars]) {
                    // e.g new key/value : successive/successive
                    // before, 
                    // |-node (key: successful, value: successful)
                    // | |-node_childs...
                    //after...
                    // |-newNode (key: success, value: "")
                    // | |-node (key: ful, value: successful)
                    // | | |-node_childs...
                    // | |-secondNewNode (key: ive, value: successive)
                    newNode = new RadixTreeNode(nodeKey.substring(0, i), null);
                    RadixTreeNode parentNode = node.getParentNode();
                    parentNode.removeChildNode(node);
                    parentNode.addChildNode(newNode);
                    node.setKey(nodeKey.substring(i));
                    newNode.addChildNode(node);
                    newNode.addChildNode(new RadixTreeNode(key.substring(noOfMatchedChars), value));
                    break OUTER_LOOP;
                }
                noOfMatchedChars++;
            }

            // If the given key is smaller than the matched node key
            if (nodeKey.length() > maxLoop) {
                // e.g new key/value : acid/acid
                // before, 
                // |-node (key: acidic, value: acidic)
                // | |-node_childs...
                //after...
                // |-newNode (key: acid, value: acid)
                // | |-node (key: ic, value: acidic)
                // | | |-node_childs...
                newNode = new RadixTreeNode(nodeKey.substring(0, i), value);
                RadixTreeNode parentNode = node.getParentNode();
                parentNode.removeChildNode(node);
                parentNode.addChildNode(newNode);
                node.setKey(nodeKey.substring(i));
                newNode.addChildNode(node);
                break;
            }

            if (noOfMatchedChars == keyLength) {
                if (node.getValue() != null && !node.getValue().isEmpty()) {
                    _logger.log(Level.INFO, SLogger.CHANGE_IN_VALUE, new Object[] {node.getValue(), value});
                }
                node.setValue(value);
                break;
            }

            RadixTreeNode matchedNode = node.getChildNode(inputChars[noOfMatchedChars]);
            // Add as a child node if no match found.
            if (matchedNode == null) {
                node.addChildNode(new RadixTreeNode(key.substring(noOfMatchedChars), value));
                break;
            }
            node = matchedNode;
        } 
    }

    public  RadixTree();

}