//# 19 errors, 659 messages
//#
package org.apache.roller.weblogger.util;
    //#Utilities.java:1:1: class: org.apache.roller.weblogger.util.Utilities

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.NoSuchElementException;
import java.util.StringTokenizer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.codec.binary.Base64;
import org.apache.roller.util.RegexUtil;

        
/**
 * General purpose utilities, not for use in templates.
 */
public class Utilities {
    //#Utilities.java:35: method: void org.apache.roller.weblogger.util.Utilities.org.apache.roller.weblogger.util.Utilities()
    //#Utilities.java:35: end of method: void org.apache.roller.weblogger.util.Utilities.org.apache.roller.weblogger.util.Utilities()
    /** The <code>Log</code> instance for this class. */
    private static Log mLogger = LogFactory.getLog(Utilities.class);
    //#Utilities.java:37: method: org.apache.roller.weblogger.util.Utilities.org.apache.roller.weblogger.util.Utilities__static_init
    //#Utilities.java:37: Warning: method not available
    //#    -- call on Log org.apache.commons.logging.LogFactory:getLog(Class)
    //#    severity: INFORMATIONAL
    //#    class: org.apache.roller.weblogger.util.Utilities
    //#    method: org.apache.roller.weblogger.util.Utilities__static_init
    //#    unanalyzed callee: Log org.apache.commons.logging.LogFactory:getLog(Class)
    //#output(org.apache.roller.weblogger.util.Utilities__static_init): BR_TAG_PATTERN
    //#output(org.apache.roller.weblogger.util.Utilities__static_init): CLOSING_A_TAG_PATTERN
    //#output(org.apache.roller.weblogger.util.Utilities__static_init): CLOSING_BLOCKQUOTE_TAG_PATTERN
    //#output(org.apache.roller.weblogger.util.Utilities__static_init): CLOSING_B_TAG_PATTERN
    //#output(org.apache.roller.weblogger.util.Utilities__static_init): CLOSING_I_TAG_PATTERN
    //#output(org.apache.roller.weblogger.util.Utilities__static_init): CLOSING_LI_TAG_PATTERN
    //#output(org.apache.roller.weblogger.util.Utilities__static_init): CLOSING_OL_TAG_PATTERN
    //#output(org.apache.roller.weblogger.util.Utilities__static_init): CLOSING_PRE_TAG_PATTERN
    //#output(org.apache.roller.weblogger.util.Utilities__static_init): CLOSING_P_TAG_PATTERN
    //#output(org.apache.roller.weblogger.util.Utilities__static_init): CLOSING_UL_TAG_PATTERN
    //#output(org.apache.roller.weblogger.util.Utilities__static_init): OPENING_A_TAG_PATTERN
    //#output(org.apache.roller.weblogger.util.Utilities__static_init): OPENING_BLOCKQUOTE_TAG_PATTERN
    //#output(org.apache.roller.weblogger.util.Utilities__static_init): OPENING_B_TAG_PATTERN
    //#output(org.apache.roller.weblogger.util.Utilities__static_init): OPENING_I_TAG_PATTERN
    //#output(org.apache.roller.weblogger.util.Utilities__static_init): OPENING_LI_TAG_PATTERN
    //#output(org.apache.roller.weblogger.util.Utilities__static_init): OPENING_OL_TAG_PATTERN
    //#output(org.apache.roller.weblogger.util.Utilities__static_init): OPENING_PRE_TAG_PATTERN
    //#output(org.apache.roller.weblogger.util.Utilities__static_init): OPENING_P_TAG_PATTERN
    //#output(org.apache.roller.weblogger.util.Utilities__static_init): OPENING_UL_TAG_PATTERN
    //#output(org.apache.roller.weblogger.util.Utilities__static_init): QUOTE_PATTERN
    //#output(org.apache.roller.weblogger.util.Utilities__static_init): __Descendant_Table[org/apache/roller/weblogger/util/Utilities]
    //#output(org.apache.roller.weblogger.util.Utilities__static_init): mLinkPattern
    //#output(org.apache.roller.weblogger.util.Utilities__static_init): mLogger
    //#post(org.apache.roller.weblogger.util.Utilities__static_init): init'ed(BR_TAG_PATTERN)
    //#post(org.apache.roller.weblogger.util.Utilities__static_init): init'ed(CLOSING_A_TAG_PATTERN)
    //#post(org.apache.roller.weblogger.util.Utilities__static_init): init'ed(CLOSING_BLOCKQUOTE_TAG_PATTERN)
    //#post(org.apache.roller.weblogger.util.Utilities__static_init): init'ed(CLOSING_B_TAG_PATTERN)
    //#post(org.apache.roller.weblogger.util.Utilities__static_init): init'ed(CLOSING_I_TAG_PATTERN)
    //#post(org.apache.roller.weblogger.util.Utilities__static_init): init'ed(CLOSING_LI_TAG_PATTERN)
    //#post(org.apache.roller.weblogger.util.Utilities__static_init): init'ed(CLOSING_OL_TAG_PATTERN)
    //#post(org.apache.roller.weblogger.util.Utilities__static_init): init'ed(CLOSING_PRE_TAG_PATTERN)
    //#post(org.apache.roller.weblogger.util.Utilities__static_init): init'ed(CLOSING_P_TAG_PATTERN)
    //#post(org.apache.roller.weblogger.util.Utilities__static_init): init'ed(CLOSING_UL_TAG_PATTERN)
    //#post(org.apache.roller.weblogger.util.Utilities__static_init): init'ed(OPENING_A_TAG_PATTERN)
    //#post(org.apache.roller.weblogger.util.Utilities__static_init): init'ed(OPENING_BLOCKQUOTE_TAG_PATTERN)
    //#post(org.apache.roller.weblogger.util.Utilities__static_init): init'ed(OPENING_B_TAG_PATTERN)
    //#post(org.apache.roller.weblogger.util.Utilities__static_init): init'ed(OPENING_I_TAG_PATTERN)
    //#post(org.apache.roller.weblogger.util.Utilities__static_init): init'ed(OPENING_LI_TAG_PATTERN)
    //#post(org.apache.roller.weblogger.util.Utilities__static_init): init'ed(OPENING_OL_TAG_PATTERN)
    //#post(org.apache.roller.weblogger.util.Utilities__static_init): init'ed(OPENING_PRE_TAG_PATTERN)
    //#post(org.apache.roller.weblogger.util.Utilities__static_init): init'ed(OPENING_P_TAG_PATTERN)
    //#post(org.apache.roller.weblogger.util.Utilities__static_init): init'ed(OPENING_UL_TAG_PATTERN)
    //#post(org.apache.roller.weblogger.util.Utilities__static_init): init'ed(QUOTE_PATTERN)
    //#post(org.apache.roller.weblogger.util.Utilities__static_init): __Descendant_Table[org/apache/roller/weblogger/util/Utilities] == &__Dispatch_Table
    //#post(org.apache.roller.weblogger.util.Utilities__static_init): init'ed(mLinkPattern)
    //#post(org.apache.roller.weblogger.util.Utilities__static_init): init'ed(mLogger)
    
    public final static String TAG_SPLIT_CHARS = " ,\n\r\f\t";
      
    private static Pattern mLinkPattern =
            Pattern.compile("<a href=.*?>", Pattern.CASE_INSENSITIVE);    
    private static final Pattern OPENING_B_TAG_PATTERN = 
            Pattern.compile("&lt;b&gt;", Pattern.CASE_INSENSITIVE);
    private static final Pattern CLOSING_B_TAG_PATTERN = 
            Pattern.compile("&lt;/b&gt;", Pattern.CASE_INSENSITIVE);
    private static final Pattern OPENING_I_TAG_PATTERN = 
            Pattern.compile("&lt;i&gt;", Pattern.CASE_INSENSITIVE);
    private static final Pattern CLOSING_I_TAG_PATTERN = 
            Pattern.compile("&lt;/i&gt;", Pattern.CASE_INSENSITIVE);
    private static final Pattern OPENING_BLOCKQUOTE_TAG_PATTERN = 
            Pattern.compile("&lt;blockquote&gt;", Pattern.CASE_INSENSITIVE);
    private static final Pattern CLOSING_BLOCKQUOTE_TAG_PATTERN = 
            Pattern.compile("&lt;/blockquote&gt;", Pattern.CASE_INSENSITIVE);
    private static final Pattern BR_TAG_PATTERN = 
            Pattern.compile("&lt;br */*&gt;", Pattern.CASE_INSENSITIVE);
    private static final Pattern OPENING_P_TAG_PATTERN = 
            Pattern.compile("&lt;p&gt;", Pattern.CASE_INSENSITIVE);
    private static final Pattern CLOSING_P_TAG_PATTERN = 
            Pattern.compile("&lt;/p&gt;", Pattern.CASE_INSENSITIVE);
    private static final Pattern OPENING_PRE_TAG_PATTERN = 
            Pattern.compile("&lt;pre&gt;", Pattern.CASE_INSENSITIVE);
    private static final Pattern CLOSING_PRE_TAG_PATTERN = 
            Pattern.compile("&lt;/pre&gt;", Pattern.CASE_INSENSITIVE);
    private static final Pattern OPENING_UL_TAG_PATTERN = 
            Pattern.compile("&lt;ul&gt;", Pattern.CASE_INSENSITIVE);
    private static final Pattern CLOSING_UL_TAG_PATTERN = 
            Pattern.compile("&lt;/ul&gt;", Pattern.CASE_INSENSITIVE);
    private static final Pattern OPENING_OL_TAG_PATTERN = 
            Pattern.compile("&lt;ol&gt;", Pattern.CASE_INSENSITIVE);
    private static final Pattern CLOSING_OL_TAG_PATTERN = 
            Pattern.compile("&lt;/ol&gt;", Pattern.CASE_INSENSITIVE);
    private static final Pattern OPENING_LI_TAG_PATTERN = 
            Pattern.compile("&lt;li&gt;", Pattern.CASE_INSENSITIVE);
    private static final Pattern CLOSING_LI_TAG_PATTERN = 
            Pattern.compile("&lt;/li&gt;", Pattern.CASE_INSENSITIVE);
    private static final Pattern CLOSING_A_TAG_PATTERN = 
            Pattern.compile("&lt;/a&gt;", Pattern.CASE_INSENSITIVE);
    private static final Pattern OPENING_A_TAG_PATTERN = 
            Pattern.compile("&lt;a href=.*?&gt;", Pattern.CASE_INSENSITIVE);
    private static final Pattern QUOTE_PATTERN = 
    //#Utilities.java:81: end of method: org.apache.roller.weblogger.util.Utilities.org.apache.roller.weblogger.util.Utilities__static_init
            Pattern.compile("&quot;", Pattern.CASE_INSENSITIVE);
    
    
    //------------------------------------------------------------------------
    /** Strip jsessionid off of a URL */
    public static String stripJsessionId( String url ) {
        // Strip off jsessionid found in referer URL
        int startPos = url.indexOf(";jsessionid=");
    //#Utilities.java:89: method: String org.apache.roller.weblogger.util.Utilities.stripJsessionId(String)
    //#input(String stripJsessionId(String)): url
    //#input(String stripJsessionId(String)): url._tainted
    //#output(String stripJsessionId(String)): java.lang.String:substring(...)._tainted
    //#output(String stripJsessionId(String)): java.lang.StringBuilder:toString(...)._tainted
    //#output(String stripJsessionId(String)): return_value
    //#new obj(String stripJsessionId(String)): java.lang.String:substring(...)
    //#new obj(String stripJsessionId(String)): java.lang.StringBuilder:toString(...)
    //#pre[1] (String stripJsessionId(String)): url != null
    //#post(String stripJsessionId(String)): init'ed(java.lang.String:substring(...)._tainted)
    //#post(String stripJsessionId(String)): init'ed(java.lang.StringBuilder:toString(...)._tainted)
    //#post(String stripJsessionId(String)): return_value == One-of{url, &java.lang.String:substring(...), &java.lang.StringBuilder:toString(...)}
    //#post(String stripJsessionId(String)): return_value != null
    //#test_vector(String stripJsessionId(String)): java.lang.String:indexOf(...)@89: {-1}, {-2_147_483_648..-2, 0..4_294_967_295}
    //#test_vector(String stripJsessionId(String)): java.lang.String:indexOf(...)@91: {-2_147_483_648..-2, 0..4_294_967_295}, {-1}
        if ( startPos != -1 ) {
            int endPos = url.indexOf("?",startPos);
            if ( endPos == -1 ) {
                url = url.substring(0,startPos);
            } else {
                url = url.substring(0,startPos)
                + url.substring(endPos,url.length());
            }
        }
        return url;
    //#Utilities.java:99: end of method: String org.apache.roller.weblogger.util.Utilities.stripJsessionId(String)
    }
    
    //------------------------------------------------------------------------
    /**
     * Escape, but do not replace HTML.
     * The default behaviour is to escape ampersands.
     */
    public static String escapeHTML(String s) {
        return escapeHTML(s, true);
    //#Utilities.java:108: method: String org.apache.roller.weblogger.util.Utilities.escapeHTML(String)
    //#input(String escapeHTML(String)): s
    //#output(String escapeHTML(String)): return_value
    //#post(String escapeHTML(String)): init'ed(return_value)
    //#unanalyzed(String escapeHTML(String)): Effects-of-calling:org.apache.commons.lang.StringUtils:replace
    //#Utilities.java:108: end of method: String org.apache.roller.weblogger.util.Utilities.escapeHTML(String)
    }
    
    //------------------------------------------------------------------------
    /**
     * Escape, but do not replace HTML.
     * @param escapeAmpersand Optionally escape
     * ampersands (&amp;).
     */
    public static String escapeHTML(String s, boolean escapeAmpersand) {
        // got to do amp's first so we don't double escape
        if (escapeAmpersand) {
    //#Utilities.java:119: method: String org.apache.roller.weblogger.util.Utilities.escapeHTML(String, bool)
    //#input(String escapeHTML(String, bool)): escapeAmpersand
    //#input(String escapeHTML(String, bool)): s
    //#output(String escapeHTML(String, bool)): return_value
    //#post(String escapeHTML(String, bool)): init'ed(return_value)
    //#test_vector(String escapeHTML(String, bool)): escapeAmpersand: {0}, {1}
            s = StringUtils.replace(s, "&", "&amp;");
    //#Utilities.java:120: Warning: method not available
    //#    -- call on String org.apache.commons.lang.StringUtils:replace(String, String, String)
    //#    severity: INFORMATIONAL
    //#    class: org.apache.roller.weblogger.util.Utilities
    //#    method: String escapeHTML(String, bool)
    //#    unanalyzed callee: String org.apache.commons.lang.StringUtils:replace(String, String, String)
        }
        s = StringUtils.replace(s, "&nbsp;", " ");
    //#Utilities.java:122: Warning: method not available
    //#    -- call on String org.apache.commons.lang.StringUtils:replace(String, String, String)
    //#    severity: INFORMATIONAL
    //#    class: org.apache.roller.weblogger.util.Utilities
    //#    method: String escapeHTML(String, bool)
    //#    unanalyzed callee: String org.apache.commons.lang.StringUtils:replace(String, String, String)
        s = StringUtils.replace(s, "\"", "&quot;");
    //#Utilities.java:123: Warning: method not available
    //#    -- call on String org.apache.commons.lang.StringUtils:replace(String, String, String)
    //#    severity: INFORMATIONAL
    //#    class: org.apache.roller.weblogger.util.Utilities
    //#    method: String escapeHTML(String, bool)
    //#    unanalyzed callee: String org.apache.commons.lang.StringUtils:replace(String, String, String)
        s = StringUtils.replace(s, "<", "&lt;");
    //#Utilities.java:124: Warning: method not available
    //#    -- call on String org.apache.commons.lang.StringUtils:replace(String, String, String)
    //#    severity: INFORMATIONAL
    //#    class: org.apache.roller.weblogger.util.Utilities
    //#    method: String escapeHTML(String, bool)
    //#    unanalyzed callee: String org.apache.commons.lang.StringUtils:replace(String, String, String)
        s = StringUtils.replace(s, ">", "&gt;");
    //#Utilities.java:125: Warning: method not available
    //#    -- call on String org.apache.commons.lang.StringUtils:replace(String, String, String)
    //#    severity: INFORMATIONAL
    //#    class: org.apache.roller.weblogger.util.Utilities
    //#    method: String escapeHTML(String, bool)
    //#    unanalyzed callee: String org.apache.commons.lang.StringUtils:replace(String, String, String)
        return s;
    //#Utilities.java:126: end of method: String org.apache.roller.weblogger.util.Utilities.escapeHTML(String, bool)
    }
     
    public static String unescapeHTML(String str) {
        return StringEscapeUtils.unescapeHtml(str);
    //#Utilities.java:130: method: String org.apache.roller.weblogger.util.Utilities.unescapeHTML(String)
    //#Utilities.java:130: Warning: method not available
    //#    -- call on String org.apache.commons.lang.StringEscapeUtils:unescapeHtml(String)
    //#    severity: INFORMATIONAL
    //#    class: org.apache.roller.weblogger.util.Utilities
    //#    method: String unescapeHTML(String)
    //#    unanalyzed callee: String org.apache.commons.lang.StringEscapeUtils:unescapeHtml(String)
    //#input(String unescapeHTML(String)): str
    //#output(String unescapeHTML(String)): return_value
    //#post(String unescapeHTML(String)): init'ed(return_value)
    //#Utilities.java:130: end of method: String org.apache.roller.weblogger.util.Utilities.unescapeHTML(String)
    }
    
    //------------------------------------------------------------------------
    /**
     * Remove occurences of html, defined as any text
     * between the characters "&lt;" and "&gt;".  Replace
     * any HTML tags with a space.
     */
    public static String removeHTML(String str) {
        return removeHTML(str, true);
    //#Utilities.java:140: method: String org.apache.roller.weblogger.util.Utilities.removeHTML(String)
    //#input(String removeHTML(String)): " "._tainted
    //#input(String removeHTML(String)): str
    //#input(String removeHTML(String)): str._tainted
    //#output(String removeHTML(String)): return_value
    //#post(String removeHTML(String)): return_value != null
    //#unanalyzed(String removeHTML(String)): Effects-of-calling:java.lang.String:indexOf
    //#unanalyzed(String removeHTML(String)): Effects-of-calling:java.lang.String:substring
    //#unanalyzed(String removeHTML(String)): Effects-of-calling:java.lang.String:length
    //#unanalyzed(String removeHTML(String)): Effects-of-calling:java.lang.StringBuffer
    //#unanalyzed(String removeHTML(String)): Effects-of-calling:java.lang.StringBuffer:append
    //#unanalyzed(String removeHTML(String)): Effects-of-calling:java.lang.StringBuffer:toString
    //#unanalyzed(String removeHTML(String)): Effects-of-calling:java.lang.String:trim
    //#Utilities.java:140: end of method: String org.apache.roller.weblogger.util.Utilities.removeHTML(String)
    }
    
    /**
     * Remove occurences of html, defined as any text
     * between the characters "&lt;" and "&gt;".
     * Optionally replace HTML tags with a space.
     *
     * @param str
     * @param addSpace
     * @return
     */
    public static String removeHTML(String str, boolean addSpace) {
        if (str == null) return "";
    //#Utilities.java:153: method: String org.apache.roller.weblogger.util.Utilities.removeHTML(String, bool)
    //#input(String removeHTML(String, bool)): " "._tainted
    //#input(String removeHTML(String, bool)): addSpace
    //#input(String removeHTML(String, bool)): str
    //#input(String removeHTML(String, bool)): str._tainted
    //#output(String removeHTML(String, bool)): return_value
    //#presumption(String removeHTML(String, bool)): java.lang.String:indexOf(...)@168 <= 4_294_967_294
    //#post(String removeHTML(String, bool)): return_value != null
    //#test_vector(String removeHTML(String, bool)): addSpace: {0}, {1}
    //#test_vector(String removeHTML(String, bool)): str: Inverse{null}, Addr_Set{null}
    //#test_vector(String removeHTML(String, bool)): java.lang.String:indexOf(...)@156: {-2_147_483_648..-2, 0..4_294_967_295}, {-1}
    //#test_vector(String removeHTML(String, bool)): java.lang.String:indexOf(...)@168: {-2_147_483_648..-1}, {0..4_294_967_294}
        StringBuffer ret = new StringBuffer(str.length());
        int start = 0;
        int beginTag = str.indexOf("<");
        int endTag = 0;
        if (beginTag == -1)
            return str;
        
        while (beginTag >= start) {
            if (beginTag > 0) {
                ret.append(str.substring(start, beginTag));
                
                // replace each tag with a space (looks better)
                if (addSpace) ret.append(" ");
            }
            endTag = str.indexOf(">", beginTag);
            
            // if endTag found move "cursor" forward
            if (endTag > -1) {
                start = endTag + 1;
                beginTag = str.indexOf("<", start);
            }
            // if no endTag found, get rest of str and break
            else {
                ret.append(str.substring(beginTag));
                break;
            }
        }
        // append everything after the last endTag
        if (endTag > -1 && endTag + 1 < str.length()) {
            ret.append(str.substring(endTag + 1));
        }
        return ret.toString().trim();
    //#Utilities.java:185: end of method: String org.apache.roller.weblogger.util.Utilities.removeHTML(String, bool)
    }
    
    //------------------------------------------------------------------------
    /** Run both removeHTML and escapeHTML on a string.
     * @param s String to be run through removeHTML and escapeHTML.
     * @return String with HTML removed and HTML special characters escaped.
     */
    public static String removeAndEscapeHTML( String s ) {
        if ( s==null ) return "";
    //#Utilities.java:194: method: String org.apache.roller.weblogger.util.Utilities.removeAndEscapeHTML(String)
    //#input(String removeAndEscapeHTML(String)): " "._tainted
    //#input(String removeAndEscapeHTML(String)): s
    //#input(String removeAndEscapeHTML(String)): s._tainted
    //#output(String removeAndEscapeHTML(String)): return_value
    //#post(String removeAndEscapeHTML(String)): init'ed(return_value)
    //#unanalyzed(String removeAndEscapeHTML(String)): Effects-of-calling:java.lang.String:indexOf
    //#unanalyzed(String removeAndEscapeHTML(String)): Effects-of-calling:java.lang.String:substring
    //#unanalyzed(String removeAndEscapeHTML(String)): Effects-of-calling:java.lang.String:length
    //#unanalyzed(String removeAndEscapeHTML(String)): Effects-of-calling:org.apache.commons.lang.StringUtils:replace
    //#unanalyzed(String removeAndEscapeHTML(String)): Effects-of-calling:java.lang.StringBuffer
    //#unanalyzed(String removeAndEscapeHTML(String)): Effects-of-calling:java.lang.StringBuffer:append
    //#unanalyzed(String removeAndEscapeHTML(String)): Effects-of-calling:java.lang.StringBuffer:toString
    //#unanalyzed(String removeAndEscapeHTML(String)): Effects-of-calling:java.lang.String:trim
    //#test_vector(String removeAndEscapeHTML(String)): s: Inverse{null}, Addr_Set{null}
        else return Utilities.escapeHTML( Utilities.removeHTML(s) );
    //#Utilities.java:195: end of method: String org.apache.roller.weblogger.util.Utilities.removeAndEscapeHTML(String)
    }
    
    //------------------------------------------------------------------------
    /**
     * Autoformat.
     */
    public static String autoformat(String s) {
        String ret = StringUtils.replace(s, "\n", "<br />");
    //#Utilities.java:203: method: String org.apache.roller.weblogger.util.Utilities.autoformat(String)
    //#Utilities.java:203: Warning: method not available
    //#    -- call on String org.apache.commons.lang.StringUtils:replace(String, String, String)
    //#    severity: INFORMATIONAL
    //#    class: org.apache.roller.weblogger.util.Utilities
    //#    method: String autoformat(String)
    //#    unanalyzed callee: String org.apache.commons.lang.StringUtils:replace(String, String, String)
    //#input(String autoformat(String)): s
    //#output(String autoformat(String)): return_value
    //#post(String autoformat(String)): init'ed(return_value)
        return ret;
    //#Utilities.java:204: end of method: String org.apache.roller.weblogger.util.Utilities.autoformat(String)
    }
    
    
    /**
     * Code (stolen from Pebble) to add rel="nofollow" string to all links in HTML.
     */
    public static String addNofollow(String html) {
        if (html == null || html.length() == 0) {
    //#Utilities.java:212: method: String org.apache.roller.weblogger.util.Utilities.addNofollow(String)
    //#input(String addNofollow(String)): " rel="nofollow">"._tainted
    //#input(String addNofollow(String)): html
    //#input(String addNofollow(String)): html._tainted
    //#input(String addNofollow(String)): mLinkPattern
    //#output(String addNofollow(String)): java.lang.StringBuffer:toString(...)._tainted
    //#output(String addNofollow(String)): return_value
    //#new obj(String addNofollow(String)): java.lang.StringBuffer:toString(...)
    //#pre[3] (String addNofollow(String)): (soft) mLinkPattern != null
    //#presumption(String addNofollow(String)): java.util.regex.Pattern:matcher(...)@215 != null
    //#post(String addNofollow(String)): init'ed(java.lang.StringBuffer:toString(...)._tainted)
    //#post(String addNofollow(String)): return_value == One-of{html, &java.lang.StringBuffer:toString(...)}
    //#post(String addNofollow(String)): init'ed(return_value)
    //#test_vector(String addNofollow(String)): html: Addr_Set{null}, Inverse{null}
    //#test_vector(String addNofollow(String)): java.lang.String:indexOf(...)@222: {-2_147_483_648..-2, 0..4_294_967_295}, {-1}
    //#test_vector(String addNofollow(String)): java.lang.String:length(...)@212: {1..4_294_967_295}, {0}
    //#test_vector(String addNofollow(String)): java.util.regex.Matcher:find(...)@217: {0}, {1}
            return html;
        }
        Matcher m = mLinkPattern.matcher(html);
        StringBuffer buf = new StringBuffer();
        while (m.find()) {
            int start = m.start();
            int end = m.end();
            String link = html.substring(start, end);
            buf.append(html.substring(0, start));
            if (link.indexOf("rel=\"nofollow\"") == -1) {
                buf.append(
                        link.substring(0, link.length() - 1) + " rel=\"nofollow\">");
            } else {
                buf.append(link);
            }
            html = html.substring(end, html.length());
            m = mLinkPattern.matcher(html);
        }
        buf.append(html);
        return buf.toString();
    //#Utilities.java:232: end of method: String org.apache.roller.weblogger.util.Utilities.addNofollow(String)
    }
    
    
    //------------------------------------------------------------------------
    /**
     * Replaces occurences of non-alphanumeric characters with an underscore.
     */
    public static String replaceNonAlphanumeric(String str) {
        return replaceNonAlphanumeric(str, '_');
    //#Utilities.java:241: method: String org.apache.roller.weblogger.util.Utilities.replaceNonAlphanumeric(String)
    //#input(String replaceNonAlphanumeric(String)): str
    //#output(String replaceNonAlphanumeric(String)): java.lang.StringBuffer:toString(...)._tainted
    //#output(String replaceNonAlphanumeric(String)): return_value
    //#new obj(String replaceNonAlphanumeric(String)): java.lang.StringBuffer:toString(...)
    //#pre[1] (String replaceNonAlphanumeric(String)): str != null
    //#post(String replaceNonAlphanumeric(String)): java.lang.StringBuffer:toString(...)._tainted == 0
    //#post(String replaceNonAlphanumeric(String)): return_value == &java.lang.StringBuffer:toString(...)
    //#unanalyzed(String replaceNonAlphanumeric(String)): Effects-of-calling:java.lang.String:length
    //#unanalyzed(String replaceNonAlphanumeric(String)): Effects-of-calling:java.lang.StringBuffer
    //#unanalyzed(String replaceNonAlphanumeric(String)): Effects-of-calling:java.lang.StringBuffer:toString
    //#unanalyzed(String replaceNonAlphanumeric(String)): Effects-of-calling:java.lang.String:toCharArray
    //#unanalyzed(String replaceNonAlphanumeric(String)): Effects-of-calling:java.lang.Character:isLetterOrDigit
    //#unanalyzed(String replaceNonAlphanumeric(String)): Effects-of-calling:java.lang.StringBuffer:append
    //#Utilities.java:241: end of method: String org.apache.roller.weblogger.util.Utilities.replaceNonAlphanumeric(String)
    }
    
    //------------------------------------------------------------------------
    /**
     * Replaces occurences of non-alphanumeric characters with a
     * supplied char.
     */
    public static String replaceNonAlphanumeric(String str, char subst) {
        StringBuffer ret = new StringBuffer(str.length());
    //#Utilities.java:250: method: String org.apache.roller.weblogger.util.Utilities.replaceNonAlphanumeric(String, char)
    //#input(String replaceNonAlphanumeric(String, char)): str
    //#input(String replaceNonAlphanumeric(String, char)): subst
    //#output(String replaceNonAlphanumeric(String, char)): java.lang.StringBuffer:toString(...)._tainted
    //#output(String replaceNonAlphanumeric(String, char)): return_value
    //#new obj(String replaceNonAlphanumeric(String, char)): java.lang.StringBuffer:toString(...)
    //#pre[1] (String replaceNonAlphanumeric(String, char)): str != null
    //#presumption(String replaceNonAlphanumeric(String, char)): testChars.length@251 <= 4_294_967_295
    //#post(String replaceNonAlphanumeric(String, char)): java.lang.StringBuffer:toString(...)._tainted == 0
    //#post(String replaceNonAlphanumeric(String, char)): return_value == &java.lang.StringBuffer:toString(...)
    //#test_vector(String replaceNonAlphanumeric(String, char)): java.lang.Character:isLetterOrDigit(...)@253: {0}, {1}
        char[] testChars = str.toCharArray();
        for (int i = 0; i < testChars.length; i++) {
            if (Character.isLetterOrDigit(testChars[i])) {
    //#Utilities.java:253: ?use of default init
    //#    init'ed(testChars[i])
    //#    severity: LOW
    //#    class: org.apache.roller.weblogger.util.Utilities
    //#    method: String replaceNonAlphanumeric(String, char)
    //#    basic block: bb_3
    //#    assertion: init'ed(testChars[i])
    //#    VN: undefined
    //#    Expected: {-Inf..+Inf}
    //#    Bad: {Invalid}
    //#    Attribs:  Int  Bad only invalid
                ret.append(testChars[i]);
    //#Utilities.java:254: ?use of default init
    //#    init'ed(testChars[i])
    //#    severity: LOW
    //#    class: org.apache.roller.weblogger.util.Utilities
    //#    method: String replaceNonAlphanumeric(String, char)
    //#    basic block: bb_4
    //#    assertion: init'ed(testChars[i])
    //#    VN: undefined
    //#    Expected: {-Inf..+Inf}
    //#    Bad: {Invalid}
    //#    Attribs:  Int  Bad only invalid
            } else {
                ret.append( subst );
            }
        }
        return ret.toString();
    //#Utilities.java:259: end of method: String org.apache.roller.weblogger.util.Utilities.replaceNonAlphanumeric(String, char)
    }
    
    //------------------------------------------------------------------------
    /**
     * Remove occurences of non-alphanumeric characters.
     */
    public static String removeNonAlphanumeric(String str) {
        StringBuffer ret = new StringBuffer(str.length());
    //#Utilities.java:267: method: String org.apache.roller.weblogger.util.Utilities.removeNonAlphanumeric(String)
    //#input(String removeNonAlphanumeric(String)): str
    //#output(String removeNonAlphanumeric(String)): java.lang.StringBuffer:toString(...)._tainted
    //#output(String removeNonAlphanumeric(String)): return_value
    //#new obj(String removeNonAlphanumeric(String)): java.lang.StringBuffer:toString(...)
    //#pre[1] (String removeNonAlphanumeric(String)): str != null
    //#presumption(String removeNonAlphanumeric(String)): testChars.length@268 <= 4_294_967_295
    //#post(String removeNonAlphanumeric(String)): java.lang.StringBuffer:toString(...)._tainted == 0
    //#post(String removeNonAlphanumeric(String)): return_value == &java.lang.StringBuffer:toString(...)
        char[] testChars = str.toCharArray();
        for (int i = 0; i < testChars.length; i++) {
            // MR: Allow periods in page links
            if (Character.isLetterOrDigit(testChars[i]) ||
    //#Utilities.java:271: ?use of default init
    //#    init'ed(testChars[i])
    //#    severity: LOW
    //#    class: org.apache.roller.weblogger.util.Utilities
    //#    method: String removeNonAlphanumeric(String)
    //#    basic block: bb_3
    //#    assertion: init'ed(testChars[i])
    //#    VN: undefined
    //#    Expected: {-Inf..+Inf}
    //#    Bad: {Invalid}
    //#    Attribs:  Int  Bad only invalid
    //#Utilities.java:271: ?use of default init
    //#    init'ed(testChars[i])
    //#    severity: LOW
    //#    class: org.apache.roller.weblogger.util.Utilities
    //#    method: String removeNonAlphanumeric(String)
    //#    basic block: bb_4
    //#    assertion: init'ed(testChars[i])
    //#    VN: undefined
    //#    Expected: {-Inf..+Inf}
    //#    Bad: {Invalid}
    //#    Attribs:  Int  Bad only invalid
                    testChars[i] == '.') {
                ret.append(testChars[i]);
    //#Utilities.java:273: ?use of default init
    //#    init'ed(testChars[i])
    //#    severity: LOW
    //#    class: org.apache.roller.weblogger.util.Utilities
    //#    method: String removeNonAlphanumeric(String)
    //#    basic block: bb_5
    //#    assertion: init'ed(testChars[i])
    //#    VN: undefined
    //#    Expected: {-Inf..+Inf}
    //#    Bad: {Invalid}
    //#    Attribs:  Int  Bad only invalid
            }
        }
        return ret.toString();
    //#Utilities.java:276: end of method: String org.apache.roller.weblogger.util.Utilities.removeNonAlphanumeric(String)
    }
    
    //------------------------------------------------------------------------
    /**
     * @param stringArray
     * @param delim
     * @return
     */
    public static String stringArrayToString(String[] stringArray, String delim) {
        String ret = "";
    //#Utilities.java:286: method: String org.apache.roller.weblogger.util.Utilities.stringArrayToString(String[], String)
    //#input(String stringArrayToString(String[], String)): ""._tainted
    //#input(String stringArrayToString(String[], String)): delim
    //#input(String stringArrayToString(String[], String)): delim._tainted
    //#input(String stringArrayToString(String[], String)): stringArray
    //#input(String stringArrayToString(String[], String)): stringArray.length
    //#input(String stringArrayToString(String[], String)): stringArray[0..4_294_967_295]
    //#input(String stringArrayToString(String[], String)): stringArray[0..4_294_967_295]._tainted
    //#output(String stringArrayToString(String[], String)): java.lang.StringBuilder:toString(...)._tainted
    //#output(String stringArrayToString(String[], String)): return_value
    //#new obj(String stringArrayToString(String[], String)): java.lang.StringBuilder:toString(...)
    //#pre[3] (String stringArrayToString(String[], String)): stringArray != null
    //#pre[4] (String stringArrayToString(String[], String)): stringArray.length <= 4_294_967_295
    //#pre[5] (String stringArrayToString(String[], String)): (soft) init'ed(stringArray[0..4_294_967_295])
    //#post(String stringArrayToString(String[], String)): init'ed(java.lang.StringBuilder:toString(...)._tainted)
    //#post(String stringArrayToString(String[], String)): init'ed(return_value)
    //#test_vector(String stringArrayToString(String[], String)): java.lang.String:length(...)@288: {0}, {1..4_294_967_295}
        for (int i = 0; i < stringArray.length; i++) {
            if (ret.length() > 0)
    //#Utilities.java:288: ?null dereference
    //#    ret != null
    //#    severity: MEDIUM
    //#    class: org.apache.roller.weblogger.util.Utilities
    //#    method: String stringArrayToString(String[], String)
    //#    basic block: bb_3
    //#    assertion: ret != null
    //#    VN: ret
    //#    Expected: Inverse{null} or Invalid
    //#    Bad: Addr_Set{null}
    //#    Attribs:  Ptr  null in Bad
                ret = ret + delim + stringArray[i];
            else
                ret = stringArray[i];
        }
        return ret;
    //#Utilities.java:293: end of method: String org.apache.roller.weblogger.util.Utilities.stringArrayToString(String[], String)
    }
    
    //--------------------------------------------------------------------------
    /** Convert string to string array. */
    public static String[] stringToStringArray(String instr, String delim)
    throws NoSuchElementException, NumberFormatException {
        StringTokenizer toker = new StringTokenizer(instr, delim);
    //#Utilities.java:300: method: String[] org.apache.roller.weblogger.util.Utilities.stringToStringArray(String, String)
    //#input(String[] stringToStringArray(String, String)): delim
    //#input(String[] stringToStringArray(String, String)): instr
    //#input(String[] stringToStringArray(String, String)): instr._tainted
    //#output(String[] stringToStringArray(String, String)): java.util.StringTokenizer:nextToken(...)._tainted
    //#output(String[] stringToStringArray(String, String)): new String[](stringToStringArray#2) num objects
    //#output(String[] stringToStringArray(String, String)): return_value.length
    //#output(String[] stringToStringArray(String, String)): return_value[0..4_294_967_295]
    //#output(String[] stringToStringArray(String, String)): return_value
    //#new obj(String[] stringToStringArray(String, String)): java.util.StringTokenizer:nextToken(...)
    //#new obj(String[] stringToStringArray(String, String)): new String[](stringToStringArray#2)
    //#presumption(String[] stringToStringArray(String, String)): java.util.StringTokenizer:countTokens(...)@301 >= 1
    //#post(String[] stringToStringArray(String, String)): init'ed(java.util.StringTokenizer:nextToken(...)._tainted)
    //#post(String[] stringToStringArray(String, String)): return_value == &new String[](stringToStringArray#2)
    //#post(String[] stringToStringArray(String, String)): new String[](stringToStringArray#2) num objects == 1
    //#post(String[] stringToStringArray(String, String)): (soft) return_value.length in 1..4_294_967_295
    //#post(String[] stringToStringArray(String, String)): return_value[0..4_294_967_295] == &java.util.StringTokenizer:nextToken(...)
    //#test_vector(String[] stringToStringArray(String, String)): java.util.StringTokenizer:hasMoreTokens(...)@304: {0}, {1}
        String stringArray[] = new String[toker.countTokens()];
        int i = 0;
        
        while (toker.hasMoreTokens()) {
            stringArray[i++] = toker.nextToken();
    //#Utilities.java:305: ?overflow
    //#    i in -2_147_483_649..4_294_967_294
    //#    severity: LOW
    //#    class: org.apache.roller.weblogger.util.Utilities
    //#    method: String[] stringToStringArray(String, String)
    //#    basic block: bb_3
    //#    assertion: i in -2_147_483_649..4_294_967_294
    //#    VN: i + 1
    //#    Expected: {-2_147_483_648..4_294_967_295, Invalid}
    //#    Bad: {4_294_967_296}
    //#    Attribs:  Int  Bad singleton  Bad > Exp
    //#Utilities.java:305: ?array index out of bounds
    //#    i < stringArray.length
    //#    severity: MEDIUM
    //#    class: org.apache.roller.weblogger.util.Utilities
    //#    method: String[] stringToStringArray(String, String)
    //#    basic block: bb_3
    //#    assertion: i < stringArray.length
    //#    VN: -(i - java.util.StringTokenizer:countTokens(...)@301)
    //#    Expected: {1..+Inf}
    //#    Bad: {0}
    //#    Attribs:  Int  Bad singleton  Bad overlaps +/-1000  Bad < Exp
        }
        return stringArray;
    //#Utilities.java:307: end of method: String[] org.apache.roller.weblogger.util.Utilities.stringToStringArray(String, String)
    }
    
    //--------------------------------------------------------------------------
    /** Convert string to integer array. */
    public static int[] stringToIntArray(String instr, String delim)
    throws NoSuchElementException, NumberFormatException {
        StringTokenizer toker = new StringTokenizer(instr, delim);
    //#Utilities.java:314: method: int[] org.apache.roller.weblogger.util.Utilities.stringToIntArray(String, String)
    //#input(int[] stringToIntArray(String, String)): delim
    //#input(int[] stringToIntArray(String, String)): instr
    //#input(int[] stringToIntArray(String, String)): instr._tainted
    //#output(int[] stringToIntArray(String, String)): new int[](stringToIntArray#2) num objects
    //#output(int[] stringToIntArray(String, String)): return_value.length
    //#output(int[] stringToIntArray(String, String)): return_value[0..4_294_967_295]
    //#output(int[] stringToIntArray(String, String)): return_value
    //#new obj(int[] stringToIntArray(String, String)): new int[](stringToIntArray#2)
    //#presumption(int[] stringToIntArray(String, String)): java.util.StringTokenizer:countTokens(...)@315 >= 1
    //#post(int[] stringToIntArray(String, String)): return_value == &new int[](stringToIntArray#2)
    //#post(int[] stringToIntArray(String, String)): new int[](stringToIntArray#2) num objects == 1
    //#post(int[] stringToIntArray(String, String)): (soft) return_value.length in 1..4_294_967_295
    //#post(int[] stringToIntArray(String, String)): init'ed(return_value[0..4_294_967_295])
    //#test_vector(int[] stringToIntArray(String, String)): java.util.StringTokenizer:hasMoreTokens(...)@318: {0}, {1}
        int intArray[] = new int[toker.countTokens()];
        int i = 0;
        
        while (toker.hasMoreTokens()) {
            String sInt = toker.nextToken();
            int nInt = Integer.parseInt(sInt);
            intArray[i++] = new Integer(nInt).intValue();
    //#Utilities.java:321: ?overflow
    //#    i in -2_147_483_649..4_294_967_294
    //#    severity: LOW
    //#    class: org.apache.roller.weblogger.util.Utilities
    //#    method: int[] stringToIntArray(String, String)
    //#    basic block: bb_3
    //#    assertion: i in -2_147_483_649..4_294_967_294
    //#    VN: i + 1
    //#    Expected: {-2_147_483_648..4_294_967_295, Invalid}
    //#    Bad: {4_294_967_296}
    //#    Attribs:  Int  Bad singleton  Bad > Exp
    //#Utilities.java:321: ?array index out of bounds
    //#    i < intArray.length
    //#    severity: MEDIUM
    //#    class: org.apache.roller.weblogger.util.Utilities
    //#    method: int[] stringToIntArray(String, String)
    //#    basic block: bb_3
    //#    assertion: i < intArray.length
    //#    VN: -(i - java.util.StringTokenizer:countTokens(...)@315)
    //#    Expected: {1..+Inf}
    //#    Bad: {0}
    //#    Attribs:  Int  Bad singleton  Bad overlaps +/-1000  Bad < Exp
        }
        return intArray;
    //#Utilities.java:323: end of method: int[] org.apache.roller.weblogger.util.Utilities.stringToIntArray(String, String)
    }
    
    //-------------------------------------------------------------------
    /** Convert integer array to a string. */
    public static String intArrayToString(int[] intArray) {
        String ret = "";
    //#Utilities.java:329: method: String org.apache.roller.weblogger.util.Utilities.intArrayToString(int[])
    //#input(String intArrayToString(int[])): ""._tainted
    //#input(String intArrayToString(int[])): ","._tainted
    //#input(String intArrayToString(int[])): intArray
    //#input(String intArrayToString(int[])): intArray.length
    //#input(String intArrayToString(int[])): intArray[0..4_294_967_295]
    //#output(String intArrayToString(int[])): java.lang.Integer:toString(...)._tainted
    //#output(String intArrayToString(int[])): java.lang.StringBuilder:toString(...)._tainted
    //#output(String intArrayToString(int[])): return_value
    //#new obj(String intArrayToString(int[])): java.lang.Integer:toString(...)
    //#new obj(String intArrayToString(int[])): java.lang.StringBuilder:toString(...)
    //#pre[1] (String intArrayToString(int[])): intArray != null
    //#pre[2] (String intArrayToString(int[])): intArray.length <= 4_294_967_295
    //#pre[3] (String intArrayToString(int[])): (soft) init'ed(intArray[0..4_294_967_295])
    //#post(String intArrayToString(int[])): java.lang.Integer:toString(...)._tainted == 0
    //#post(String intArrayToString(int[])): java.lang.StringBuilder:toString(...)._tainted == 0
    //#post(String intArrayToString(int[])): return_value in Addr_Set{&"",&java.lang.StringBuilder:toString(...),&java.lang.Integer:toString(...)}
    //#test_vector(String intArrayToString(int[])): java.lang.String:length(...)@331: {0}, {1..4_294_967_295}
        for (int i = 0; i < intArray.length; i++) {
            if (ret.length() > 0)
                ret = ret + "," + Integer.toString(intArray[i]);
            else
                ret = Integer.toString(intArray[i]);
        }
        return ret;
    //#Utilities.java:336: end of method: String org.apache.roller.weblogger.util.Utilities.intArrayToString(int[])
    }
    
    //------------------------------------------------------------------------
    public static void copyFile(File from, File to) throws IOException {
        InputStream in = null;
    //#Utilities.java:341: method: void org.apache.roller.weblogger.util.Utilities.copyFile(File, File)
    //#Utilities.java:341: Warning: unused assignment
    //#    unused assignment into in
    //#    severity: SUPPRESSED
    //#    class: org.apache.roller.weblogger.util.Utilities
    //#    method: void copyFile(File, File)
    //#    Attribs:  Uncertain
    //#input(void copyFile(File, File)): "', "._tainted
    //#input(void copyFile(File, File)): "Closing file streams, "._tainted
    //#input(void copyFile(File, File)): "Reading input stream, "._tainted
    //#input(void copyFile(File, File)): "Utilities.copyFile: opening input stream '"._tainted
    //#input(void copyFile(File, File)): "Utilities.copyFile: opening output stream '"._tainted
    //#input(void copyFile(File, File)): "Writing output stream, "._tainted
    //#input(void copyFile(File, File)): from
    //#input(void copyFile(File, File)): to
    //#pre[1] (void copyFile(File, File)): from != null
    //#unanalyzed(void copyFile(File, File)): Effects-of-calling:java.lang.StringBuilder
    //#unanalyzed(void copyFile(File, File)): Effects-of-calling:java.lang.StringBuilder:append
    //#unanalyzed(void copyFile(File, File)): Effects-of-calling:java.lang.StringBuilder:toString
    //#unanalyzed(void copyFile(File, File)): Effects-of-calling:java.io.BufferedInputStream
    //#unanalyzed(void copyFile(File, File)): Effects-of-calling:java.io.BufferedOutputStream
    //#unanalyzed(void copyFile(File, File)): Effects-of-calling:java.io.BufferedInputStream:read
    //#unanalyzed(void copyFile(File, File)): Effects-of-calling:java.io.BufferedOutputStream:write
    //#unanalyzed(void copyFile(File, File)): Effects-of-calling:java.lang.Throwable:__curr_excep_obj
    //#unanalyzed(void copyFile(File, File)): Effects-of-calling:java.io.BufferedInputStream:close
    //#unanalyzed(void copyFile(File, File)): Effects-of-calling:java.io.BufferedOutputStream:close
    //#unanalyzed(void copyFile(File, File)): Effects-of-calling:java.io.IOException:getMessage
    //#unanalyzed(void copyFile(File, File)): Effects-of-calling:java.io.IOException
        OutputStream out = null;
    //#Utilities.java:342: Warning: unused assignment
    //#    unused assignment into out
    //#    severity: SUPPRESSED
    //#    class: org.apache.roller.weblogger.util.Utilities
    //#    method: void copyFile(File, File)
    //#    Attribs:  Uncertain
        
        try {
            in = new FileInputStream(from);
        } catch (IOException ex) {
            throw new IOException(
                    "Utilities.copyFile: opening input stream '"
                    + from.getPath()
                    + "', "
                    + ex.getMessage());
        }
        
        try {
            out = new FileOutputStream(to);
        } catch (Exception ex) {
            try {
                in.close();
            } catch (IOException ex1) {
            }
            throw new IOException(
                    "Utilities.copyFile: opening output stream '"
                    + to.getPath()
                    + "', "
                    + ex.getMessage());
        }
        
        copyInputToOutput(in, out, from.length());
    }
    //#Utilities.java:369: end of method: void org.apache.roller.weblogger.util.Utilities.copyFile(File, File)
    
    //------------------------------------------------------------------------
    /**
     * Utility method to copy an input stream to an output stream.
     * Wraps both streams in buffers. Ensures right numbers of bytes copied.
     */
    public static void copyInputToOutput(
            InputStream input,
            OutputStream output,
            long byteCount)
            throws IOException {
        int bytes;
        long length;
        
        BufferedInputStream in = new BufferedInputStream(input);
    //#Utilities.java:384: method: void org.apache.roller.weblogger.util.Utilities.copyInputToOutput(InputStream, OutputStream, long)
    //#input(void copyInputToOutput(InputStream, OutputStream, long)): "Closing file streams, "._tainted
    //#input(void copyInputToOutput(InputStream, OutputStream, long)): "Reading input stream, "._tainted
    //#input(void copyInputToOutput(InputStream, OutputStream, long)): "Writing output stream, "._tainted
    //#input(void copyInputToOutput(InputStream, OutputStream, long)): byteCount
    //#input(void copyInputToOutput(InputStream, OutputStream, long)): input
    //#input(void copyInputToOutput(InputStream, OutputStream, long)): output
        BufferedOutputStream out = new BufferedOutputStream(output);
        
        byte[] buffer;
        buffer = new byte[8192];
        
        for (length = byteCount; length > 0;) {
            bytes = (int) (length > 8192 ? 8192 : length);
            
            try {
                bytes = in.read(buffer, 0, bytes);
            } catch (IOException ex) {
                try {
                    in.close();
                    out.close();
                } catch (IOException ex1) {
                }
                throw new IOException(
                        "Reading input stream, " + ex.getMessage());
            }
            
            if (bytes < 0)
                break;
            
            length -= bytes;
            
            try {
                out.write(buffer, 0, bytes);
            } catch (IOException ex) {
                try {
                    in.close();
                    out.close();
                } catch (IOException ex1) {
                }
                throw new IOException(
                        "Writing output stream, " + ex.getMessage());
            }
        }
        
        try {
            in.close();
            out.close();
        } catch (IOException ex) {
            throw new IOException("Closing file streams, " + ex.getMessage());
        }
    }
    //#Utilities.java:429: end of method: void org.apache.roller.weblogger.util.Utilities.copyInputToOutput(InputStream, OutputStream, long)
    
    //------------------------------------------------------------------------
    public static void copyInputToOutput(
            InputStream input,
            OutputStream output)
            throws IOException {
        BufferedInputStream in = new BufferedInputStream(input);
    //#Utilities.java:436: method: void org.apache.roller.weblogger.util.Utilities.copyInputToOutput(InputStream, OutputStream)
    //#input(void copyInputToOutput(InputStream, OutputStream)): "Closing file streams, "._tainted
    //#input(void copyInputToOutput(InputStream, OutputStream)): input
    //#input(void copyInputToOutput(InputStream, OutputStream)): output
    //#test_vector(void copyInputToOutput(InputStream, OutputStream)): java.io.BufferedInputStream:read(...)@440: {-1}, {-2_147_483_648..-2, 0..4_294_967_295}
        BufferedOutputStream out = new BufferedOutputStream(output);
        byte buffer[] = new byte[8192];
        for (int count = 0; count != -1;) {
            count = in.read(buffer, 0, 8192);
            if (count != -1)
                out.write(buffer, 0, count);
        }
        
        try {
            in.close();
            out.close();
        } catch (IOException ex) {
            throw new IOException("Closing file streams, " + ex.getMessage());
        }
    }
    //#Utilities.java:451: end of method: void org.apache.roller.weblogger.util.Utilities.copyInputToOutput(InputStream, OutputStream)
    
    /**
     * Encode a string using algorithm specified in web.xml and return the
     * resulting encrypted password. If exception, the plain credentials
     * string is returned
     *
     * @param password Password or other credentials to use in authenticating
     *        this username
     * @param algorithm Algorithm used to do the digest
     *
     * @return encypted password based on the algorithm.
     */
    public static String encodePassword(String password, String algorithm) {
        byte[] unencodedPassword = password.getBytes();
    //#Utilities.java:465: method: String org.apache.roller.weblogger.util.Utilities.encodePassword(String, String)
    //#input(String encodePassword(String, String)): "0"._tainted
    //#input(String encodePassword(String, String)): "Exception: "._tainted
    //#input(String encodePassword(String, String)): algorithm
    //#input(String encodePassword(String, String)): mLogger
    //#input(String encodePassword(String, String)): password
    //#output(String encodePassword(String, String)): java.lang.StringBuffer:toString(...)._tainted
    //#output(String encodePassword(String, String)): return_value
    //#new obj(String encodePassword(String, String)): java.lang.StringBuffer:toString(...)
    //#pre[3] (String encodePassword(String, String)): password != null
    //#pre[2] (String encodePassword(String, String)): (soft) mLogger != null
    //#presumption(String encodePassword(String, String)): encodedPassword.length@484 <= 4_294_967_295
    //#presumption(String encodePassword(String, String)): java.security.MessageDigest:digest(...)@484 != null
    //#presumption(String encodePassword(String, String)): java.security.MessageDigest:getInstance(...)@471 != null
    //#post(String encodePassword(String, String)): java.lang.StringBuffer:toString(...)._tainted == 0
    //#post(String encodePassword(String, String)): return_value == One-of{password, &java.lang.StringBuffer:toString(...)}
    //#post(String encodePassword(String, String)): return_value != null
        
        MessageDigest md = null;
    //#Utilities.java:467: Warning: unused assignment
    //#    unused assignment into md
    //#    severity: SUPPRESSED
    //#    class: org.apache.roller.weblogger.util.Utilities
    //#    method: String encodePassword(String, String)
    //#    Attribs:  Uncertain
        
        try {
            // first create an instance, given the provider
            md = MessageDigest.getInstance(algorithm);
        } catch (Exception e) {
            mLogger.error("Exception: " + e);
    //#Utilities.java:473: Warning: method not available
    //#    -- call on void org.apache.commons.logging.Log:error(Object)
    //#    severity: INFORMATIONAL
    //#    class: org.apache.roller.weblogger.util.Utilities
    //#    method: String encodePassword(String, String)
    //#    unanalyzed callee: void org.apache.commons.logging.Log:error(Object)
            return password;
        }
        
        md.reset();
        
        // call the update method one or more times
        // (useful when you don't know the size of your data, eg. stream)
        md.update(unencodedPassword);
        
        // now calculate the hash
        byte[] encodedPassword = md.digest();
        
        StringBuffer buf = new StringBuffer();
        
        for (int i = 0; i < encodedPassword.length; i++) {
            if ((encodedPassword[i] & 0xff) < 0x10) {
    //#Utilities.java:489: ?use of default init
    //#    init'ed(encodedPassword[i])
    //#    severity: LOW
    //#    class: org.apache.roller.weblogger.util.Utilities
    //#    method: String encodePassword(String, String)
    //#    basic block: bb_6
    //#    assertion: init'ed(encodedPassword[i])
    //#    VN: undefined
    //#    Expected: {-Inf..+Inf}
    //#    Bad: {Invalid}
    //#    Attribs:  Int  Bad only invalid
    //#Utilities.java:489: Warning: test always goes same way
    //#    test predetermined because encodedPassword[i] mod 256 == 0
    //#    severity: LOW
    //#    class: org.apache.roller.weblogger.util.Utilities
    //#    method: String encodePassword(String, String)
    //#    from bb: bb_6
    //#    live edge: bb_6-->bb_7
    //#    tested vn: undefined mod 256 - 16
    //#    tested vn values: {-16}
                buf.append("0");
            }
            
            buf.append(Long.toString(encodedPassword[i] & 0xff, 16));
    //#Utilities.java:493: ?use of default init
    //#    init'ed(encodedPassword[i])
    //#    severity: LOW
    //#    class: org.apache.roller.weblogger.util.Utilities
    //#    method: String encodePassword(String, String)
    //#    basic block: bb_8
    //#    assertion: init'ed(encodedPassword[i])
    //#    VN: undefined
    //#    Expected: {-Inf..+Inf}
    //#    Bad: {Invalid}
    //#    Attribs:  Int  Bad only invalid
        }
        
        return buf.toString();
    //#Utilities.java:496: end of method: String org.apache.roller.weblogger.util.Utilities.encodePassword(String, String)
    }
    
    /**
     * Encode a string using Base64 encoding. Used when storing passwords
     * as cookies.
     *
     * This is weak encoding in that anyone can use the decodeString
     * routine to reverse the encoding.
     *
     * @param str
     * @return String
     * @throws IOException
     */
    public static String encodeString(String str) throws IOException {
        Base64 base64 = new Base64();
    //#Utilities.java:511: method: String org.apache.roller.weblogger.util.Utilities.encodeString(String)
    //#Utilities.java:511: Warning: unused assignment
    //#    unused assignment into base64
    //#    severity: LOW
    //#    class: org.apache.roller.weblogger.util.Utilities
    //#    method: String encodeString(String)
    //#Utilities.java:511: Warning: method not available
    //#    -- call on void org.apache.commons.codec.binary.Base64()
    //#    severity: INFORMATIONAL
    //#    class: org.apache.roller.weblogger.util.Utilities
    //#    method: String encodeString(String)
    //#    unanalyzed callee: void org.apache.commons.codec.binary.Base64()
    //#input(String encodeString(String)): str
    //#output(String encodeString(String)): return_value
    //#pre[1] (String encodeString(String)): str != null
    //#post(String encodeString(String)): return_value != null
        String encodedStr = new String(base64.encodeBase64(str.getBytes()));        
    //#Utilities.java:512: Warning: method not available
    //#    -- call on byte[] org.apache.commons.codec.binary.Base64:encodeBase64(byte[])
    //#    severity: INFORMATIONAL
    //#    class: org.apache.roller.weblogger.util.Utilities
    //#    method: String encodeString(String)
    //#    unanalyzed callee: byte[] org.apache.commons.codec.binary.Base64:encodeBase64(byte[])
        return (encodedStr.trim());
    //#Utilities.java:513: end of method: String org.apache.roller.weblogger.util.Utilities.encodeString(String)
    }
    
    /**
     * Decode a string using Base64 encoding.
     *
     * @param str
     * @return String
     * @throws IOException
     */
    public static String decodeString(String str) throws IOException {
        Base64 base64 = new Base64();
    //#Utilities.java:524: method: String org.apache.roller.weblogger.util.Utilities.decodeString(String)
    //#Utilities.java:524: Warning: unused assignment
    //#    unused assignment into base64
    //#    severity: LOW
    //#    class: org.apache.roller.weblogger.util.Utilities
    //#    method: String decodeString(String)
    //#Utilities.java:524: Warning: method not available
    //#    -- call on void org.apache.commons.codec.binary.Base64()
    //#    severity: INFORMATIONAL
    //#    class: org.apache.roller.weblogger.util.Utilities
    //#    method: String decodeString(String)
    //#    unanalyzed callee: void org.apache.commons.codec.binary.Base64()
    //#input(String decodeString(String)): str
    //#output(String decodeString(String)): new String(decodeString#2) num objects
    //#output(String decodeString(String)): return_value
    //#new obj(String decodeString(String)): new String(decodeString#2)
    //#pre[1] (String decodeString(String)): str != null
    //#post(String decodeString(String)): return_value == &new String(decodeString#2)
    //#post(String decodeString(String)): new String(decodeString#2) num objects == 1
        String value = new String(base64.decodeBase64(str.getBytes()));        
    //#Utilities.java:525: Warning: method not available
    //#    -- call on byte[] org.apache.commons.codec.binary.Base64:decodeBase64(byte[])
    //#    severity: INFORMATIONAL
    //#    class: org.apache.roller.weblogger.util.Utilities
    //#    method: String decodeString(String)
    //#    unanalyzed callee: byte[] org.apache.commons.codec.binary.Base64:decodeBase64(byte[])
        return (value);
    //#Utilities.java:526: end of method: String org.apache.roller.weblogger.util.Utilities.decodeString(String)
    }
    
    /**
     * Strips HTML and truncates.
     */
    public static String truncate(
            String str, int lower, int upper, String appendToEnd) {
        // strip markup from the string
        String str2 = removeHTML(str, false);
    //#Utilities.java:535: method: String org.apache.roller.weblogger.util.Utilities.truncate(String, int, int, String)
    //#input(String truncate(String, int, int, String)): " "._tainted
    //#input(String truncate(String, int, int, String)): ""._tainted
    //#input(String truncate(String, int, int, String)): appendToEnd
    //#input(String truncate(String, int, int, String)): appendToEnd._tainted
    //#input(String truncate(String, int, int, String)): lower
    //#input(String truncate(String, int, int, String)): str
    //#input(String truncate(String, int, int, String)): str._tainted
    //#input(String truncate(String, int, int, String)): upper
    //#output(String truncate(String, int, int, String)): java.lang.String:substring(...)._tainted
    //#output(String truncate(String, int, int, String)): java.lang.StringBuilder:toString(...)._tainted
    //#output(String truncate(String, int, int, String)): return_value
    //#new obj(String truncate(String, int, int, String)): java.lang.String:substring(...)
    //#new obj(String truncate(String, int, int, String)): java.lang.StringBuilder:toString(...)
    //#post(String truncate(String, int, int, String)): init'ed(java.lang.String:substring(...)._tainted)
    //#post(String truncate(String, int, int, String)): init'ed(java.lang.StringBuilder:toString(...)._tainted)
    //#post(String truncate(String, int, int, String)): return_value != null
    //#unanalyzed(String truncate(String, int, int, String)): Effects-of-calling:java.lang.String:indexOf
    //#unanalyzed(String truncate(String, int, int, String)): Effects-of-calling:java.lang.String:substring
    //#unanalyzed(String truncate(String, int, int, String)): Effects-of-calling:java.lang.String:length
    //#unanalyzed(String truncate(String, int, int, String)): Effects-of-calling:java.lang.StringBuffer
    //#unanalyzed(String truncate(String, int, int, String)): Effects-of-calling:java.lang.StringBuffer:append
    //#unanalyzed(String truncate(String, int, int, String)): Effects-of-calling:java.lang.StringBuffer:toString
    //#unanalyzed(String truncate(String, int, int, String)): Effects-of-calling:java.lang.String:trim
    //#test_vector(String truncate(String, int, int, String)): lower - upper: {-6_442_450_943..0}, {1..6_442_450_943}
        
        // quickly adjust the upper if it is set lower than 'lower'
        if (upper < lower) {
            upper = lower;
        }
        
        // now determine if the string fits within the upper limit
        // if it does, go straight to return, do not pass 'go' and collect $200
        if(str2.length() > upper) {
            // the magic location int
            int loc;
            
            // first we determine where the next space appears after lower
            loc = str2.lastIndexOf(' ', upper);
            
            // now we'll see if the location is greater than the lower limit
            if(loc >= lower) {
                // yes it was, so we'll cut it off here
                str2 = str2.substring(0, loc);
            } else {
                // no it wasnt, so we'll cut it off at the upper limit
                str2 = str2.substring(0, upper);
                loc = upper;
    //#Utilities.java:558: Warning: unused assignment
    //#    unused assignment into loc
    //#    severity: LOW
    //#    class: org.apache.roller.weblogger.util.Utilities
    //#    method: String truncate(String, int, int, String)
            }
            
            // the string was truncated, so we append the appendToEnd String
            str2 = str2 + appendToEnd;
        }
        
        return str2;
    //#Utilities.java:565: end of method: String org.apache.roller.weblogger.util.Utilities.truncate(String, int, int, String)
    }
    
    /**
     * This method based on code from the String taglib at Apache Jakarta:
     * http://cvs.apache.org/viewcvs/jakarta-taglibs/string/src/org/apache/taglibs/string/util/StringW.java?rev=1.16&content-type=text/vnd.viewcvs-markup
     * Copyright (c) 1999 The Apache Software Foundation.
     * Author: timster@mac.com
     *
     * @param str
     * @param lower
     * @param upper
     * @param appendToEnd
     * @return
     */
    public static String truncateNicely(String str, int lower, int upper, String appendToEnd) {
        // strip markup from the string
        String str2 = removeHTML(str, false);
    //#Utilities.java:582: method: String org.apache.roller.weblogger.util.Utilities.truncateNicely(String, int, int, String)
    //#input(String truncateNicely(String, int, int, String)): " "._tainted
    //#input(String truncateNicely(String, int, int, String)): ""._tainted
    //#input(String truncateNicely(String, int, int, String)): appendToEnd
    //#input(String truncateNicely(String, int, int, String)): appendToEnd._tainted
    //#input(String truncateNicely(String, int, int, String)): lower
    //#input(String truncateNicely(String, int, int, String)): str
    //#input(String truncateNicely(String, int, int, String)): str._tainted
    //#input(String truncateNicely(String, int, int, String)): upper
    //#output(String truncateNicely(String, int, int, String)): java.lang.StringBuilder:toString(...)._tainted
    //#output(String truncateNicely(String, int, int, String)): return_value
    //#new obj(String truncateNicely(String, int, int, String)): java.lang.StringBuilder:toString(...)
    //#pre[5] (String truncateNicely(String, int, int, String)): str != null
    //#presumption(String truncateNicely(String, int, int, String)): java.lang.String:indexOf(...)@619 + java.lang.String:length(...)@619 in -2_147_483_648..4_294_967_295
    //#presumption(String truncateNicely(String, int, int, String)): java.lang.String:lastIndexOf(...)@613 <= 4_294_967_294
    //#post(String truncateNicely(String, int, int, String)): init'ed(java.lang.StringBuilder:toString(...)._tainted)
    //#post(String truncateNicely(String, int, int, String)): return_value == One-of{str, &java.lang.StringBuilder:toString(...)}
    //#post(String truncateNicely(String, int, int, String)): return_value != null
    //#unanalyzed(String truncateNicely(String, int, int, String)): Effects-of-calling:java.lang.String:indexOf
    //#unanalyzed(String truncateNicely(String, int, int, String)): Effects-of-calling:java.lang.String:substring
    //#unanalyzed(String truncateNicely(String, int, int, String)): Effects-of-calling:java.lang.String:length
    //#unanalyzed(String truncateNicely(String, int, int, String)): Effects-of-calling:java.lang.StringBuffer
    //#unanalyzed(String truncateNicely(String, int, int, String)): Effects-of-calling:java.lang.StringBuffer:append
    //#unanalyzed(String truncateNicely(String, int, int, String)): Effects-of-calling:java.lang.StringBuffer:toString
    //#unanalyzed(String truncateNicely(String, int, int, String)): Effects-of-calling:java.lang.String:trim
    //#test_vector(String truncateNicely(String, int, int, String)): lower - upper: {-6_442_450_943..0}, {1..6_442_450_943}
        boolean diff = (str2.length() < str.length());
        
        // quickly adjust the upper if it is set lower than 'lower'
        if(upper < lower) {
            upper = lower;
        }
        
        // now determine if the string fits within the upper limit
        // if it does, go straight to return, do not pass 'go' and collect $200
        if(str2.length() > upper) {
            // the magic location int
            int loc;
            
            // first we determine where the next space appears after lower
            loc = str2.lastIndexOf(' ', upper);
            
            // now we'll see if the location is greater than the lower limit
            if(loc >= lower) {
                // yes it was, so we'll cut it off here
                str2 = str2.substring(0, loc);
            } else {
                // no it wasnt, so we'll cut it off at the upper limit
                str2 = str2.substring(0, upper);
                loc = upper;
            }
            
            // HTML was removed from original str
            if (diff) {
                
                // location of last space in truncated string
                loc = str2.lastIndexOf(' ', loc);
                
                // get last "word" in truncated string (add 1 to loc to eliminate space
                String str3 = str2.substring(loc+1);
                
                // find this fragment in original str, from 'loc' position
                loc = str.indexOf(str3, loc) + str3.length();
                
                // get truncated string from original str, given new 'loc'
                str2 = str.substring(0, loc);
                
                // get all the HTML from original str after loc
                str3 = extractHTML(str.substring(loc));
                
                // remove any tags which generate visible HTML
                // This call is unecessary, all HTML has already been stripped
                //str3 = removeVisibleHTMLTags(str3);
                
                // append the appendToEnd String and
                // add extracted HTML back onto truncated string
                str = str2 + appendToEnd + str3;
            } else {
                // the string was truncated, so we append the appendToEnd String
                str = str2 + appendToEnd;
            }
            
        }
        
        return str;
    //#Utilities.java:641: end of method: String org.apache.roller.weblogger.util.Utilities.truncateNicely(String, int, int, String)
    }
    
    public static String truncateText(String str, int lower, int upper, String appendToEnd) {
        // strip markup from the string
        String str2 = removeHTML(str, false);
    //#Utilities.java:646: method: String org.apache.roller.weblogger.util.Utilities.truncateText(String, int, int, String)
    //#input(String truncateText(String, int, int, String)): " "._tainted
    //#input(String truncateText(String, int, int, String)): ""._tainted
    //#input(String truncateText(String, int, int, String)): appendToEnd
    //#input(String truncateText(String, int, int, String)): appendToEnd._tainted
    //#input(String truncateText(String, int, int, String)): lower
    //#input(String truncateText(String, int, int, String)): str
    //#input(String truncateText(String, int, int, String)): str._tainted
    //#input(String truncateText(String, int, int, String)): upper
    //#output(String truncateText(String, int, int, String)): java.lang.StringBuilder:toString(...)._tainted
    //#output(String truncateText(String, int, int, String)): return_value
    //#new obj(String truncateText(String, int, int, String)): java.lang.StringBuilder:toString(...)
    //#pre[5] (String truncateText(String, int, int, String)): str != null
    //#post(String truncateText(String, int, int, String)): init'ed(java.lang.StringBuilder:toString(...)._tainted)
    //#post(String truncateText(String, int, int, String)): return_value == One-of{str, &java.lang.StringBuilder:toString(...)}
    //#post(String truncateText(String, int, int, String)): return_value != null
    //#unanalyzed(String truncateText(String, int, int, String)): Effects-of-calling:java.lang.String:indexOf
    //#unanalyzed(String truncateText(String, int, int, String)): Effects-of-calling:java.lang.String:substring
    //#unanalyzed(String truncateText(String, int, int, String)): Effects-of-calling:java.lang.String:length
    //#unanalyzed(String truncateText(String, int, int, String)): Effects-of-calling:java.lang.StringBuffer
    //#unanalyzed(String truncateText(String, int, int, String)): Effects-of-calling:java.lang.StringBuffer:append
    //#unanalyzed(String truncateText(String, int, int, String)): Effects-of-calling:java.lang.StringBuffer:toString
    //#unanalyzed(String truncateText(String, int, int, String)): Effects-of-calling:java.lang.String:trim
    //#test_vector(String truncateText(String, int, int, String)): lower - upper: {-6_442_450_943..0}, {1..6_442_450_943}
        boolean diff = (str2.length() < str.length());
    //#Utilities.java:647: Warning: unused assignment
    //#    unused assignment into diff
    //#    severity: LOW
    //#    class: org.apache.roller.weblogger.util.Utilities
    //#    method: String truncateText(String, int, int, String)
        
        // quickly adjust the upper if it is set lower than 'lower'
        if(upper < lower) {
            upper = lower;
        }
        
        // now determine if the string fits within the upper limit
        // if it does, go straight to return, do not pass 'go' and collect $200
        if(str2.length() > upper) {
            // the magic location int
            int loc;
            
            // first we determine where the next space appears after lower
            loc = str2.lastIndexOf(' ', upper);
            
            // now we'll see if the location is greater than the lower limit
            if(loc >= lower) {
                // yes it was, so we'll cut it off here
                str2 = str2.substring(0, loc);
            } else {
                // no it wasnt, so we'll cut it off at the upper limit
                str2 = str2.substring(0, upper);
                loc = upper;
    //#Utilities.java:670: Warning: unused assignment
    //#    unused assignment into loc
    //#    severity: LOW
    //#    class: org.apache.roller.weblogger.util.Utilities
    //#    method: String truncateText(String, int, int, String)
            }
            // the string was truncated, so we append the appendToEnd String
            str = str2 + appendToEnd;
        }
        return str;
    //#Utilities.java:675: end of method: String org.apache.roller.weblogger.util.Utilities.truncateText(String, int, int, String)
    }
    
    /**
     * @param str
     * @return
     */
    private static String stripLineBreaks(String str) {
        // TODO: use a string buffer, ignore case !
        str = str.replaceAll("<br>", "");
    //#Utilities.java:684: method: String org.apache.roller.weblogger.util.Utilities.stripLineBreaks(String)
    //#input(String stripLineBreaks(String)): str
    //#output(String stripLineBreaks(String)): return_value
    //#pre[1] (String stripLineBreaks(String)): str != null
    //#post(String stripLineBreaks(String)): return_value != null
        str = str.replaceAll("<br/>", "");
        str = str.replaceAll("<br />", "");
        str = str.replaceAll("<p></p>", "");
        str = str.replaceAll("<p/>","");
        str = str.replaceAll("<p />","");
        return str;
    //#Utilities.java:690: end of method: String org.apache.roller.weblogger.util.Utilities.stripLineBreaks(String)
    }
    
    /**
     * Need need to get rid of any user-visible HTML tags once all text has been
     * removed such as &lt;BR&gt;. This sounds like a better approach than removing
     * all HTML tags and taking the chance to leave some tags un-closed.
     *
     * WARNING: this method has serious performance problems a
     *
     * @author Alexis Moussine-Pouchkine (alexis.moussine-pouchkine@france.sun.com)
     * @author Lance Lavandowska
     * @param str the String object to modify
     * @return the new String object without the HTML "visible" tags
     */
    private static String removeVisibleHTMLTags(String str) {
        str = stripLineBreaks(str);
    //#Utilities.java:706: method: String org.apache.roller.weblogger.util.Utilities.removeVisibleHTMLTags(String)
    //#input(String removeVisibleHTMLTags(String)): "<"._tainted
    //#input(String removeVisibleHTMLTags(String)): "<."._tainted
    //#input(String removeVisibleHTMLTags(String)): ">"._tainted
    //#input(String removeVisibleHTMLTags(String)): "a"._tainted
    //#input(String removeVisibleHTMLTags(String)): "div"._tainted
    //#input(String removeVisibleHTMLTags(String)): "h1"._tainted
    //#input(String removeVisibleHTMLTags(String)): "h2"._tainted
    //#input(String removeVisibleHTMLTags(String)): "h3"._tainted
    //#input(String removeVisibleHTMLTags(String)): "h4"._tainted
    //#input(String removeVisibleHTMLTags(String)): "li"._tainted
    //#input(String removeVisibleHTMLTags(String)): str
    //#input(String removeVisibleHTMLTags(String)): str._tainted
    //#output(String removeVisibleHTMLTags(String)): java.lang.StringBuffer:toString(...)._tainted
    //#output(String removeVisibleHTMLTags(String)): return_value
    //#new obj(String removeVisibleHTMLTags(String)): java.lang.StringBuffer:toString(...)
    //#pre[1] (String removeVisibleHTMLTags(String)): str != null
    //#presumption(String removeVisibleHTMLTags(String)): java.lang.StringBuffer:indexOf(...)@714 + java.lang.String:length(...)@716 in -2_147_483_648..4_294_967_295
    //#presumption(String removeVisibleHTMLTags(String)): java.lang.StringBuffer:indexOf(...)@714 + java.lang.String:length(...)@717 in -2_147_483_648..4_294_967_295
    //#presumption(String removeVisibleHTMLTags(String)): java.lang.StringBuffer:indexOf(...)@720 <= 4_294_967_294
    //#presumption(String removeVisibleHTMLTags(String)): java.lang.StringBuffer:indexOf(...)@738 <= 4_294_967_294
    //#presumption(String removeVisibleHTMLTags(String)): java.lang.StringBuffer:indexOf(...)@741 + java.lang.String:length(...)@744 in -2_147_483_648..4_294_967_295
    //#presumption(String removeVisibleHTMLTags(String)): java.lang.StringBuffer:indexOf(...)@741 + java.lang.String:length(...)@745 in -2_147_483_648..4_294_967_295
    //#presumption(String removeVisibleHTMLTags(String)): java.lang.StringBuffer:indexOf(...)@748 <= 4_294_967_294
    //#post(String removeVisibleHTMLTags(String)): init'ed(java.lang.StringBuffer:toString(...)._tainted)
    //#post(String removeVisibleHTMLTags(String)): return_value == &java.lang.StringBuffer:toString(...)
    //#unanalyzed(String removeVisibleHTMLTags(String)): Effects-of-calling:java.lang.String:replaceAll
    //#test_vector(String removeVisibleHTMLTags(String)): java.lang.String:endsWith(...)@715: {0}, {1}
    //#test_vector(String removeVisibleHTMLTags(String)): java.lang.StringBuffer:charAt(...)@750: {0..46, 48..65_535}, {47}
    //#test_vector(String removeVisibleHTMLTags(String)): java.lang.StringBuffer:indexOf(...)@714: {-1}, {-2_147_483_648..-2, 0..4_294_967_295}
    //#test_vector(String removeVisibleHTMLTags(String)): java.lang.StringBuffer:indexOf(...)@720: {-2_147_483_648..-1}, {0..4_294_967_294}
    //#test_vector(String removeVisibleHTMLTags(String)): java.lang.StringBuffer:indexOf(...)@738: {-2_147_483_648..-1}, {0..4_294_967_293}
    //#test_vector(String removeVisibleHTMLTags(String)): java.lang.StringBuffer:indexOf(...)@741: {-2_147_483_648..-1}, {0..4_294_967_295}
    //#test_vector(String removeVisibleHTMLTags(String)): java.lang.StringBuffer:indexOf(...)@749: {-2_147_483_648..-2, 0..4_294_967_294}, {-1}
        StringBuffer result = new StringBuffer(str);
        StringBuffer lcresult = new StringBuffer(str.toLowerCase());
        
        // <img should take care of smileys
        String[] visibleTags = {"<img"}; // are there others to add?
        int stringIndex;
        for ( int j = 0 ;  j < visibleTags.length ; j++ ) {
            while ( (stringIndex = lcresult.indexOf(visibleTags[j])) != -1 ) {
                if ( visibleTags[j].endsWith(">") )  {
                    result.delete(stringIndex, stringIndex+visibleTags[j].length() );
                    lcresult.delete(stringIndex, stringIndex+visibleTags[j].length() );
                } else {
                    // need to delete everything up until next closing '>', for <img for instance
                    int endIndex = result.indexOf(">", stringIndex);
                    if (endIndex > -1) {
                        // only delete it if we find the end!  If we don't the HTML may be messed up, but we
                        // can't safely delete anything.
                        result.delete(stringIndex, endIndex + 1 );
                        lcresult.delete(stringIndex, endIndex + 1 );
                    }
                }
            }
        }
        
        // TODO:  This code is buggy by nature.  It doesn't deal with nesting of tags properly.
        // remove certain elements with open & close tags
        String[] openCloseTags = {"li", "a", "div", "h1", "h2", "h3", "h4"}; // more ?
        for (int j = 0; j < openCloseTags.length; j++) {
            // could this be better done with a regular expression?
            String closeTag = "</"+openCloseTags[j]+">";
            int lastStringIndex = 0;
            while ( (stringIndex = lcresult.indexOf( "<"+openCloseTags[j], lastStringIndex)) > -1) {
                lastStringIndex = stringIndex;
                // Try to find the matching closing tag  (ignores possible nesting!)
                int endIndex = lcresult.indexOf(closeTag, stringIndex);
                if (endIndex > -1) {
                    // If we found it delete it.
                    result.delete(stringIndex, endIndex+closeTag.length());
                    lcresult.delete(stringIndex, endIndex+closeTag.length());
                } else {
                    // Try to see if it is a self-closed empty content tag, i.e. closed with />.
                    endIndex = lcresult.indexOf(">", stringIndex);
                    int nextStart = lcresult.indexOf("<", stringIndex+1);
                    if (endIndex > stringIndex && lcresult.charAt(endIndex-1) == '/' && (endIndex < nextStart || nextStart == -1)) {
                        // Looks like it, so remove it.
                        result.delete(stringIndex, endIndex + 1);
                        lcresult.delete(stringIndex, endIndex + 1);
                        
                    }
                }
            }
        }
        
        return result.toString();
    //#Utilities.java:760: end of method: String org.apache.roller.weblogger.util.Utilities.removeVisibleHTMLTags(String)
    }
    
    /**
     * Extract (keep) JUST the HTML from the String.
     * @param str
     * @return
     */
    public static String extractHTML(String str) {
        if (str == null) return "";
    //#Utilities.java:769: method: String org.apache.roller.weblogger.util.Utilities.extractHTML(String)
    //#input(String extractHTML(String)): str
    //#input(String extractHTML(String)): str._tainted
    //#output(String extractHTML(String)): java.lang.StringBuffer:toString(...)._tainted
    //#output(String extractHTML(String)): return_value
    //#new obj(String extractHTML(String)): java.lang.StringBuffer:toString(...)
    //#presumption(String extractHTML(String)): java.lang.String:indexOf(...)@778 <= 4_294_967_294
    //#post(String extractHTML(String)): init'ed(java.lang.StringBuffer:toString(...)._tainted)
    //#post(String extractHTML(String)): return_value == One-of{&"", str, &java.lang.StringBuffer:toString(...)}
    //#post(String extractHTML(String)): return_value != null
    //#test_vector(String extractHTML(String)): str: Inverse{null}, Addr_Set{null}
    //#test_vector(String extractHTML(String)): java.lang.String:indexOf(...)@772: {-2_147_483_648..-2, 0..4_294_967_295}, {-1}
    //#test_vector(String extractHTML(String)): java.lang.String:indexOf(...)@778: {-2_147_483_648..-1}, {0..4_294_967_294}
        StringBuffer ret = new StringBuffer(str.length());
        int start = 0;
        int beginTag = str.indexOf("<");
        int endTag = 0;
    //#Utilities.java:773: Warning: unused assignment
    //#    unused assignment into endTag
    //#    severity: SUPPRESSED
    //#    class: org.apache.roller.weblogger.util.Utilities
    //#    method: String extractHTML(String)
    //#    Attribs:  Uncertain
        if (beginTag == -1)
            return str;
        
        while (beginTag >= start) {
            endTag = str.indexOf(">", beginTag);
            
            // if endTag found, keep tag
            if (endTag > -1) {
                ret.append( str.substring(beginTag, endTag+1) );
                
                // move start forward and find another tag
                start = endTag + 1;
                beginTag = str.indexOf("<", start);
            }
            // if no endTag found, break
            else {
                break;
            }
        }
        return ret.toString();
    //#Utilities.java:793: end of method: String org.apache.roller.weblogger.util.Utilities.extractHTML(String)
    }
    
    
    public static String hexEncode(String str) {
        if (StringUtils.isEmpty(str)) return str;
    //#Utilities.java:798: method: String org.apache.roller.weblogger.util.Utilities.hexEncode(String)
    //#Utilities.java:798: Warning: method not available
    //#    -- call on bool org.apache.commons.lang.StringUtils:isEmpty(String)
    //#    severity: INFORMATIONAL
    //#    class: org.apache.roller.weblogger.util.Utilities
    //#    method: String hexEncode(String)
    //#    unanalyzed callee: bool org.apache.commons.lang.StringUtils:isEmpty(String)
    //#input(String hexEncode(String)): str
    //#output(String hexEncode(String)): return_value
    //#post(String hexEncode(String)): init'ed(return_value)
    //#test_vector(String hexEncode(String)): org.apache.commons.lang.StringUtils:isEmpty(...)@798: {0}, {1}
        
        return RegexUtil.encode(str);
    //#Utilities.java:800: Warning: method not available
    //#    -- call on String org.apache.roller.util.RegexUtil:encode(String)
    //#    severity: INFORMATIONAL
    //#    class: org.apache.roller.weblogger.util.Utilities
    //#    method: String hexEncode(String)
    //#    unanalyzed callee: String org.apache.roller.util.RegexUtil:encode(String)
    //#Utilities.java:800: end of method: String org.apache.roller.weblogger.util.Utilities.hexEncode(String)
    }
    
    public static String encodeEmail(String str) {
        return str!=null ? RegexUtil.encodeEmail(str) : null;
    //#Utilities.java:804: method: String org.apache.roller.weblogger.util.Utilities.encodeEmail(String)
    //#Utilities.java:804: Warning: method not available
    //#    -- call on String org.apache.roller.util.RegexUtil:encodeEmail(String)
    //#    severity: INFORMATIONAL
    //#    class: org.apache.roller.weblogger.util.Utilities
    //#    method: String encodeEmail(String)
    //#    unanalyzed callee: String org.apache.roller.util.RegexUtil:encodeEmail(String)
    //#input(String encodeEmail(String)): str
    //#output(String encodeEmail(String)): return_value
    //#post(String encodeEmail(String)): init'ed(return_value)
    //#Utilities.java:804: end of method: String org.apache.roller.weblogger.util.Utilities.encodeEmail(String)
    }

    /**
     * URL encoding.
     * @param s a string to be URL-encoded
     * @return URL encoding of s using character encoding UTF-8; null if s is null.
     */
    public static final String encode(String s) {
        try {
            if (s != null)
    //#Utilities.java:814: method: String org.apache.roller.weblogger.util.Utilities.encode(String)
    //#input(String encode(String)): s
    //#output(String encode(String)): return_value
    //#post(String encode(String)): init'ed(return_value)
    //#test_vector(String encode(String)): s: Addr_Set{null}, Inverse{null}
                return URLEncoder.encode(s, "UTF-8");
            else
                return s;
        } catch (UnsupportedEncodingException e) {
            // Java Spec requires UTF-8 be in all Java environments, so this should not happen
            return s;
    //#Utilities.java:820: end of method: String org.apache.roller.weblogger.util.Utilities.encode(String)
        }
    }

    /**
     * URL decoding.
     * @param s a URL-encoded string to be URL-decoded
     * @return URL decoded value of s using character encoding UTF-8; null if s is null.
     */
    public static final String decode(String s) {
        try {
            if (s != null)
    //#Utilities.java:831: method: String org.apache.roller.weblogger.util.Utilities.decode(String)
    //#input(String decode(String)): s
    //#output(String decode(String)): return_value
    //#post(String decode(String)): init'ed(return_value)
    //#test_vector(String decode(String)): s: Addr_Set{null}, Inverse{null}
                return URLDecoder.decode(s, "UTF-8");
            else
                return s;
        } catch (UnsupportedEncodingException e) {
            // Java Spec requires UTF-8 be in all Java environments, so this should not happen
            return s;
    //#Utilities.java:837: end of method: String org.apache.roller.weblogger.util.Utilities.decode(String)
        }
    }

    /**
     * @param string
     * @return
     */
    public static int stringToInt(String string) {
        try {
            return Integer.valueOf(string).intValue();
    //#Utilities.java:847: method: int org.apache.roller.weblogger.util.Utilities.stringToInt(String)
    //#input(int stringToInt(String)): "Invalid Integer:"._tainted
    //#input(int stringToInt(String)): mLogger
    //#input(int stringToInt(String)): string
    //#input(int stringToInt(String)): string._tainted
    //#output(int stringToInt(String)): return_value
    //#pre[1] (int stringToInt(String)): (soft) mLogger != null
    //#presumption(int stringToInt(String)): java.lang.Integer:valueOf(...)@847 != null
    //#post(int stringToInt(String)): init'ed(return_value)
        } catch (NumberFormatException e) {
            mLogger.debug("Invalid Integer:" + string);
    //#Utilities.java:849: Warning: method not available
    //#    -- call on void org.apache.commons.logging.Log:debug(Object)
    //#    severity: INFORMATIONAL
    //#    class: org.apache.roller.weblogger.util.Utilities
    //#    method: int stringToInt(String)
    //#    unanalyzed callee: void org.apache.commons.logging.Log:debug(Object)
        }
        return 0;
    //#Utilities.java:851: end of method: int org.apache.roller.weblogger.util.Utilities.stringToInt(String)
    }
                    
    /**
     * Convert a byte array into a Base64 string (as used in mime formats)
     */
    public static String toBase64(byte[] aValue) {
        
        final String m_strBase64Chars =
    //#Utilities.java:859: method: String org.apache.roller.weblogger.util.Utilities.toBase64(byte[])
    //#Utilities.java:859: Warning: unused assignment
    //#    unused assignment into m_strBase64Chars
    //#    severity: LOW
    //#    class: org.apache.roller.weblogger.util.Utilities
    //#    method: String toBase64(byte[])
    //#Utilities.java:859: Warning: suspicious precondition
    //#    the precondition for aValue.length is not a contiguous range of values
    //#    severity: SUPPRESSED
    //#    class: org.apache.roller.weblogger.util.Utilities
    //#    method: String toBase64(byte[])
    //#    suspicious precondition index: [2]
    //#    Attribs:  Soft
    //#input(String toBase64(byte[])): aValue
    //#input(String toBase64(byte[])): aValue.length
    //#input(String toBase64(byte[])): aValue[0..4_294_967_295]
    //#output(String toBase64(byte[])): java.lang.StringBuffer:toString(...)._tainted
    //#output(String toBase64(byte[])): return_value
    //#new obj(String toBase64(byte[])): java.lang.StringBuffer:toString(...)
    //#pre[1] (String toBase64(byte[])): aValue != null
    //#pre[2] (String toBase64(byte[])): (soft) aValue.length in {0, 3..4_294_967_295}
    //#pre[3] (String toBase64(byte[])): (soft) init'ed(aValue[0..4_294_967_295])
    //#post(String toBase64(byte[])): java.lang.StringBuffer:toString(...)._tainted == 0
    //#post(String toBase64(byte[])): return_value == &java.lang.StringBuffer:toString(...)
                "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
        
        int byte1;
        int byte2;
        int byte3;
        int iByteLen = aValue.length;
        StringBuffer tt = new StringBuffer();
        
        for (int i = 0; i < iByteLen; i += 3) {
    //#Utilities.java:868: ?overflow
    //#    i in -2_147_483_651..4_294_967_292
    //#    severity: SUPPRESSED
    //#    class: org.apache.roller.weblogger.util.Utilities
    //#    method: String toBase64(byte[])
    //#    basic block: bb_21
    //#    assertion: i in -2_147_483_651..4_294_967_292
    //#    VN: i + 3
    //#    Expected: {-2_147_483_648..4_294_967_295, Invalid}
    //#    Bad: {4_294_967_296,4_294_967_297}
    //#    Attribs:  Int  Bad > Exp
            boolean bByte2 = (i + 1) < iByteLen;
            boolean bByte3 = (i + 2) < iByteLen;
            byte1 = aValue[i] & 0xFF;
            byte2 = (bByte2) ? (aValue[i + 1] & 0xFF) : 0;
            byte3 = (bByte3) ? (aValue[i + 2] & 0xFF) : 0;
            
            tt.append(m_strBase64Chars.charAt(byte1 / 4));
            tt.append(m_strBase64Chars.charAt((byte2 / 16) + ((byte1 & 0x3) * 16)));
            tt.append(((bByte2) ? m_strBase64Chars.charAt((byte3 / 64) + ((byte2 & 0xF) * 4)) : '='));
            tt.append(((bByte3) ? m_strBase64Chars.charAt(byte3 & 0x3F) : '='));
        }
        
        return tt.toString();
    //#Utilities.java:881: end of method: String org.apache.roller.weblogger.util.Utilities.toBase64(byte[])
    }
    
    /**
     * @param tag
     * @return
     */
    public static String stripInvalidTagCharacters(String tag) {
        if (tag == null)
    //#Utilities.java:889: method: String org.apache.roller.weblogger.util.Utilities.stripInvalidTagCharacters(String)
    //#input(String stripInvalidTagCharacters(String)): tag
    //#output(String stripInvalidTagCharacters(String)): java.lang.StringBuffer:toString(...)._tainted
    //#output(String stripInvalidTagCharacters(String)): return_value
    //#new obj(String stripInvalidTagCharacters(String)): java.lang.StringBuffer:toString(...)
    //#pre[1] (String stripInvalidTagCharacters(String)): tag != null
    //#presumption(String stripInvalidTagCharacters(String)): charArray.length@893 <= 4_294_967_295
    //#post(String stripInvalidTagCharacters(String)): java.lang.StringBuffer:toString(...)._tainted == 0
    //#post(String stripInvalidTagCharacters(String)): return_value == &java.lang.StringBuffer:toString(...)
    //#test_vector(String stripInvalidTagCharacters(String)): java.lang.Character:isUnicodeIdentifierPart(...)@904: {1}, {0}
    //#test_vector(String stripInvalidTagCharacters(String)): java.lang.Character:isUnicodeIdentifierStart(...)@904: {0}, {1}
            throw new NullPointerException();

        StringBuffer sb = new StringBuffer();
        char[] charArray = tag.toCharArray();
        for (int i = 0; i < charArray.length; i++) {
            char c = charArray[i];
    //#Utilities.java:895: ?use of default init
    //#    init'ed(charArray[i])
    //#    severity: LOW
    //#    class: org.apache.roller.weblogger.util.Utilities
    //#    method: String stripInvalidTagCharacters(String)
    //#    basic block: bb_3
    //#    assertion: init'ed(charArray[i])
    //#    VN: undefined
    //#    Expected: {-Inf..+Inf}
    //#    Bad: {Invalid}
    //#    Attribs:  Int  Bad only invalid

            // fast-path exclusions quotes and commas are obvious
            switch (c) {
    //#Utilities.java:898: ?use of default init
    //#    init'ed(c)
    //#    severity: LOW
    //#    class: org.apache.roller.weblogger.util.Utilities
    //#    method: String stripInvalidTagCharacters(String)
    //#    basic block: bb_3
    //#    assertion: init'ed(c)
    //#    VN: undefined
    //#    Expected: {-Inf..+Inf}
    //#    Bad: {Invalid}
    //#    Attribs:  Int  Bad only invalid
            case 34: // "
            case 44: // ,
                continue;
            }

            if ((33 <= c && c <= 126) || Character.isUnicodeIdentifierPart(c)
    //#Utilities.java:904: ?use of default init
    //#    init'ed(c)
    //#    severity: LOW
    //#    class: org.apache.roller.weblogger.util.Utilities
    //#    method: String stripInvalidTagCharacters(String)
    //#    basic block: bb_5
    //#    assertion: init'ed(c)
    //#    VN: undefined
    //#    Expected: {-Inf..+Inf}
    //#    Bad: {Invalid}
    //#    Attribs:  Int  Bad only invalid
    //#Utilities.java:904: ?use of default init
    //#    init'ed(c)
    //#    severity: LOW
    //#    class: org.apache.roller.weblogger.util.Utilities
    //#    method: String stripInvalidTagCharacters(String)
    //#    basic block: bb_7
    //#    assertion: init'ed(c)
    //#    VN: undefined
    //#    Expected: {-Inf..+Inf}
    //#    Bad: {Invalid}
    //#    Attribs:  Int  Bad only invalid
    //#Utilities.java:904: ?use of default init
    //#    init'ed(c)
    //#    severity: LOW
    //#    class: org.apache.roller.weblogger.util.Utilities
    //#    method: String stripInvalidTagCharacters(String)
    //#    basic block: bb_8
    //#    assertion: init'ed(c)
    //#    VN: undefined
    //#    Expected: {-Inf..+Inf}
    //#    Bad: {Invalid}
    //#    Attribs:  Int  Bad only invalid
                    || Character.isUnicodeIdentifierStart(c)) {
                sb.append(charArray[i]);
    //#Utilities.java:906: ?use of default init
    //#    init'ed(charArray[i])
    //#    severity: LOW
    //#    class: org.apache.roller.weblogger.util.Utilities
    //#    method: String stripInvalidTagCharacters(String)
    //#    basic block: bb_9
    //#    assertion: init'ed(charArray[i])
    //#    VN: undefined
    //#    Expected: {-Inf..+Inf}
    //#    Bad: {Invalid}
    //#    Attribs:  Int  Bad only invalid
            }
        }
        return sb.toString();
    //#Utilities.java:909: end of method: String org.apache.roller.weblogger.util.Utilities.stripInvalidTagCharacters(String)
    }
        
    public static String normalizeTag(String tag, Locale locale) {
        tag = Utilities.stripInvalidTagCharacters(tag);
    //#Utilities.java:913: method: String org.apache.roller.weblogger.util.Utilities.normalizeTag(String, Locale)
    //#input(String normalizeTag(String, Locale)): locale
    //#input(String normalizeTag(String, Locale)): tag
    //#output(String normalizeTag(String, Locale)): return_value
    //#pre[2] (String normalizeTag(String, Locale)): tag != null
    //#post(String normalizeTag(String, Locale)): return_value != null
    //#unanalyzed(String normalizeTag(String, Locale)): Effects-of-calling:java.lang.StringBuffer:toString
    //#unanalyzed(String normalizeTag(String, Locale)): Effects-of-calling:java.lang.StringBuffer
    //#unanalyzed(String normalizeTag(String, Locale)): Effects-of-calling:java.lang.String:toCharArray
    //#unanalyzed(String normalizeTag(String, Locale)): Effects-of-calling:java.lang.StringBuffer:append
    //#unanalyzed(String normalizeTag(String, Locale)): Effects-of-calling:java.lang.Character:isUnicodeIdentifierPart
    //#unanalyzed(String normalizeTag(String, Locale)): Effects-of-calling:java.lang.Character:isUnicodeIdentifierStart
    //#test_vector(String normalizeTag(String, Locale)): locale: Inverse{null}, Addr_Set{null}
        return locale == null ? tag.toLowerCase() : tag.toLowerCase(locale);        
    //#Utilities.java:914: end of method: String org.apache.roller.weblogger.util.Utilities.normalizeTag(String, Locale)
    }
    
    /**
     * @param tags
     * @return
     */
    public static List splitStringAsTags(String tags)  {
        String[] tagsarr = StringUtils.split(tags, TAG_SPLIT_CHARS);
    //#Utilities.java:922: method: List org.apache.roller.weblogger.util.Utilities.splitStringAsTags(String)
    //#Utilities.java:922: Warning: method not available
    //#    -- call on String[] org.apache.commons.lang.StringUtils:split(String, String)
    //#    severity: INFORMATIONAL
    //#    class: org.apache.roller.weblogger.util.Utilities
    //#    method: List splitStringAsTags(String)
    //#    unanalyzed callee: String[] org.apache.commons.lang.StringUtils:split(String, String)
    //#input(List splitStringAsTags(String)): java.util.Collections.EMPTY_LIST
    //#input(List splitStringAsTags(String)): tags
    //#output(List splitStringAsTags(String)): return_value
    //#presumption(List splitStringAsTags(String)): init'ed(java.util.Collections.EMPTY_LIST)
    //#post(List splitStringAsTags(String)): init'ed(return_value)
    //#test_vector(List splitStringAsTags(String)): org.apache.commons.lang.StringUtils:split(...)@922: Inverse{null}, Addr_Set{null}
        if(tagsarr == null)
            return Collections.EMPTY_LIST;
        return Arrays.asList(tagsarr);
    //#Utilities.java:925: end of method: List org.apache.roller.weblogger.util.Utilities.splitStringAsTags(String)
    }
    
    
    /**
     * Transforms the given String into a subset of HTML displayable on a web
     * page. The subset includes &lt;b&gt;, &lt;i&gt;, &lt;p&gt;, &lt;br&gt;,
     * &lt;pre&gt; and &lt;a href&gt; (and their corresponding end tags).
     *
     * @param s   the String to transform
     * @return    the transformed String
     */
    public static String transformToHTMLSubset(String s) {
        
        if (s == null) {
    //#Utilities.java:939: method: String org.apache.roller.weblogger.util.Utilities.transformToHTMLSubset(String)
    //#input(String transformToHTMLSubset(String)): "<"._tainted
    //#input(String transformToHTMLSubset(String)): ">"._tainted
    //#input(String transformToHTMLSubset(String)): BR_TAG_PATTERN
    //#input(String transformToHTMLSubset(String)): CLOSING_A_TAG_PATTERN
    //#input(String transformToHTMLSubset(String)): CLOSING_BLOCKQUOTE_TAG_PATTERN
    //#input(String transformToHTMLSubset(String)): CLOSING_B_TAG_PATTERN
    //#input(String transformToHTMLSubset(String)): CLOSING_I_TAG_PATTERN
    //#input(String transformToHTMLSubset(String)): CLOSING_LI_TAG_PATTERN
    //#input(String transformToHTMLSubset(String)): CLOSING_OL_TAG_PATTERN
    //#input(String transformToHTMLSubset(String)): CLOSING_PRE_TAG_PATTERN
    //#input(String transformToHTMLSubset(String)): CLOSING_P_TAG_PATTERN
    //#input(String transformToHTMLSubset(String)): CLOSING_UL_TAG_PATTERN
    //#input(String transformToHTMLSubset(String)): OPENING_A_TAG_PATTERN
    //#input(String transformToHTMLSubset(String)): OPENING_BLOCKQUOTE_TAG_PATTERN
    //#input(String transformToHTMLSubset(String)): OPENING_B_TAG_PATTERN
    //#input(String transformToHTMLSubset(String)): OPENING_I_TAG_PATTERN
    //#input(String transformToHTMLSubset(String)): OPENING_LI_TAG_PATTERN
    //#input(String transformToHTMLSubset(String)): OPENING_OL_TAG_PATTERN
    //#input(String transformToHTMLSubset(String)): OPENING_PRE_TAG_PATTERN
    //#input(String transformToHTMLSubset(String)): OPENING_P_TAG_PATTERN
    //#input(String transformToHTMLSubset(String)): OPENING_UL_TAG_PATTERN
    //#input(String transformToHTMLSubset(String)): QUOTE_PATTERN
    //#input(String transformToHTMLSubset(String)): s
    //#input(String transformToHTMLSubset(String)): s._tainted
    //#output(String transformToHTMLSubset(String)): java.lang.StringBuilder:toString(...)._tainted
    //#output(String transformToHTMLSubset(String)): return_value
    //#new obj(String transformToHTMLSubset(String)): java.lang.StringBuilder:toString(...)
    //#presumption(String transformToHTMLSubset(String)): java.util.regex.Matcher:replaceAll(...)@985 != null
    //#presumption(String transformToHTMLSubset(String)): java.util.regex.Pattern:compile(...)@43 != null
    //#presumption(String transformToHTMLSubset(String)): java.util.regex.Pattern:compile(...)@45 != null
    //#presumption(String transformToHTMLSubset(String)): java.util.regex.Pattern:compile(...)@47 != null
    //#presumption(String transformToHTMLSubset(String)): java.util.regex.Pattern:compile(...)@49 != null
    //#presumption(String transformToHTMLSubset(String)): java.util.regex.Pattern:compile(...)@51 != null
    //#presumption(String transformToHTMLSubset(String)): java.util.regex.Pattern:compile(...)@53 != null
    //#presumption(String transformToHTMLSubset(String)): java.util.regex.Pattern:compile(...)@55 != null
    //#presumption(String transformToHTMLSubset(String)): java.util.regex.Pattern:compile(...)@57 != null
    //#presumption(String transformToHTMLSubset(String)): java.util.regex.Pattern:compile(...)@59 != null
    //#presumption(String transformToHTMLSubset(String)): java.util.regex.Pattern:compile(...)@61 != null
    //#presumption(String transformToHTMLSubset(String)): java.util.regex.Pattern:compile(...)@63 != null
    //#presumption(String transformToHTMLSubset(String)): java.util.regex.Pattern:compile(...)@65 != null
    //#presumption(String transformToHTMLSubset(String)): java.util.regex.Pattern:compile(...)@67 != null
    //#presumption(String transformToHTMLSubset(String)): java.util.regex.Pattern:compile(...)@69 != null
    //#presumption(String transformToHTMLSubset(String)): java.util.regex.Pattern:compile(...)@71 != null
    //#presumption(String transformToHTMLSubset(String)): java.util.regex.Pattern:compile(...)@73 != null
    //#presumption(String transformToHTMLSubset(String)): java.util.regex.Pattern:compile(...)@75 != null
    //#presumption(String transformToHTMLSubset(String)): java.util.regex.Pattern:compile(...)@77 != null
    //#presumption(String transformToHTMLSubset(String)): java.util.regex.Pattern:compile(...)@79 != null
    //#presumption(String transformToHTMLSubset(String)): java.util.regex.Pattern:compile(...)@81 != null
    //#presumption(String transformToHTMLSubset(String)): java.util.regex.Pattern:matcher(...)@964 != null
    //#post(String transformToHTMLSubset(String)): init'ed(java.lang.StringBuilder:toString(...)._tainted)
    //#post(String transformToHTMLSubset(String)): init'ed(return_value)
    //#unanalyzed(String transformToHTMLSubset(String)): Effects-of-calling:java.util.regex.Pattern:matcher
    //#unanalyzed(String transformToHTMLSubset(String)): Effects-of-calling:java.util.regex.Matcher:replaceAll
    //#test_vector(String transformToHTMLSubset(String)): s: Inverse{null}, Addr_Set{null}
    //#test_vector(String transformToHTMLSubset(String)): java.util.regex.Matcher:find(...)@965: {0}, {1}
            return null;
        }
        
        s = replace(s, OPENING_B_TAG_PATTERN, "<b>");
        s = replace(s, CLOSING_B_TAG_PATTERN, "</b>");
        s = replace(s, OPENING_I_TAG_PATTERN, "<i>");
        s = replace(s, CLOSING_I_TAG_PATTERN, "</i>");
        s = replace(s, OPENING_BLOCKQUOTE_TAG_PATTERN, "<blockquote>");
        s = replace(s, CLOSING_BLOCKQUOTE_TAG_PATTERN, "</blockquote>");
        s = replace(s, BR_TAG_PATTERN, "<br />");
        s = replace(s, OPENING_P_TAG_PATTERN, "<p>");
        s = replace(s, CLOSING_P_TAG_PATTERN, "</p>");
        s = replace(s, OPENING_PRE_TAG_PATTERN, "<pre>");
        s = replace(s, CLOSING_PRE_TAG_PATTERN, "</pre>");
        s = replace(s, OPENING_UL_TAG_PATTERN, "<ul>");
        s = replace(s, CLOSING_UL_TAG_PATTERN, "</ul>");
        s = replace(s, OPENING_OL_TAG_PATTERN, "<ol>");
        s = replace(s, CLOSING_OL_TAG_PATTERN, "</ol>");
        s = replace(s, OPENING_LI_TAG_PATTERN, "<li>");
        s = replace(s, CLOSING_LI_TAG_PATTERN, "</li>");
        s = replace(s, QUOTE_PATTERN, "\"");
        
        // HTTP links
        s = replace(s, CLOSING_A_TAG_PATTERN, "</a>");
        Matcher m = OPENING_A_TAG_PATTERN.matcher(s);
        while (m.find()) {
            int start = m.start();
            int end = m.end();
            String link = s.substring(start, end);
            link = "<" + link.substring(4, link.length() - 4) + ">";
            s = s.substring(0, start) + link + s.substring(end, s.length());
            m = OPENING_A_TAG_PATTERN.matcher(s);
        }
        
        // escaped angle brackets
        s = s.replaceAll("&amp;lt;", "&lt;");
        s = s.replaceAll("&amp;gt;", "&gt;");
        s = s.replaceAll("&amp;#", "&#");
        
        return s;
    //#Utilities.java:979: end of method: String org.apache.roller.weblogger.util.Utilities.transformToHTMLSubset(String)
    }
    
    
    private static String replace(String string, Pattern pattern, String replacement) {
        Matcher m = pattern.matcher(string);
    //#Utilities.java:984: method: String org.apache.roller.weblogger.util.Utilities.replace(String, Pattern, String)
    //#input(String replace(String, Pattern, String)): pattern
    //#input(String replace(String, Pattern, String)): replacement
    //#input(String replace(String, Pattern, String)): string
    //#output(String replace(String, Pattern, String)): return_value
    //#pre[1] (String replace(String, Pattern, String)): pattern != null
    //#presumption(String replace(String, Pattern, String)): java.util.regex.Pattern:matcher(...)@984 != null
    //#post(String replace(String, Pattern, String)): init'ed(return_value)
        return m.replaceAll(replacement);
    //#Utilities.java:985: end of method: String org.apache.roller.weblogger.util.Utilities.replace(String, Pattern, String)
    }
    
}
    //#Utilities.java:: end of class: org.apache.roller.weblogger.util.Utilities
