public void insertCTCPColoredString(String[] line, Style givenStyle) throws BadLocationException {
        GUI.ctcpStyle = GUI.sc.addStyle("Defaultstyle", givenStyle);
        if (GUI.showTimestamp) {
            String timestamp = makeTimestamp();
            this.insertString(chatPane.getStyledDocument().getLength(), "\n[" + timestamp + "] ", GUI.timestampStyle);
        } else this.insertString(chatPane.getStyledDocument().getLength(), "\n", GUI.style);
        //if (!GUI.chatNameColors && line[0] != null) this.insertString(chatPane.getStyledDocument().getLength(), "<" + line[0] + ">: ", GUI.chatStyle);
        if (line[0] != null) {
            Color c = getUserColor(line[0]);
            this.insertString(chatPane.getStyledDocument().getLength(), "<", GUI.style);
            StyleConstants.setForeground(GUI.userNameStyle, c);
            this.insertString(chatPane.getStyledDocument().getLength(), line[0], GUI.userNameStyle);
            this.insertString(chatPane.getStyledDocument().getLength(), ">: ", GUI.style);
        }

        Pattern pattern;
        Matcher matcher;

        StringTokenizer st = new StringTokenizer(line[1], Connection.HTTP_DELIM + Connection.CTCP_DELIM + Connection.CTCP_COLOR_DELIM + Connection.CTCP_UNDERLINE_DELIM + Connection.CTCP_BOLD_DELIM + Connection.CTCP_RESET_DELIM, true);
        while (st.hasMoreTokens()) {
            String token = st.nextToken();
            if (token.equals(Connection.CTCP_DELIM)) {
                continue;
            }
            if (token.equals(Connection.CTCP_BOLD_DELIM)) {
                StyleConstants.setBold(GUI.ctcpStyle, !StyleConstants.isBold(GUI.ctcpStyle));
                continue;
            }
            if (token.equals(Connection.CTCP_UNDERLINE_DELIM)) {
                StyleConstants.setUnderline(GUI.ctcpStyle, !StyleConstants.isUnderline(GUI.ctcpStyle));
                continue;
            }
            if (token.equals(Connection.CTCP_RESET_DELIM)) {
                GUI.ctcpStyle = GUI.sc.addStyle("Defaultstyle", givenStyle);
                continue;
            }
            if (token.equals(Connection.HTTP_DELIM)) {
                if (st.hasMoreTokens()) token = st.nextToken();
                if (token.startsWith(" #")) {
                    token = token.substring(1);
                }
                if (token.startsWith("#")) //hyperlinking a channel
                {
                    int[] ind = {token.indexOf('.'), //disallowed irc channel characters
                            token.indexOf(','),
                            token.indexOf(':'),
                            token.indexOf(';'),
                            token.indexOf('<'),
                            token.indexOf('>'),
                            token.indexOf('?'),
                            token.indexOf('/'),
                            token.indexOf('\''),
                            token.indexOf('"'),
                            token.indexOf(' ')
                    };

                    int min = Integer.MAX_VALUE;
                    for (int anInd : ind) {
                        if (anInd == -1) continue;
                        min = Math.min(anInd, min);
                    }
                    if (min == Integer.MAX_VALUE) {
                        this.insertString(chatPane.getStyledDocument().getLength(), token, GUI.hyperlinkUnclickedStyle);
                        continue;
                    }
                    String channel = token.substring(0, min);
                    this.insertString(chatPane.getStyledDocument().getLength(), channel, GUI.hyperlinkUnclickedStyle);
                    String rest = token.substring(min);
                    this.insertString(chatPane.getStyledDocument().getLength(), rest, GUI.ctcpStyle);
                    continue;
                } else //hyperlinking a URL
                {
                    int[] ind = {token.indexOf('"'), //disallowed URL characters
                            token.indexOf('`'),
                            token.indexOf(']'),
                            token.indexOf('['),
                            token.indexOf('>'),
                            token.indexOf('<'),
                            token.indexOf(','),
                            token.indexOf('('),
                            token.indexOf(')'),
                            token.indexOf('{'),
                            token.indexOf('}'),
                            token.indexOf(' ')
                    };

                    int min = Integer.MAX_VALUE;
                    for (int anInd : ind) {
                        if (anInd == -1) continue;
                        min = Math.min(anInd, min);
                    }
                    if (min == Integer.MAX_VALUE) {
                        this.insertString(chatPane.getStyledDocument().getLength(), token, GUI.hyperlinkUnclickedStyle);
                        continue;
                    }
                    String url = token.substring(0, min);
                    this.insertString(chatPane.getStyledDocument().getLength(), url, GUI.hyperlinkUnclickedStyle);
                    String rest = token.substring(min);
                    this.insertString(chatPane.getStyledDocument().getLength(), rest, GUI.ctcpStyle);
                    continue;
                }
            }
            if (token.equals(Connection.CTCP_COLOR_DELIM)) {
                if (st.hasMoreTokens()) {
                    token = st.nextToken();
                    pattern = Pattern.compile("(\\d{1,2}+)(,?+)(\\d{1,2}+)(.+)|(\\d{1,2})(,)(.*)|(,?+)(\\d{1,2}+)(.+)");
                    matcher = pattern.matcher(token);
                    String foreground;
                    String background;
                    String message;

                    if (!StringUtils.isNumeric(token.substring(0, 1)) && !token.startsWith(",")) {
                        this.insertString(chatPane.getStyledDocument().getLength(), token, GUI.chatStyle);
                        continue;
                    }
                    while (matcher.find()) {
                        if (matcher.group(8) != null && matcher.group(8).equals(",")) //invalid (ex. ,5this is a message) prints plain
                        {
                            message = matcher.group(10);
                            this.insertString(chatPane.getStyledDocument().getLength(), message, GUI.ctcpStyle);
                            continue;
                        }
                        if (matcher.group(6) != null && matcher.group(6).equals(",")) //foreground color, no bg color (ex. 5,this is a message)
                        {
                            foreground = matcher.group(5);
                            message = matcher.group(7);
                            Color f = GUI.CTCPMap.get(Integer.valueOf(foreground));
                            StyleConstants.setForeground(GUI.ctcpStyle, f);
                            this.insertString(chatPane.getStyledDocument().getLength(), message, GUI.ctcpStyle);
                            continue;
                        }
                        if (matcher.group(8) != null && matcher.group(8).equals("")) //foreground color, no bg color (ex. 5this is a message)
                        {
                            foreground = matcher.group(9);
                            message = matcher.group(10);
                            Color f = GUI.CTCPMap.get(Integer.valueOf(foreground));
                            StyleConstants.setForeground(GUI.ctcpStyle, f);
                            this.insertString(chatPane.getStyledDocument().getLength(), message, GUI.ctcpStyle);
                            continue;
                        }
                        if (matcher.group(2) != null && matcher.group(2).equals("")) //foreground color, no bg color, but followed by a number, ie 53 blind mice
                        {
                            foreground = matcher.group(1);
                            message = matcher.group(3) + matcher.group(4);
                            Color f = GUI.CTCPMap.get(Integer.valueOf(foreground));
                            StyleConstants.setForeground(GUI.ctcpStyle, f);
                            this.insertString(chatPane.getStyledDocument().getLength(), message, GUI.ctcpStyle);
                            continue;
                        }
                        if (matcher.group(2) != null && matcher.group(2).equals(",")) //foreground and background (ex. 5,5this is a message)
                        {
                            foreground = matcher.group(1);
                            background = matcher.group(3);
                            message = matcher.group(4);
                            Color f = GUI.CTCPMap.get(Integer.valueOf(foreground));
                            Color b = GUI.CTCPMap.get(Integer.valueOf(background));
                            StyleConstants.setForeground(GUI.ctcpStyle, f);
                            StyleConstants.setBackground(GUI.ctcpStyle, b);
                            this.insertString(chatPane.getStyledDocument().getLength(), message, GUI.ctcpStyle);
                        }
                    }
                }
            } else {
                this.insertString(chatPane.getStyledDocument().getLength(), token, GUI.ctcpStyle);
            }
        }
    }