//# 1 errors, 622 messages
//#
/*
    //#Blacklist.java:1:1: class: org.apache.roller.weblogger.util.Blacklist
* Licensed to the Apache Software Foundation (ASF) under one or more
*  contributor license agreements.  The ASF licenses this file to You
* under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.  For additional information regarding
* copyright in this work, please see the NOTICE file in the top level
* directory of this distribution.
*/
/* Created on Nov 11, 2003 */
package org.apache.roller.weblogger.util;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.File;
import java.io.FileOutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.StringTokenizer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import org.apache.roller.weblogger.config.WebloggerConfig;
import org.apache.commons.lang.StringUtils;
import org.apache.roller.util.DateUtil;

/**
 * Loads MT-Blacklist style blacklist from disk and allows callers to test
 * strings against the blacklist and (optionally) addition blacklists.
 * <br />
 * First looks for blacklist.txt in uploads directory, than in classpath 
 * as /blacklist.txt. Download from web feature disabed.
 * <br />
 * Blacklist is formatted one entry per line. 
 * Any line that begins with # is considered to be a comment. 
 * Any line that begins with ( is considered to be a regex expression. 
 * <br />
 * For more information on the (discontinued) MT-Blacklist service:
 * http://www.jayallen.org/projects/mt-blacklist. 
 *
 * @author Lance Lavandowska
 * @author Allen Gilliland
 */
public class Blacklist {
    
    private static Log mLogger = LogFactory.getLog(Blacklist.class);
    //#Blacklist.java:66: method: org.apache.roller.weblogger.util.Blacklist.org.apache.roller.weblogger.util.Blacklist__static_init
    //#Blacklist.java:66: Warning: method not available
    //#    -- call on Log org.apache.commons.logging.LogFactory:getLog(Class)
    //#    severity: INFORMATIONAL
    //#    class: org.apache.roller.weblogger.util.Blacklist
    //#    method: org.apache.roller.weblogger.util.Blacklist__static_init
    //#    unanalyzed callee: Log org.apache.commons.logging.LogFactory:getLog(Class)
    //#input(org.apache.roller.weblogger.util.Blacklist__static_init): java.io.File.separator
    //#input(org.apache.roller.weblogger.util.Blacklist__static_init): java.io.File.separator._tainted
    //#output(org.apache.roller.weblogger.util.Blacklist__static_init): __Descendant_Table[org/apache/roller/weblogger/util/Blacklist]
    //#output(org.apache.roller.weblogger.util.Blacklist__static_init): __Dispatch_Table.downloadBlacklist()Z
    //#output(org.apache.roller.weblogger.util.Blacklist__static_init): __Dispatch_Table.isBlacklisted(Ljava/lang/String;)Z
    //#output(org.apache.roller.weblogger.util.Blacklist__static_init): __Dispatch_Table.isBlacklisted(Ljava/lang/String;Ljava/util/List;Ljava/util/List;)Z
    //#output(org.apache.roller.weblogger.util.Blacklist__static_init): __Dispatch_Table.loadBlacklistFromFile(Ljava/lang/String;)V
    //#output(org.apache.roller.weblogger.util.Blacklist__static_init): __Dispatch_Table.readComment(Ljava/lang/String;)V
    //#output(org.apache.roller.weblogger.util.Blacklist__static_init): __Dispatch_Table.readFromStream(Ljava/io/InputStream;Z)Ljava/lang/String;
    //#output(org.apache.roller.weblogger.util.Blacklist__static_init): __Dispatch_Table.readRule(Ljava/lang/String;)V
    //#output(org.apache.roller.weblogger.util.Blacklist__static_init): __Dispatch_Table.toString()Ljava/lang/String;
    //#output(org.apache.roller.weblogger.util.Blacklist__static_init): __Dispatch_Table.update()V
    //#output(org.apache.roller.weblogger.util.Blacklist__static_init): blacklist
    //#output(org.apache.roller.weblogger.util.Blacklist__static_init): blacklistURL
    //#output(org.apache.roller.weblogger.util.Blacklist__static_init): mLogger
    //#output(org.apache.roller.weblogger.util.Blacklist__static_init): new Blacklist(Blacklist__static_init#1) num objects
    //#output(org.apache.roller.weblogger.util.Blacklist__static_init): blacklist.__Tag
    //#output(org.apache.roller.weblogger.util.Blacklist__static_init): blacklist.blacklistRegex
    //#output(org.apache.roller.weblogger.util.Blacklist__static_init): blacklist.blacklistStr
    //#output(org.apache.roller.weblogger.util.Blacklist__static_init): blacklist.lastModified
    //#output(org.apache.roller.weblogger.util.Blacklist__static_init): new Date(loadBlacklistFromFile#3) num objects
    //#output(org.apache.roller.weblogger.util.Blacklist__static_init): new LinkedList(Blacklist#1) num objects
    //#output(org.apache.roller.weblogger.util.Blacklist__static_init): new LinkedList(Blacklist#2) num objects
    //#new obj(org.apache.roller.weblogger.util.Blacklist__static_init): new Blacklist(Blacklist__static_init#1)
    //#new obj(org.apache.roller.weblogger.util.Blacklist__static_init): new Date(loadBlacklistFromFile#3)
    //#new obj(org.apache.roller.weblogger.util.Blacklist__static_init): new LinkedList(Blacklist#1)
    //#new obj(org.apache.roller.weblogger.util.Blacklist__static_init): new LinkedList(Blacklist#2)
    //#presumption(org.apache.roller.weblogger.util.Blacklist__static_init): blacklist.blacklistRegex init'ed
    //#presumption(org.apache.roller.weblogger.util.Blacklist__static_init): blacklist.blacklistStr init'ed
    //#presumption(org.apache.roller.weblogger.util.Blacklist__static_init): org.apache.commons.logging.LogFactory:getLog(...)@66 != null
    //#post(org.apache.roller.weblogger.util.Blacklist__static_init): __Descendant_Table[org/apache/roller/weblogger/util/Blacklist] == &__Dispatch_Table
    //#post(org.apache.roller.weblogger.util.Blacklist__static_init): __Dispatch_Table.downloadBlacklist()Z == &downloadBlacklist
    //#post(org.apache.roller.weblogger.util.Blacklist__static_init): __Dispatch_Table.isBlacklisted(Ljava/lang/String;)Z == &isBlacklisted
    //#post(org.apache.roller.weblogger.util.Blacklist__static_init): __Dispatch_Table.isBlacklisted(Ljava/lang/String;Ljava/util/List;Ljava/util/List;)Z == &isBlacklisted
    //#post(org.apache.roller.weblogger.util.Blacklist__static_init): __Dispatch_Table.loadBlacklistFromFile(Ljava/lang/String;)V == &loadBlacklistFromFile
    //#post(org.apache.roller.weblogger.util.Blacklist__static_init): __Dispatch_Table.readComment(Ljava/lang/String;)V == &readComment
    //#post(org.apache.roller.weblogger.util.Blacklist__static_init): __Dispatch_Table.readFromStream(Ljava/io/InputStream;Z)Ljava/lang/String; == &readFromStream
    //#post(org.apache.roller.weblogger.util.Blacklist__static_init): __Dispatch_Table.readRule(Ljava/lang/String;)V == &readRule
    //#post(org.apache.roller.weblogger.util.Blacklist__static_init): __Dispatch_Table.toString()Ljava/lang/String; == &toString
    //#post(org.apache.roller.weblogger.util.Blacklist__static_init): __Dispatch_Table.update()V == &update
    //#post(org.apache.roller.weblogger.util.Blacklist__static_init): blacklist == &new Blacklist(Blacklist__static_init#1)
    //#post(org.apache.roller.weblogger.util.Blacklist__static_init): blacklistURL == null
    //#post(org.apache.roller.weblogger.util.Blacklist__static_init): (soft) mLogger != null
    //#post(org.apache.roller.weblogger.util.Blacklist__static_init): new Blacklist(Blacklist__static_init#1) num objects == 1
    //#post(org.apache.roller.weblogger.util.Blacklist__static_init): new LinkedList(Blacklist#1) num objects == 1
    //#post(org.apache.roller.weblogger.util.Blacklist__static_init): new LinkedList(Blacklist#2) num objects == 1
    //#post(org.apache.roller.weblogger.util.Blacklist__static_init): blacklist.__Tag == org/apache/roller/weblogger/util/Blacklist
    //#post(org.apache.roller.weblogger.util.Blacklist__static_init): blacklist.blacklistRegex == &new LinkedList(Blacklist#2)
    //#post(org.apache.roller.weblogger.util.Blacklist__static_init): blacklist.blacklistStr == &new LinkedList(Blacklist#1)
    //#post(org.apache.roller.weblogger.util.Blacklist__static_init): init'ed(blacklist.lastModified)
    //#post(org.apache.roller.weblogger.util.Blacklist__static_init): new Date(loadBlacklistFromFile#3) num objects <= 1
    //#unanalyzed(org.apache.roller.weblogger.util.Blacklist__static_init): Effects-of-calling:org.apache.commons.logging.Log:info
    //#unanalyzed(org.apache.roller.weblogger.util.Blacklist__static_init): Effects-of-calling:java.lang.StringBuilder
    //#unanalyzed(org.apache.roller.weblogger.util.Blacklist__static_init): Effects-of-calling:java.lang.StringBuilder:append
    //#unanalyzed(org.apache.roller.weblogger.util.Blacklist__static_init): Effects-of-calling:java.lang.StringBuilder:toString
    //#unanalyzed(org.apache.roller.weblogger.util.Blacklist__static_init): Effects-of-calling:org.apache.commons.logging.Log:debug
    //#unanalyzed(org.apache.roller.weblogger.util.Blacklist__static_init): Effects-of-calling:java.lang.Throwable:__curr_excep_obj
    //#unanalyzed(org.apache.roller.weblogger.util.Blacklist__static_init): Effects-of-calling:org.apache.commons.lang.StringUtils:isEmpty
    //#unanalyzed(org.apache.roller.weblogger.util.Blacklist__static_init): Effects-of-calling:java.util.List:size
    //#unanalyzed(org.apache.roller.weblogger.util.Blacklist__static_init): Effects-of-calling:java.lang.StringBuffer:append
    //#unanalyzed(org.apache.roller.weblogger.util.Blacklist__static_init): Effects-of-calling:java.lang.StringBuffer:toString
    //#unanalyzed(org.apache.roller.weblogger.util.Blacklist__static_init): Effects-of-calling:org.apache.roller.weblogger.config.WebloggerConfig:getProperty
    //#unanalyzed(org.apache.roller.weblogger.util.Blacklist__static_init): Effects-of-calling:java.io.File
    //#unanalyzed(org.apache.roller.weblogger.util.Blacklist__static_init): Effects-of-calling:java.util.Date:getTime
    //#unanalyzed(org.apache.roller.weblogger.util.Blacklist__static_init): Effects-of-calling:java.io.File:lastModified
    //#unanalyzed(org.apache.roller.weblogger.util.Blacklist__static_init): Effects-of-calling:java.util.Date
    //#unanalyzed(org.apache.roller.weblogger.util.Blacklist__static_init): Effects-of-calling:java.io.FileInputStream
    //#unanalyzed(org.apache.roller.weblogger.util.Blacklist__static_init): Effects-of-calling:java.lang.Object:getClass
    //#unanalyzed(org.apache.roller.weblogger.util.Blacklist__static_init): Effects-of-calling:java.lang.Class:getResourceAsStream
    //#unanalyzed(org.apache.roller.weblogger.util.Blacklist__static_init): Effects-of-calling:org.apache.commons.logging.Log:warn
    //#unanalyzed(org.apache.roller.weblogger.util.Blacklist__static_init): Effects-of-calling:readFromStream
    //#unanalyzed(org.apache.roller.weblogger.util.Blacklist__static_init): Effects-of-calling:org.apache.commons.logging.Log:error
    //#unanalyzed(org.apache.roller.weblogger.util.Blacklist__static_init): Effects-of-calling:java.lang.String:trim
    //#unanalyzed(org.apache.roller.weblogger.util.Blacklist__static_init): Effects-of-calling:java.lang.String:indexOf
    //#unanalyzed(org.apache.roller.weblogger.util.Blacklist__static_init): Effects-of-calling:java.lang.String:substring
    //#unanalyzed(org.apache.roller.weblogger.util.Blacklist__static_init): Effects-of-calling:java.util.regex.Pattern:compile
    //#unanalyzed(org.apache.roller.weblogger.util.Blacklist__static_init): Effects-of-calling:java.util.List:add
    //#unanalyzed(org.apache.roller.weblogger.util.Blacklist__static_init): Effects-of-calling:org.apache.commons.lang.StringUtils:isNotEmpty
    //#unanalyzed(org.apache.roller.weblogger.util.Blacklist__static_init): Effects-of-calling:java.lang.String:length
    //#unanalyzed(org.apache.roller.weblogger.util.Blacklist__static_init): Effects-of-calling:java.text.SimpleDateFormat
    //#unanalyzed(org.apache.roller.weblogger.util.Blacklist__static_init): Effects-of-calling:org.apache.roller.util.DateUtil:parse
    //#unanalyzed(org.apache.roller.weblogger.util.Blacklist__static_init): Effects-of-calling:java.lang.StringBuffer
    //#unanalyzed(org.apache.roller.weblogger.util.Blacklist__static_init): Effects-of-calling:java.io.InputStreamReader
    //#unanalyzed(org.apache.roller.weblogger.util.Blacklist__static_init): Effects-of-calling:java.io.BufferedReader
    //#unanalyzed(org.apache.roller.weblogger.util.Blacklist__static_init): Effects-of-calling:java.io.BufferedReader:readLine
    //#unanalyzed(org.apache.roller.weblogger.util.Blacklist__static_init): Effects-of-calling:java.lang.String:startsWith
    //#unanalyzed(org.apache.roller.weblogger.util.Blacklist__static_init): Effects-of-calling:java.io.BufferedReader:close
    //#unanalyzed(org.apache.roller.weblogger.util.Blacklist__static_init): Effects-of-calling:java.util.LinkedList
    
    private static Blacklist blacklist;
    private static final String blacklistFile = "blacklist.txt";
    private static final String lastUpdateStr = "Last update:";

    /** We no longer have a blacklist update URL */
    private static final String blacklistURL = null; 

    private Date lastModified = null;
    private List blacklistStr = new LinkedList();
    private List blacklistRegex = new LinkedList();
    
    // setup our singleton at class loading time
    static {
        mLogger.info("Initializing MT Blacklist");
    //#Blacklist.java:81: Warning: method not available
    //#    -- call on void org.apache.commons.logging.Log:info(Object)
    //#    severity: INFORMATIONAL
    //#    class: org.apache.roller.weblogger.util.Blacklist
    //#    method: org.apache.roller.weblogger.util.Blacklist__static_init
    //#    unanalyzed callee: void org.apache.commons.logging.Log:info(Object)
        blacklist = new Blacklist();
        blacklist.loadBlacklistFromFile(null);
    }
    //#Blacklist.java:84: end of method: org.apache.roller.weblogger.util.Blacklist.org.apache.roller.weblogger.util.Blacklist__static_init
    
    /** Hide constructor */
    private Blacklist() {
    //#Blacklist.java:87: method: void org.apache.roller.weblogger.util.Blacklist.org.apache.roller.weblogger.util.Blacklist()
    //#input(void org.apache.roller.weblogger.util.Blacklist()): this
    //#output(void org.apache.roller.weblogger.util.Blacklist()): new LinkedList(Blacklist#1) num objects
    //#output(void org.apache.roller.weblogger.util.Blacklist()): new LinkedList(Blacklist#2) num objects
    //#output(void org.apache.roller.weblogger.util.Blacklist()): this.blacklistRegex
    //#output(void org.apache.roller.weblogger.util.Blacklist()): this.blacklistStr
    //#output(void org.apache.roller.weblogger.util.Blacklist()): this.lastModified
    //#new obj(void org.apache.roller.weblogger.util.Blacklist()): new LinkedList(Blacklist#1)
    //#new obj(void org.apache.roller.weblogger.util.Blacklist()): new LinkedList(Blacklist#2)
    //#post(void org.apache.roller.weblogger.util.Blacklist()): this.blacklistRegex == &new LinkedList(Blacklist#2)
    //#post(void org.apache.roller.weblogger.util.Blacklist()): this.blacklistStr == &new LinkedList(Blacklist#1)
    //#post(void org.apache.roller.weblogger.util.Blacklist()): this.lastModified == null
    //#post(void org.apache.roller.weblogger.util.Blacklist()): new LinkedList(Blacklist#1) num objects == 1
    //#post(void org.apache.roller.weblogger.util.Blacklist()): new LinkedList(Blacklist#2) num objects == 1
    }
    //#Blacklist.java:88: end of method: void org.apache.roller.weblogger.util.Blacklist.org.apache.roller.weblogger.util.Blacklist()
      
    /** Singleton factory method. */
    public static Blacklist getBlacklist() {
        return blacklist;
    //#Blacklist.java:92: method: Blacklist org.apache.roller.weblogger.util.Blacklist.getBlacklist()
    //#input(Blacklist getBlacklist()): blacklist
    //#output(Blacklist getBlacklist()): return_value
    //#pre[1] (Blacklist getBlacklist()): init'ed(blacklist)
    //#post(Blacklist getBlacklist()): return_value == blacklist
    //#post(Blacklist getBlacklist()): init'ed(return_value)
    //#Blacklist.java:92: end of method: Blacklist org.apache.roller.weblogger.util.Blacklist.getBlacklist()
    }
    
    /** Updated MT blacklist if necessary. */
    public static void checkForUpdate() {
        getBlacklist().update();
    //#Blacklist.java:97: method: void org.apache.roller.weblogger.util.Blacklist.checkForUpdate()
    //#input(void checkForUpdate()): "&#10;"._tainted
    //#input(void checkForUpdate()): "HttpConnection response = "._tainted
    //#input(void checkForUpdate()): "Loading blacklist from "._tainted
    //#input(void checkForUpdate()): "MT last modified = "._tainted
    //#input(void checkForUpdate()): "Number of blacklist regex rules: "._tainted
    //#input(void checkForUpdate()): "Number of blacklist string rules: "._tainted
    //#input(void checkForUpdate()): "ParseException reading "._tainted
    //#input(void checkForUpdate()): "blacklist.txt"._tainted
    //#input(void checkForUpdate()): "my last modified = "._tainted
    //#input(void checkForUpdate()): "writing updated MT blacklist to "._tainted
    //#input(void checkForUpdate()): __Descendant_Table[org/apache/roller/weblogger/util/Blacklist]
    //#input(void checkForUpdate()): __Descendant_Table[others]
    //#input(void checkForUpdate()): __Dispatch_Table.loadBlacklistFromFile(Ljava/lang/String;)V
    //#input(void checkForUpdate()): __Dispatch_Table.update()V
    //#input(void checkForUpdate()): blacklist
    //#input(void checkForUpdate()): blacklist.__Tag
    //#input(void checkForUpdate()): blacklistURL
    //#input(void checkForUpdate()): java.io.File.separator
    //#input(void checkForUpdate()): java.io.File.separator._tainted
    //#output(void checkForUpdate()): blacklist.lastModified
    //#output(void checkForUpdate()): new Date(loadBlacklistFromFile#3) num objects
    //#new obj(void checkForUpdate()): new Date(loadBlacklistFromFile#3)
    //#pre[1] (void checkForUpdate()): blacklist != null
    //#pre[2] (void checkForUpdate()): blacklist.__Tag == org/apache/roller/weblogger/util/Blacklist
    //#post(void checkForUpdate()): possibly_updated(blacklist.lastModified)
    //#post(void checkForUpdate()): new Date(loadBlacklistFromFile#3) num objects == 0
    //#unanalyzed(void checkForUpdate()): Effects-of-calling:org.apache.commons.logging.Log:info
    //#unanalyzed(void checkForUpdate()): Effects-of-calling:java.lang.StringBuilder
    //#unanalyzed(void checkForUpdate()): Effects-of-calling:java.lang.StringBuilder:append
    //#unanalyzed(void checkForUpdate()): Effects-of-calling:java.lang.StringBuilder:toString
    //#unanalyzed(void checkForUpdate()): Effects-of-calling:org.apache.commons.logging.Log:debug
    //#unanalyzed(void checkForUpdate()): Effects-of-calling:java.lang.Throwable:__curr_excep_obj
    //#unanalyzed(void checkForUpdate()): Effects-of-calling:org.apache.commons.lang.StringUtils:isEmpty
    //#unanalyzed(void checkForUpdate()): Effects-of-calling:java.util.List:size
    //#unanalyzed(void checkForUpdate()): Effects-of-calling:java.lang.StringBuffer:append
    //#unanalyzed(void checkForUpdate()): Effects-of-calling:java.lang.StringBuffer:toString
    //#unanalyzed(void checkForUpdate()): Effects-of-calling:org.apache.roller.weblogger.config.WebloggerConfig:getProperty
    //#unanalyzed(void checkForUpdate()): Effects-of-calling:java.io.File
    //#unanalyzed(void checkForUpdate()): Effects-of-calling:java.util.Date:getTime
    //#unanalyzed(void checkForUpdate()): Effects-of-calling:java.io.File:lastModified
    //#unanalyzed(void checkForUpdate()): Effects-of-calling:java.util.Date
    //#unanalyzed(void checkForUpdate()): Effects-of-calling:java.io.FileInputStream
    //#unanalyzed(void checkForUpdate()): Effects-of-calling:java.lang.Object:getClass
    //#unanalyzed(void checkForUpdate()): Effects-of-calling:java.lang.Class:getResourceAsStream
    //#unanalyzed(void checkForUpdate()): Effects-of-calling:org.apache.commons.logging.Log:warn
    //#unanalyzed(void checkForUpdate()): Effects-of-calling:readFromStream
    //#unanalyzed(void checkForUpdate()): Effects-of-calling:org.apache.commons.logging.Log:error
    //#unanalyzed(void checkForUpdate()): Effects-of-calling:java.net.URL
    //#unanalyzed(void checkForUpdate()): Effects-of-calling:java.net.URL:openConnection
    //#unanalyzed(void checkForUpdate()): Effects-of-calling:java.net.HttpURLConnection:setRequestProperty
    //#unanalyzed(void checkForUpdate()): Effects-of-calling:org.apache.roller.util.DateUtil:formatRfc822
    //#unanalyzed(void checkForUpdate()): Effects-of-calling:java.net.HttpURLConnection:getResponseCode
    //#unanalyzed(void checkForUpdate()): Effects-of-calling:java.net.HttpURLConnection:getHeaderFieldDate
    //#unanalyzed(void checkForUpdate()): Effects-of-calling:java.net.HttpURLConnection:getInputStream
    //#unanalyzed(void checkForUpdate()): Effects-of-calling:java.io.FileOutputStream
    //#unanalyzed(void checkForUpdate()): Effects-of-calling:java.io.InputStream:read
    //#unanalyzed(void checkForUpdate()): Effects-of-calling:java.io.FileOutputStream:write
    //#unanalyzed(void checkForUpdate()): Effects-of-calling:java.io.FileOutputStream:close
    //#unanalyzed(void checkForUpdate()): Effects-of-calling:java.io.InputStream:close
    //#unanalyzed(void checkForUpdate()): Effects-of-calling:java.lang.String:trim
    //#unanalyzed(void checkForUpdate()): Effects-of-calling:java.lang.String:indexOf
    //#unanalyzed(void checkForUpdate()): Effects-of-calling:java.lang.String:substring
    //#unanalyzed(void checkForUpdate()): Effects-of-calling:java.util.regex.Pattern:compile
    //#unanalyzed(void checkForUpdate()): Effects-of-calling:java.util.List:add
    //#unanalyzed(void checkForUpdate()): Effects-of-calling:org.apache.commons.lang.StringUtils:isNotEmpty
    //#unanalyzed(void checkForUpdate()): Effects-of-calling:java.lang.String:length
    //#unanalyzed(void checkForUpdate()): Effects-of-calling:java.text.SimpleDateFormat
    //#unanalyzed(void checkForUpdate()): Effects-of-calling:org.apache.roller.util.DateUtil:parse
    //#unanalyzed(void checkForUpdate()): Effects-of-calling:java.lang.StringBuffer
    //#unanalyzed(void checkForUpdate()): Effects-of-calling:java.io.InputStreamReader
    //#unanalyzed(void checkForUpdate()): Effects-of-calling:java.io.BufferedReader
    //#unanalyzed(void checkForUpdate()): Effects-of-calling:java.io.BufferedReader:readLine
    //#unanalyzed(void checkForUpdate()): Effects-of-calling:java.lang.String:startsWith
    //#unanalyzed(void checkForUpdate()): Effects-of-calling:java.io.BufferedReader:close
    }
    //#Blacklist.java:98: end of method: void org.apache.roller.weblogger.util.Blacklist.checkForUpdate()
    
    /** Non-Static update method. */
    public void update() {
        if (this.blacklistURL != null) {
    //#Blacklist.java:102: method: void org.apache.roller.weblogger.util.Blacklist.update()
    //#Blacklist.java:102: Warning: test always goes same way
    //#    test predetermined because blacklistURL == null
    //#    severity: LOW
    //#    class: org.apache.roller.weblogger.util.Blacklist
    //#    method: void update()
    //#    from bb: Entry_BB_1
    //#    live edge: Entry_BB_1-->bb_4
    //#    tested vn: 1
    //#    tested vn values: {1}
    //#input(void update()): "&#10;"._tainted
    //#input(void update()): "HttpConnection response = "._tainted
    //#input(void update()): "Loading blacklist from "._tainted
    //#input(void update()): "MT last modified = "._tainted
    //#input(void update()): "Number of blacklist regex rules: "._tainted
    //#input(void update()): "Number of blacklist string rules: "._tainted
    //#input(void update()): "ParseException reading "._tainted
    //#input(void update()): "blacklist.txt"._tainted
    //#input(void update()): "my last modified = "._tainted
    //#input(void update()): "writing updated MT blacklist to "._tainted
    //#input(void update()): __Descendant_Table[org/apache/roller/weblogger/util/Blacklist]
    //#input(void update()): __Descendant_Table[others]
    //#input(void update()): __Dispatch_Table.loadBlacklistFromFile(Ljava/lang/String;)V
    //#input(void update()): blacklistURL
    //#input(void update()): java.io.File.separator
    //#input(void update()): java.io.File.separator._tainted
    //#input(void update()): this
    //#input(void update()): this.__Tag
    //#output(void update()): new Date(loadBlacklistFromFile#3) num objects
    //#output(void update()): this.lastModified
    //#new obj(void update()): new Date(loadBlacklistFromFile#3)
    //#post(void update()): possibly_updated(this.lastModified)
    //#post(void update()): new Date(loadBlacklistFromFile#3) num objects == 0
    //#unanalyzed(void update()): Effects-of-calling:org.apache.commons.logging.Log:info
    //#unanalyzed(void update()): Effects-of-calling:java.lang.StringBuilder
    //#unanalyzed(void update()): Effects-of-calling:java.lang.StringBuilder:append
    //#unanalyzed(void update()): Effects-of-calling:java.lang.StringBuilder:toString
    //#unanalyzed(void update()): Effects-of-calling:org.apache.commons.logging.Log:debug
    //#unanalyzed(void update()): Effects-of-calling:java.lang.Throwable:__curr_excep_obj
    //#unanalyzed(void update()): Effects-of-calling:org.apache.commons.lang.StringUtils:isEmpty
    //#unanalyzed(void update()): Effects-of-calling:java.util.List:size
    //#unanalyzed(void update()): Effects-of-calling:java.lang.StringBuffer:append
    //#unanalyzed(void update()): Effects-of-calling:java.lang.StringBuffer:toString
    //#unanalyzed(void update()): Effects-of-calling:org.apache.roller.weblogger.config.WebloggerConfig:getProperty
    //#unanalyzed(void update()): Effects-of-calling:java.io.File
    //#unanalyzed(void update()): Effects-of-calling:java.util.Date:getTime
    //#unanalyzed(void update()): Effects-of-calling:java.io.File:lastModified
    //#unanalyzed(void update()): Effects-of-calling:java.util.Date
    //#unanalyzed(void update()): Effects-of-calling:java.io.FileInputStream
    //#unanalyzed(void update()): Effects-of-calling:java.lang.Object:getClass
    //#unanalyzed(void update()): Effects-of-calling:java.lang.Class:getResourceAsStream
    //#unanalyzed(void update()): Effects-of-calling:org.apache.commons.logging.Log:warn
    //#unanalyzed(void update()): Effects-of-calling:readFromStream
    //#unanalyzed(void update()): Effects-of-calling:org.apache.commons.logging.Log:error
    //#unanalyzed(void update()): Effects-of-calling:java.net.URL
    //#unanalyzed(void update()): Effects-of-calling:java.net.URL:openConnection
    //#unanalyzed(void update()): Effects-of-calling:java.net.HttpURLConnection:setRequestProperty
    //#unanalyzed(void update()): Effects-of-calling:org.apache.roller.util.DateUtil:formatRfc822
    //#unanalyzed(void update()): Effects-of-calling:java.net.HttpURLConnection:getResponseCode
    //#unanalyzed(void update()): Effects-of-calling:java.net.HttpURLConnection:getHeaderFieldDate
    //#unanalyzed(void update()): Effects-of-calling:java.net.HttpURLConnection:getInputStream
    //#unanalyzed(void update()): Effects-of-calling:java.io.FileOutputStream
    //#unanalyzed(void update()): Effects-of-calling:java.io.InputStream:read
    //#unanalyzed(void update()): Effects-of-calling:java.io.FileOutputStream:write
    //#unanalyzed(void update()): Effects-of-calling:java.io.FileOutputStream:close
    //#unanalyzed(void update()): Effects-of-calling:java.io.InputStream:close
    //#unanalyzed(void update()): Effects-of-calling:java.lang.String:trim
    //#unanalyzed(void update()): Effects-of-calling:java.lang.String:indexOf
    //#unanalyzed(void update()): Effects-of-calling:java.lang.String:substring
    //#unanalyzed(void update()): Effects-of-calling:java.util.regex.Pattern:compile
    //#unanalyzed(void update()): Effects-of-calling:java.util.List:add
    //#unanalyzed(void update()): Effects-of-calling:org.apache.commons.lang.StringUtils:isNotEmpty
    //#unanalyzed(void update()): Effects-of-calling:java.lang.String:length
    //#unanalyzed(void update()): Effects-of-calling:java.text.SimpleDateFormat
    //#unanalyzed(void update()): Effects-of-calling:org.apache.roller.util.DateUtil:parse
    //#unanalyzed(void update()): Effects-of-calling:java.lang.StringBuffer
    //#unanalyzed(void update()): Effects-of-calling:java.io.InputStreamReader
    //#unanalyzed(void update()): Effects-of-calling:java.io.BufferedReader
    //#unanalyzed(void update()): Effects-of-calling:java.io.BufferedReader:readLine
    //#unanalyzed(void update()): Effects-of-calling:java.lang.String:startsWith
    //#unanalyzed(void update()): Effects-of-calling:java.io.BufferedReader:close
            boolean blacklist_updated = this.downloadBlacklist();
    //#Blacklist.java:103: Warning: dead code
    //#    dead code here because blacklistURL == null
    //#    severity: LOW
    //#    class: org.apache.roller.weblogger.util.Blacklist
    //#    method: void update()
    //#    dead bb: bb_2
            if (blacklist_updated) {
                this.loadBlacklistFromFile(null);
    //#Blacklist.java:105: Warning: dead code continues
    //#    dead code continues
    //#    severity: INFORMATIONAL
    //#    class: org.apache.roller.weblogger.util.Blacklist
    //#    method: void update()
    //#    dead bb: bb_3
            }
        }
    }
    //#Blacklist.java:108: end of method: void org.apache.roller.weblogger.util.Blacklist.update()
        
    /** Download the MT blacklist from the web to our uploads directory. */
    private boolean downloadBlacklist() {
        
        boolean blacklist_updated = false;
    //#Blacklist.java:113: method: bool org.apache.roller.weblogger.util.Blacklist.downloadBlacklist()
    //#input(bool downloadBlacklist()): "HttpConnection response = "._tainted
    //#input(bool downloadBlacklist()): "MT last modified = "._tainted
    //#input(bool downloadBlacklist()): "blacklist.txt"._tainted
    //#input(bool downloadBlacklist()): "my last modified = "._tainted
    //#input(bool downloadBlacklist()): "writing updated MT blacklist to "._tainted
    //#input(bool downloadBlacklist()): blacklistURL
    //#input(bool downloadBlacklist()): java.io.File.separator
    //#input(bool downloadBlacklist()): java.io.File.separator._tainted
    //#input(bool downloadBlacklist()): mLogger
    //#input(bool downloadBlacklist()): this
    //#input(bool downloadBlacklist()): this.lastModified
    //#output(bool downloadBlacklist()): return_value
    //#pre[1] (bool downloadBlacklist()): mLogger != null
    //#pre[3] (bool downloadBlacklist()): (soft) init'ed(this.lastModified)
    //#presumption(bool downloadBlacklist()): init'ed(java.io.File.separator)
    //#presumption(bool downloadBlacklist()): java.net.HttpURLConnection:getInputStream(...)@154 != null
    //#presumption(bool downloadBlacklist()): java.net.URL:openConnection(...)@118 != null
    //#post(bool downloadBlacklist()): init'ed(return_value)
    //#test_vector(bool downloadBlacklist()): this.lastModified: Addr_Set{null}, Inverse{null}
    //#test_vector(bool downloadBlacklist()): java.io.InputStream:read(...)@165: {-2_147_483_648..0}, {1..4_294_967_295}
    //#test_vector(bool downloadBlacklist()): java.net.HttpURLConnection:getResponseCode(...)@131: {-2_147_483_648..199, 201..303, 305..4_294_967_295}, {304}, {200}
        try {
            mLogger.debug("Attempting to download MT blacklist");
    //#Blacklist.java:115: Warning: method not available
    //#    -- call on void org.apache.commons.logging.Log:debug(Object)
    //#    severity: INFORMATIONAL
    //#    class: org.apache.roller.weblogger.util.Blacklist
    //#    method: bool downloadBlacklist()
    //#    unanalyzed callee: void org.apache.commons.logging.Log:debug(Object)
            
            URL url = new URL(blacklistURL);
            HttpURLConnection connection = 
                    (HttpURLConnection) url.openConnection();
            
            // after spending way too much time debugging i've discovered
            // that the blacklist server is selective based on the User-Agent
            // header.  without this header set i always get a 403 response :(
            connection.setRequestProperty("User-Agent", "Mozilla/5.0");
            
            if (this.lastModified != null) {
                connection.setRequestProperty("If-Modified-Since",
    //#Blacklist.java:127: Warning: method not available
    //#    -- call on String org.apache.roller.util.DateUtil:formatRfc822(Date)
    //#    severity: INFORMATIONAL
    //#    class: org.apache.roller.weblogger.util.Blacklist
    //#    method: bool downloadBlacklist()
    //#    unanalyzed callee: String org.apache.roller.util.DateUtil:formatRfc822(Date)
                        DateUtil.formatRfc822(this.lastModified));
            }
            
            int responseCode = connection.getResponseCode();
            
            mLogger.debug("HttpConnection response = "+responseCode);
    //#Blacklist.java:133: Warning: method not available
    //#    -- call on void org.apache.commons.logging.Log:debug(Object)
    //#    severity: INFORMATIONAL
    //#    class: org.apache.roller.weblogger.util.Blacklist
    //#    method: bool downloadBlacklist()
    //#    unanalyzed callee: void org.apache.commons.logging.Log:debug(Object)
            
            // did the connection return NotModified? If so, no need to parse
            if (responseCode == HttpURLConnection.HTTP_NOT_MODIFIED) {
                mLogger.debug("MT blacklist site says we are current");
    //#Blacklist.java:137: Warning: method not available
    //#    -- call on void org.apache.commons.logging.Log:debug(Object)
    //#    severity: INFORMATIONAL
    //#    class: org.apache.roller.weblogger.util.Blacklist
    //#    method: bool downloadBlacklist()
    //#    unanalyzed callee: void org.apache.commons.logging.Log:debug(Object)
                return false;
            }
            
            // did the connection return a LastModified header?
            long lastModifiedLong = 
                    connection.getHeaderFieldDate("Last-Modified", -1);
            
            // if the file is newer than our current then we need do update it
            if (responseCode == HttpURLConnection.HTTP_OK &&
                    (this.lastModified == null ||
                    this.lastModified.getTime() < lastModifiedLong)) {

                mLogger.debug("my last modified = "+this.lastModified.getTime());
    //#Blacklist.java:150: ?null dereference
    //#    this.lastModified != null
    //#    severity: MEDIUM
    //#    class: org.apache.roller.weblogger.util.Blacklist
    //#    method: bool downloadBlacklist()
    //#    basic block: bb_10
    //#    assertion: this.lastModified != null
    //#    VN: this.lastModified
    //#    Expected: Inverse{null} or Invalid
    //#    Bad: Addr_Set{null}
    //#    Attribs:  Ptr  null in Bad
    //#Blacklist.java:150: Warning: method not available
    //#    -- call on void org.apache.commons.logging.Log:debug(Object)
    //#    severity: INFORMATIONAL
    //#    class: org.apache.roller.weblogger.util.Blacklist
    //#    method: bool downloadBlacklist()
    //#    unanalyzed callee: void org.apache.commons.logging.Log:debug(Object)
                mLogger.debug("MT last modified = "+lastModifiedLong);
    //#Blacklist.java:151: Warning: method not available
    //#    -- call on void org.apache.commons.logging.Log:debug(Object)
    //#    severity: INFORMATIONAL
    //#    class: org.apache.roller.weblogger.util.Blacklist
    //#    method: bool downloadBlacklist()
    //#    unanalyzed callee: void org.apache.commons.logging.Log:debug(Object)
                
                // save the new blacklist
                InputStream instream = connection.getInputStream();
                
                String uploadDir = WebloggerConfig.getProperty("uploads.dir");
    //#Blacklist.java:156: Warning: method not available
    //#    -- call on String org.apache.roller.weblogger.config.WebloggerConfig:getProperty(String)
    //#    severity: INFORMATIONAL
    //#    class: org.apache.roller.weblogger.util.Blacklist
    //#    method: bool downloadBlacklist()
    //#    unanalyzed callee: String org.apache.roller.weblogger.config.WebloggerConfig:getProperty(String)
                String path = uploadDir + File.separator + blacklistFile;
                FileOutputStream outstream = new FileOutputStream(path);
                
                mLogger.debug("writing updated MT blacklist to "+path);
    //#Blacklist.java:160: Warning: method not available
    //#    -- call on void org.apache.commons.logging.Log:debug(Object)
    //#    severity: INFORMATIONAL
    //#    class: org.apache.roller.weblogger.util.Blacklist
    //#    method: bool downloadBlacklist()
    //#    unanalyzed callee: void org.apache.commons.logging.Log:debug(Object)
                
                // read from url and write to file
                byte[] buf = new byte[4096];
                int length = 0;
    //#Blacklist.java:164: Warning: unused assignment
    //#    unused assignment into length
    //#    severity: SUPPRESSED
    //#    class: org.apache.roller.weblogger.util.Blacklist
    //#    method: bool downloadBlacklist()
    //#    Attribs:  Uncertain
                while((length = instream.read(buf)) > 0)
                    outstream.write(buf, 0, length);
                
                outstream.close();
                instream.close();
                
                blacklist_updated = true;
                
                mLogger.debug("MT blacklist download completed.");
    //#Blacklist.java:173: Warning: method not available
    //#    -- call on void org.apache.commons.logging.Log:debug(Object)
    //#    severity: INFORMATIONAL
    //#    class: org.apache.roller.weblogger.util.Blacklist
    //#    method: bool downloadBlacklist()
    //#    unanalyzed callee: void org.apache.commons.logging.Log:debug(Object)
                
            } else {
                mLogger.debug("blacklist *NOT* saved, assuming we are current");
    //#Blacklist.java:176: Warning: method not available
    //#    -- call on void org.apache.commons.logging.Log:debug(Object)
    //#    severity: INFORMATIONAL
    //#    class: org.apache.roller.weblogger.util.Blacklist
    //#    method: bool downloadBlacklist()
    //#    unanalyzed callee: void org.apache.commons.logging.Log:debug(Object)
            }
            
        } catch (Exception e) {
            mLogger.error("error downloading blacklist", e);
    //#Blacklist.java:180: Warning: method not available
    //#    -- call on void org.apache.commons.logging.Log:error(Object, Throwable)
    //#    severity: INFORMATIONAL
    //#    class: org.apache.roller.weblogger.util.Blacklist
    //#    method: bool downloadBlacklist()
    //#    unanalyzed callee: void org.apache.commons.logging.Log:error(Object, Throwable)
        }
        
        return blacklist_updated;
    //#Blacklist.java:183: end of method: bool org.apache.roller.weblogger.util.Blacklist.downloadBlacklist()
    }
        
    /**
     * Load the MT blacklist from the file system.
     * We look for a previously downloaded version of the blacklist first and
     * if it's not found then we load the default blacklist packed with Roller.
     * Only public for purposes of unit testing.
     */
    public void loadBlacklistFromFile(String blacklistFilePath) {
        
        InputStream txtStream = null;
    //#Blacklist.java:194: method: void org.apache.roller.weblogger.util.Blacklist.loadBlacklistFromFile(String)
    //#Blacklist.java:194: Warning: unused assignment
    //#    unused assignment into txtStream
    //#    severity: SUPPRESSED
    //#    class: org.apache.roller.weblogger.util.Blacklist
    //#    method: void loadBlacklistFromFile(String)
    //#    Attribs:  Uncertain
    //#input(void loadBlacklistFromFile(String)): "&#10;"._tainted
    //#input(void loadBlacklistFromFile(String)): "Loading blacklist from "._tainted
    //#input(void loadBlacklistFromFile(String)): "Number of blacklist regex rules: "._tainted
    //#input(void loadBlacklistFromFile(String)): "Number of blacklist string rules: "._tainted
    //#input(void loadBlacklistFromFile(String)): "ParseException reading "._tainted
    //#input(void loadBlacklistFromFile(String)): "blacklist.txt"._tainted
    //#input(void loadBlacklistFromFile(String)): blacklistFilePath
    //#input(void loadBlacklistFromFile(String)): blacklistFilePath._tainted
    //#input(void loadBlacklistFromFile(String)): java.io.File.separator
    //#input(void loadBlacklistFromFile(String)): java.io.File.separator._tainted
    //#input(void loadBlacklistFromFile(String)): mLogger
    //#input(void loadBlacklistFromFile(String)): this
    //#input(void loadBlacklistFromFile(String)): this.blacklistRegex
    //#input(void loadBlacklistFromFile(String)): this.blacklistStr
    //#input(void loadBlacklistFromFile(String)): this.lastModified
    //#output(void loadBlacklistFromFile(String)): new Date(loadBlacklistFromFile#3) num objects
    //#output(void loadBlacklistFromFile(String)): this.lastModified
    //#new obj(void loadBlacklistFromFile(String)): new Date(loadBlacklistFromFile#3)
    //#pre[3] (void loadBlacklistFromFile(String)): mLogger != null
    //#pre[4] (void loadBlacklistFromFile(String)): (soft) init'ed(this.lastModified)
    //#pre[6] (void loadBlacklistFromFile(String)): (soft) this.blacklistRegex != null
    //#pre[7] (void loadBlacklistFromFile(String)): (soft) this.blacklistStr != null
    //#presumption(void loadBlacklistFromFile(String)): init'ed(java.io.File.separator)
    //#presumption(void loadBlacklistFromFile(String)): java.lang.Object:getClass(...)@216 != null
    //#post(void loadBlacklistFromFile(String)): (soft) init'ed(this.lastModified)
    //#post(void loadBlacklistFromFile(String)): new Date(loadBlacklistFromFile#3) num objects <= 1
    //#unanalyzed(void loadBlacklistFromFile(String)): Effects-of-calling:java.lang.StringBuilder
    //#unanalyzed(void loadBlacklistFromFile(String)): Effects-of-calling:java.lang.StringBuilder:append
    //#unanalyzed(void loadBlacklistFromFile(String)): Effects-of-calling:java.lang.StringBuilder:toString
    //#unanalyzed(void loadBlacklistFromFile(String)): Effects-of-calling:org.apache.commons.logging.Log:debug
    //#unanalyzed(void loadBlacklistFromFile(String)): Effects-of-calling:java.lang.Throwable:__curr_excep_obj
    //#unanalyzed(void loadBlacklistFromFile(String)): Effects-of-calling:org.apache.commons.lang.StringUtils:isEmpty
    //#unanalyzed(void loadBlacklistFromFile(String)): Effects-of-calling:java.lang.StringBuffer:append
    //#unanalyzed(void loadBlacklistFromFile(String)): Effects-of-calling:java.lang.StringBuffer:toString
    //#unanalyzed(void loadBlacklistFromFile(String)): Effects-of-calling:org.apache.commons.logging.Log:error
    //#unanalyzed(void loadBlacklistFromFile(String)): Effects-of-calling:java.lang.String:trim
    //#unanalyzed(void loadBlacklistFromFile(String)): Effects-of-calling:java.lang.String:indexOf
    //#unanalyzed(void loadBlacklistFromFile(String)): Effects-of-calling:java.lang.String:substring
    //#unanalyzed(void loadBlacklistFromFile(String)): Effects-of-calling:java.util.regex.Pattern:compile
    //#unanalyzed(void loadBlacklistFromFile(String)): Effects-of-calling:java.util.List:add
    //#unanalyzed(void loadBlacklistFromFile(String)): Effects-of-calling:org.apache.commons.lang.StringUtils:isNotEmpty
    //#unanalyzed(void loadBlacklistFromFile(String)): Effects-of-calling:java.lang.String:length
    //#unanalyzed(void loadBlacklistFromFile(String)): Effects-of-calling:java.text.SimpleDateFormat
    //#unanalyzed(void loadBlacklistFromFile(String)): Effects-of-calling:org.apache.roller.util.DateUtil:parse
    //#unanalyzed(void loadBlacklistFromFile(String)): Effects-of-calling:java.lang.StringBuffer
    //#unanalyzed(void loadBlacklistFromFile(String)): Effects-of-calling:java.io.InputStreamReader
    //#unanalyzed(void loadBlacklistFromFile(String)): Effects-of-calling:java.io.BufferedReader
    //#unanalyzed(void loadBlacklistFromFile(String)): Effects-of-calling:java.io.BufferedReader:readLine
    //#unanalyzed(void loadBlacklistFromFile(String)): Effects-of-calling:java.lang.String:startsWith
    //#unanalyzed(void loadBlacklistFromFile(String)): Effects-of-calling:java.io.BufferedReader:close
    //#test_vector(void loadBlacklistFromFile(String)): blacklistFilePath: Inverse{null}, Addr_Set{null}
    //#test_vector(void loadBlacklistFromFile(String)): this.lastModified: Addr_Set{null}, Inverse{null}
        try {
            String path = blacklistFilePath;
            if (path == null) {
                String uploadDir = WebloggerConfig.getProperty("uploads.dir");
    //#Blacklist.java:198: Warning: method not available
    //#    -- call on String org.apache.roller.weblogger.config.WebloggerConfig:getProperty(String)
    //#    severity: INFORMATIONAL
    //#    class: org.apache.roller.weblogger.util.Blacklist
    //#    method: void loadBlacklistFromFile(String)
    //#    unanalyzed callee: String org.apache.roller.weblogger.config.WebloggerConfig:getProperty(String)
                path = uploadDir + File.separator + blacklistFile;
            }
            File blacklistFile = new File(path);
            
            // check our lastModified date to see if we need to re-read the file
            if (this.lastModified != null &&
                    this.lastModified.getTime() >= blacklistFile.lastModified()) {               
                mLogger.debug("Blacklist is current, no need to load again");
    //#Blacklist.java:206: Warning: method not available
    //#    -- call on void org.apache.commons.logging.Log:debug(Object)
    //#    severity: INFORMATIONAL
    //#    class: org.apache.roller.weblogger.util.Blacklist
    //#    method: void loadBlacklistFromFile(String)
    //#    unanalyzed callee: void org.apache.commons.logging.Log:debug(Object)
                return;
            } else {
                this.lastModified = new Date(blacklistFile.lastModified());
            }           
            txtStream = new FileInputStream(blacklistFile);           
            mLogger.info("Loading blacklist from "+path);
    //#Blacklist.java:212: Warning: method not available
    //#    -- call on void org.apache.commons.logging.Log:info(Object)
    //#    severity: INFORMATIONAL
    //#    class: org.apache.roller.weblogger.util.Blacklist
    //#    method: void loadBlacklistFromFile(String)
    //#    unanalyzed callee: void org.apache.commons.logging.Log:info(Object)
            
        } catch (Exception e) {
            // Roller keeps a copy in the webapp just in case
            txtStream = getClass().getResourceAsStream("/blacklist.txt");           
            mLogger.warn(
    //#Blacklist.java:217: Warning: method not available
    //#    -- call on void org.apache.commons.logging.Log:warn(Object)
    //#    severity: INFORMATIONAL
    //#    class: org.apache.roller.weblogger.util.Blacklist
    //#    method: void loadBlacklistFromFile(String)
    //#    unanalyzed callee: void org.apache.commons.logging.Log:warn(Object)
                "Couldn't find downloaded blacklist, loaded blacklist.txt from classpath instead");
        }
        
        if (txtStream != null) {
            readFromStream(txtStream, false);
        } else {
            mLogger.error("Couldn't load a blacklist file from anywhere, "
    //#Blacklist.java:224: Warning: method not available
    //#    -- call on void org.apache.commons.logging.Log:error(Object)
    //#    severity: INFORMATIONAL
    //#    class: org.apache.roller.weblogger.util.Blacklist
    //#    method: void loadBlacklistFromFile(String)
    //#    unanalyzed callee: void org.apache.commons.logging.Log:error(Object)
                        + "this means blacklist checking is disabled for now.");
        }
        mLogger.info("Number of blacklist string rules: "+blacklistStr.size());
    //#Blacklist.java:227: Warning: method not available
    //#    -- call on void org.apache.commons.logging.Log:info(Object)
    //#    severity: INFORMATIONAL
    //#    class: org.apache.roller.weblogger.util.Blacklist
    //#    method: void loadBlacklistFromFile(String)
    //#    unanalyzed callee: void org.apache.commons.logging.Log:info(Object)
        mLogger.info("Number of blacklist regex rules: "+blacklistRegex.size());
    //#Blacklist.java:228: Warning: method not available
    //#    -- call on void org.apache.commons.logging.Log:info(Object)
    //#    severity: INFORMATIONAL
    //#    class: org.apache.roller.weblogger.util.Blacklist
    //#    method: void loadBlacklistFromFile(String)
    //#    unanalyzed callee: void org.apache.commons.logging.Log:info(Object)
    }
    //#Blacklist.java:229: end of method: void org.apache.roller.weblogger.util.Blacklist.loadBlacklistFromFile(String)
       
    /**
     * Read in the InputStream for rules.
     * @param txtStream
     */
    private String readFromStream(InputStream txtStream, boolean saveStream) {
        String line;
        StringBuffer buf = new StringBuffer();
    //#Blacklist.java:237: method: String org.apache.roller.weblogger.util.Blacklist.readFromStream(InputStream, bool)
    //#input(String readFromStream(InputStream, bool)): "&#10;"._tainted
    //#input(String readFromStream(InputStream, bool)): "ParseException reading "._tainted
    //#input(String readFromStream(InputStream, bool)): mLogger
    //#input(String readFromStream(InputStream, bool)): saveStream
    //#input(String readFromStream(InputStream, bool)): this
    //#input(String readFromStream(InputStream, bool)): this.blacklistRegex
    //#input(String readFromStream(InputStream, bool)): this.blacklistStr
    //#input(String readFromStream(InputStream, bool)): txtStream
    //#output(String readFromStream(InputStream, bool)): java.lang.StringBuffer:toString(...)._tainted
    //#output(String readFromStream(InputStream, bool)): return_value
    //#output(String readFromStream(InputStream, bool)): this.lastModified
    //#new obj(String readFromStream(InputStream, bool)): java.lang.StringBuffer:toString(...)
    //#pre[1] (String readFromStream(InputStream, bool)): (soft) mLogger != null
    //#pre[5] (String readFromStream(InputStream, bool)): (soft) this.blacklistRegex != null
    //#pre[6] (String readFromStream(InputStream, bool)): (soft) this.blacklistStr != null
    //#post(String readFromStream(InputStream, bool)): init'ed(java.lang.StringBuffer:toString(...)._tainted)
    //#post(String readFromStream(InputStream, bool)): return_value == &java.lang.StringBuffer:toString(...)
    //#post(String readFromStream(InputStream, bool)): possibly_updated(this.lastModified)
    //#unanalyzed(String readFromStream(InputStream, bool)): Effects-of-calling:java.lang.StringBuilder
    //#unanalyzed(String readFromStream(InputStream, bool)): Effects-of-calling:java.lang.StringBuilder:append
    //#unanalyzed(String readFromStream(InputStream, bool)): Effects-of-calling:java.lang.StringBuilder:toString
    //#unanalyzed(String readFromStream(InputStream, bool)): Effects-of-calling:org.apache.commons.logging.Log:debug
    //#unanalyzed(String readFromStream(InputStream, bool)): Effects-of-calling:java.lang.Throwable:__curr_excep_obj
    //#unanalyzed(String readFromStream(InputStream, bool)): Effects-of-calling:org.apache.commons.lang.StringUtils:isEmpty
    //#unanalyzed(String readFromStream(InputStream, bool)): Effects-of-calling:java.lang.String:trim
    //#unanalyzed(String readFromStream(InputStream, bool)): Effects-of-calling:java.lang.String:indexOf
    //#unanalyzed(String readFromStream(InputStream, bool)): Effects-of-calling:java.lang.String:substring
    //#unanalyzed(String readFromStream(InputStream, bool)): Effects-of-calling:java.util.regex.Pattern:compile
    //#unanalyzed(String readFromStream(InputStream, bool)): Effects-of-calling:java.util.List:add
    //#unanalyzed(String readFromStream(InputStream, bool)): Effects-of-calling:org.apache.commons.lang.StringUtils:isNotEmpty
    //#unanalyzed(String readFromStream(InputStream, bool)): Effects-of-calling:java.lang.String:length
    //#unanalyzed(String readFromStream(InputStream, bool)): Effects-of-calling:java.text.SimpleDateFormat
    //#unanalyzed(String readFromStream(InputStream, bool)): Effects-of-calling:org.apache.roller.util.DateUtil:parse
    //#test_vector(String readFromStream(InputStream, bool)): saveStream: {0}, {1}
    //#test_vector(String readFromStream(InputStream, bool)): java.lang.String:startsWith(...)@243: {0}, {1}
        BufferedReader in = null;
        try {
            in = new BufferedReader(
                    new InputStreamReader( txtStream, "UTF-8" ) );
            while ((line = in.readLine()) != null) {
                if (line.startsWith("#")) {
                    readComment(line);
                } else {
                    readRule(line);
                }
                
                if (saveStream) buf.append(line).append("\n");
            }
        } catch (Exception e) {
            mLogger.error(e);
    //#Blacklist.java:252: Warning: method not available
    //#    -- call on void org.apache.commons.logging.Log:error(Object)
    //#    severity: INFORMATIONAL
    //#    class: org.apache.roller.weblogger.util.Blacklist
    //#    method: String readFromStream(InputStream, bool)
    //#    unanalyzed callee: void org.apache.commons.logging.Log:error(Object)
        } finally {
            try {
                if (in != null) in.close();
            } catch (IOException e1) {
                mLogger.error(e1);
    //#Blacklist.java:257: Warning: method not available
    //#    -- call on void org.apache.commons.logging.Log:error(Object)
    //#    severity: INFORMATIONAL
    //#    class: org.apache.roller.weblogger.util.Blacklist
    //#    method: String readFromStream(InputStream, bool)
    //#    unanalyzed callee: void org.apache.commons.logging.Log:error(Object)
            }
        }
        return buf.toString();
    //#Blacklist.java:260: end of method: String org.apache.roller.weblogger.util.Blacklist.readFromStream(InputStream, bool)
    }
    
    private void readRule(String str) {
        if (StringUtils.isEmpty(str)) return; // bad condition
    //#Blacklist.java:264: method: void org.apache.roller.weblogger.util.Blacklist.readRule(String)
    //#Blacklist.java:264: Warning: method not available
    //#    -- call on bool org.apache.commons.lang.StringUtils:isEmpty(String)
    //#    severity: INFORMATIONAL
    //#    class: org.apache.roller.weblogger.util.Blacklist
    //#    method: void readRule(String)
    //#    unanalyzed callee: bool org.apache.commons.lang.StringUtils:isEmpty(String)
    //#input(void readRule(String)): str
    //#input(void readRule(String)): str._tainted
    //#input(void readRule(String)): this
    //#input(void readRule(String)): this.blacklistRegex
    //#input(void readRule(String)): this.blacklistStr
    //#pre[1] (void readRule(String)): (soft) str != null
    //#pre[4] (void readRule(String)): (soft) this.blacklistRegex != null
    //#pre[5] (void readRule(String)): (soft) this.blacklistStr != null
    //#presumption(void readRule(String)): java.lang.String:indexOf(...)@270 >= -2_147_483_647
    //#test_vector(void readRule(String)): java.lang.String:indexOf(...)@268: {-2_147_483_648..0}, {1..4_294_967_295}
    //#test_vector(void readRule(String)): java.lang.String:indexOf(...)@274: {-2_147_483_648..-1}, {0..4_294_967_295}
    //#test_vector(void readRule(String)): org.apache.commons.lang.StringUtils:isEmpty(...)@264: {0}, {1}
    //#test_vector(void readRule(String)): org.apache.commons.lang.StringUtils:isNotEmpty(...)@278: {0}, {1}
        
        String rule = str.trim();
        
        if (str.indexOf("#") > 0) // line has a comment
        {
            int commentLoc = str.indexOf("#");
            rule = str.substring(0, commentLoc-1).trim(); // strip comment
        }
        
        if (rule.indexOf( "(" ) > -1) // regex rule
        {
            // pre-compile patterns since they will be frequently used
            blacklistRegex.add(Pattern.compile(rule));
        } else if (StringUtils.isNotEmpty(rule)) {
    //#Blacklist.java:278: Warning: method not available
    //#    -- call on bool org.apache.commons.lang.StringUtils:isNotEmpty(String)
    //#    severity: INFORMATIONAL
    //#    class: org.apache.roller.weblogger.util.Blacklist
    //#    method: void readRule(String)
    //#    unanalyzed callee: bool org.apache.commons.lang.StringUtils:isNotEmpty(String)
            blacklistStr.add(rule);
        }
    }
    //#Blacklist.java:281: end of method: void org.apache.roller.weblogger.util.Blacklist.readRule(String)
        
    /** Read comment and try to parse out "Last update" value */
    private void readComment(String str) {
        int lastUpdatePos = str.indexOf(lastUpdateStr);
    //#Blacklist.java:285: method: void org.apache.roller.weblogger.util.Blacklist.readComment(String)
    //#input(void readComment(String)): "ParseException reading "._tainted
    //#input(void readComment(String)): mLogger
    //#input(void readComment(String)): str
    //#input(void readComment(String)): str._tainted
    //#input(void readComment(String)): this
    //#output(void readComment(String)): this.lastModified
    //#pre[3] (void readComment(String)): str != null
    //#pre[1] (void readComment(String)): (soft) mLogger != null
    //#presumption(void readComment(String)): java.lang.String:indexOf(...)@285 + java.lang.String:length(...)@287 in -2_147_483_648..4_294_967_295
    //#post(void readComment(String)): possibly_updated(this.lastModified)
    //#test_vector(void readComment(String)): java.lang.String:indexOf(...)@285: {-2_147_483_648..-1}, {0..4_294_967_295}
        if (lastUpdatePos > -1) {
            str = str.substring(lastUpdatePos + lastUpdateStr.length());
            str = str.trim();
            try {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
                lastModified = DateUtil.parse(str, sdf);
    //#Blacklist.java:291: Warning: method not available
    //#    -- call on Date org.apache.roller.util.DateUtil:parse(String, SimpleDateFormat)
    //#    severity: INFORMATIONAL
    //#    class: org.apache.roller.weblogger.util.Blacklist
    //#    method: void readComment(String)
    //#    unanalyzed callee: Date org.apache.roller.util.DateUtil:parse(String, SimpleDateFormat)
            } catch (ParseException e) {
                mLogger.debug("ParseException reading " + str);
    //#Blacklist.java:293: Warning: method not available
    //#    -- call on void org.apache.commons.logging.Log:debug(Object)
    //#    severity: INFORMATIONAL
    //#    class: org.apache.roller.weblogger.util.Blacklist
    //#    method: void readComment(String)
    //#    unanalyzed callee: void org.apache.commons.logging.Log:debug(Object)
            }
        }
    }
    //#Blacklist.java:296: end of method: void org.apache.roller.weblogger.util.Blacklist.readComment(String)
       
    /** 
     * Does the String argument match any of the rules in the built-in blacklist? 
     */
    public boolean isBlacklisted(String str) {
        return isBlacklisted(str, null, null);
    //#Blacklist.java:302: method: bool org.apache.roller.weblogger.util.Blacklist.isBlacklisted(String)
    //#input(bool isBlacklisted(String)): " matched by "._tainted
    //#input(bool isBlacklisted(String)): ")\b"._tainted
    //#input(bool isBlacklisted(String)): ":"._tainted
    //#input(bool isBlacklisted(String)): "\b("._tainted
    //#input(bool isBlacklisted(String)): "matched:"._tainted
    //#input(bool isBlacklisted(String)): __Descendant_Table[org/apache/roller/weblogger/util/Blacklist]
    //#input(bool isBlacklisted(String)): __Descendant_Table[others]
    //#input(bool isBlacklisted(String)): __Dispatch_Table.isBlacklisted(Ljava/lang/String;Ljava/util/List;Ljava/util/List;)Z
    //#input(bool isBlacklisted(String)): mLogger
    //#input(bool isBlacklisted(String)): str
    //#input(bool isBlacklisted(String)): this
    //#input(bool isBlacklisted(String)): this.__Tag
    //#input(bool isBlacklisted(String)): this.blacklistRegex
    //#input(bool isBlacklisted(String)): this.blacklistStr
    //#output(bool isBlacklisted(String)): return_value
    //#pre[4] (bool isBlacklisted(String)): this.__Tag == org/apache/roller/weblogger/util/Blacklist
    //#pre[1] (bool isBlacklisted(String)): (soft) mLogger != null
    //#pre[5] (bool isBlacklisted(String)): (soft) this.blacklistRegex != null
    //#pre[6] (bool isBlacklisted(String)): (soft) this.blacklistStr != null
    //#post(bool isBlacklisted(String)): init'ed(return_value)
    //#unanalyzed(bool isBlacklisted(String)): Effects-of-calling:java.util.List:iterator
    //#unanalyzed(bool isBlacklisted(String)): Effects-of-calling:java.util.Iterator:hasNext
    //#unanalyzed(bool isBlacklisted(String)): Effects-of-calling:java.util.Iterator:next
    //#unanalyzed(bool isBlacklisted(String)): Effects-of-calling:org.apache.commons.logging.Log:isDebugEnabled
    //#unanalyzed(bool isBlacklisted(String)): Effects-of-calling:java.util.regex.Pattern:matcher
    //#unanalyzed(bool isBlacklisted(String)): Effects-of-calling:java.util.regex.Matcher:find
    //#unanalyzed(bool isBlacklisted(String)): Effects-of-calling:java.lang.StringBuilder
    //#unanalyzed(bool isBlacklisted(String)): Effects-of-calling:java.util.regex.Matcher:group
    //#unanalyzed(bool isBlacklisted(String)): Effects-of-calling:java.lang.StringBuilder:append
    //#unanalyzed(bool isBlacklisted(String)): Effects-of-calling:java.util.regex.Pattern:pattern
    //#unanalyzed(bool isBlacklisted(String)): Effects-of-calling:java.lang.StringBuilder:toString
    //#unanalyzed(bool isBlacklisted(String)): Effects-of-calling:org.apache.commons.logging.Log:debug
    //#unanalyzed(bool isBlacklisted(String)): Effects-of-calling:java.util.regex.Pattern:compile
    //#unanalyzed(bool isBlacklisted(String)): Effects-of-calling:java.lang.Throwable:__curr_excep_obj
    //#unanalyzed(bool isBlacklisted(String)): Effects-of-calling:java.lang.String:contains
    //#unanalyzed(bool isBlacklisted(String)): Effects-of-calling:org.apache.commons.lang.StringUtils:isEmpty
    //#unanalyzed(bool isBlacklisted(String)): Effects-of-calling:java.util.List:size
    //#unanalyzed(bool isBlacklisted(String)): Effects-of-calling:java.util.ArrayList
    //#unanalyzed(bool isBlacklisted(String)): Effects-of-calling:java.util.List:addAll
    //#Blacklist.java:302: end of method: bool org.apache.roller.weblogger.util.Blacklist.isBlacklisted(String)
    }
    
    /** 
     * Does the String argument match any of the rules in the built-in blacklist
     * plus additional blacklists provided by caller?
     * @param str             String to be checked against blacklist
     * @param moreStringRules Additional string rules to consider
     * @param moreRegexRules  Additional regex rules to consider 
     */
    public boolean isBlacklisted(
         String str, List moreStringRules, List moreRegexRules) {
        if (str == null || StringUtils.isEmpty(str)) return false;
    //#Blacklist.java:314: method: bool org.apache.roller.weblogger.util.Blacklist.isBlacklisted(String, List, List)
    //#Blacklist.java:314: Warning: method not available
    //#    -- call on bool org.apache.commons.lang.StringUtils:isEmpty(String)
    //#    severity: INFORMATIONAL
    //#    class: org.apache.roller.weblogger.util.Blacklist
    //#    method: bool isBlacklisted(String, List, List)
    //#    unanalyzed callee: bool org.apache.commons.lang.StringUtils:isEmpty(String)
    //#input(bool isBlacklisted(String, List, List)): " matched by "._tainted
    //#input(bool isBlacklisted(String, List, List)): ")\b"._tainted
    //#input(bool isBlacklisted(String, List, List)): ":"._tainted
    //#input(bool isBlacklisted(String, List, List)): "\b("._tainted
    //#input(bool isBlacklisted(String, List, List)): "matched:"._tainted
    //#input(bool isBlacklisted(String, List, List)): mLogger
    //#input(bool isBlacklisted(String, List, List)): moreRegexRules
    //#input(bool isBlacklisted(String, List, List)): moreStringRules
    //#input(bool isBlacklisted(String, List, List)): str
    //#input(bool isBlacklisted(String, List, List)): this
    //#input(bool isBlacklisted(String, List, List)): this.blacklistRegex
    //#input(bool isBlacklisted(String, List, List)): this.blacklistStr
    //#output(bool isBlacklisted(String, List, List)): return_value
    //#pre[1] (bool isBlacklisted(String, List, List)): (soft) mLogger != null
    //#pre[6] (bool isBlacklisted(String, List, List)): (soft) this.blacklistRegex != null
    //#pre[7] (bool isBlacklisted(String, List, List)): (soft) this.blacklistStr != null
    //#post(bool isBlacklisted(String, List, List)): init'ed(return_value)
    //#unanalyzed(bool isBlacklisted(String, List, List)): Effects-of-calling:java.util.List:iterator
    //#unanalyzed(bool isBlacklisted(String, List, List)): Effects-of-calling:java.util.Iterator:hasNext
    //#unanalyzed(bool isBlacklisted(String, List, List)): Effects-of-calling:java.util.Iterator:next
    //#unanalyzed(bool isBlacklisted(String, List, List)): Effects-of-calling:org.apache.commons.logging.Log:isDebugEnabled
    //#unanalyzed(bool isBlacklisted(String, List, List)): Effects-of-calling:java.util.regex.Pattern:matcher
    //#unanalyzed(bool isBlacklisted(String, List, List)): Effects-of-calling:java.util.regex.Matcher:find
    //#unanalyzed(bool isBlacklisted(String, List, List)): Effects-of-calling:java.lang.StringBuilder
    //#unanalyzed(bool isBlacklisted(String, List, List)): Effects-of-calling:java.util.regex.Matcher:group
    //#unanalyzed(bool isBlacklisted(String, List, List)): Effects-of-calling:java.lang.StringBuilder:append
    //#unanalyzed(bool isBlacklisted(String, List, List)): Effects-of-calling:java.util.regex.Pattern:pattern
    //#unanalyzed(bool isBlacklisted(String, List, List)): Effects-of-calling:java.lang.StringBuilder:toString
    //#unanalyzed(bool isBlacklisted(String, List, List)): Effects-of-calling:org.apache.commons.logging.Log:debug
    //#unanalyzed(bool isBlacklisted(String, List, List)): Effects-of-calling:java.util.regex.Pattern:compile
    //#unanalyzed(bool isBlacklisted(String, List, List)): Effects-of-calling:java.lang.Throwable:__curr_excep_obj
    //#unanalyzed(bool isBlacklisted(String, List, List)): Effects-of-calling:java.lang.String:contains
    //#test_vector(bool isBlacklisted(String, List, List)): moreRegexRules: Addr_Set{null}, Inverse{null}
    //#test_vector(bool isBlacklisted(String, List, List)): moreStringRules: Addr_Set{null}, Inverse{null}
    //#test_vector(bool isBlacklisted(String, List, List)): str: Addr_Set{null}, Inverse{null}
    //#test_vector(bool isBlacklisted(String, List, List)): java.util.List:size(...)@322: {-2_147_483_648..0}, {1..4_294_967_295}
    //#test_vector(bool isBlacklisted(String, List, List)): java.util.List:size(...)@331: {-2_147_483_648..0}, {1..4_294_967_295}
    //#test_vector(bool isBlacklisted(String, List, List)): org.apache.commons.lang.StringUtils:isEmpty(...)@314: {0}, {1}

        // First iterate over blacklist, doing indexOf.
        // Then iterate over blacklistRegex and test.
        // As soon as there is a hit in either case return true
        
        // test plain String.indexOf
        List stringRules = blacklistStr;
        if (moreStringRules != null && moreStringRules.size() > 0) {
            stringRules = new ArrayList();
            stringRules.addAll(moreStringRules);
            stringRules.addAll(blacklistStr);
        }
        if (testStringRules(str, stringRules)) return true;
        
        // test regex blacklisted
        List regexRules = blacklistRegex;
        if (moreRegexRules != null && moreRegexRules.size() > 0) {
            regexRules = new ArrayList();
            regexRules.addAll(moreRegexRules);
            regexRules.addAll(blacklistRegex);
        }
        return testRegExRules(str, regexRules);
    //#Blacklist.java:336: end of method: bool org.apache.roller.weblogger.util.Blacklist.isBlacklisted(String, List, List)
    }      

    /** 
     * Test string only against rules provided by caller, NOT against built-in blacklist.
     * @param str             String to be checked against rules
     * @param moreStringRules String rules to consider
     * @param moreRegexRules  Regex rules to consider 
     */
    public static boolean matchesRulesOnly(
        String str, List stringRules, List regexRules) {
        if (testStringRules(str, stringRules)) return true;
    //#Blacklist.java:347: method: bool org.apache.roller.weblogger.util.Blacklist.matchesRulesOnly(String, List, List)
    //#input(bool matchesRulesOnly(String, List, List)): " matched by "._tainted
    //#input(bool matchesRulesOnly(String, List, List)): ")\b"._tainted
    //#input(bool matchesRulesOnly(String, List, List)): ":"._tainted
    //#input(bool matchesRulesOnly(String, List, List)): "\b("._tainted
    //#input(bool matchesRulesOnly(String, List, List)): "matched:"._tainted
    //#input(bool matchesRulesOnly(String, List, List)): mLogger
    //#input(bool matchesRulesOnly(String, List, List)): regexRules
    //#input(bool matchesRulesOnly(String, List, List)): str
    //#input(bool matchesRulesOnly(String, List, List)): stringRules
    //#output(bool matchesRulesOnly(String, List, List)): return_value
    //#pre[4] (bool matchesRulesOnly(String, List, List)): stringRules != null
    //#pre[1] (bool matchesRulesOnly(String, List, List)): (soft) mLogger != null
    //#pre[2] (bool matchesRulesOnly(String, List, List)): (soft) regexRules != null
    //#pre[3] (bool matchesRulesOnly(String, List, List)): (soft) str != null
    //#post(bool matchesRulesOnly(String, List, List)): init'ed(return_value)
    //#unanalyzed(bool matchesRulesOnly(String, List, List)): Effects-of-calling:java.util.List:iterator
    //#unanalyzed(bool matchesRulesOnly(String, List, List)): Effects-of-calling:java.util.Iterator:hasNext
    //#unanalyzed(bool matchesRulesOnly(String, List, List)): Effects-of-calling:java.util.Iterator:next
    //#unanalyzed(bool matchesRulesOnly(String, List, List)): Effects-of-calling:org.apache.commons.logging.Log:isDebugEnabled
    //#unanalyzed(bool matchesRulesOnly(String, List, List)): Effects-of-calling:java.util.regex.Pattern:matcher
    //#unanalyzed(bool matchesRulesOnly(String, List, List)): Effects-of-calling:java.util.regex.Matcher:find
    //#unanalyzed(bool matchesRulesOnly(String, List, List)): Effects-of-calling:java.lang.StringBuilder
    //#unanalyzed(bool matchesRulesOnly(String, List, List)): Effects-of-calling:java.util.regex.Matcher:group
    //#unanalyzed(bool matchesRulesOnly(String, List, List)): Effects-of-calling:java.lang.StringBuilder:append
    //#unanalyzed(bool matchesRulesOnly(String, List, List)): Effects-of-calling:java.util.regex.Pattern:pattern
    //#unanalyzed(bool matchesRulesOnly(String, List, List)): Effects-of-calling:java.lang.StringBuilder:toString
    //#unanalyzed(bool matchesRulesOnly(String, List, List)): Effects-of-calling:org.apache.commons.logging.Log:debug
    //#unanalyzed(bool matchesRulesOnly(String, List, List)): Effects-of-calling:java.util.regex.Pattern:compile
    //#unanalyzed(bool matchesRulesOnly(String, List, List)): Effects-of-calling:java.lang.Throwable:__curr_excep_obj
    //#unanalyzed(bool matchesRulesOnly(String, List, List)): Effects-of-calling:java.lang.String:contains
        return testRegExRules(str, regexRules);  
    //#Blacklist.java:348: end of method: bool org.apache.roller.weblogger.util.Blacklist.matchesRulesOnly(String, List, List)
    }
        
    /** Test String against the RegularExpression rules. */
    private static boolean testRegExRules(String str, List regexRules) {
        boolean hit = false;
    //#Blacklist.java:353: method: bool org.apache.roller.weblogger.util.Blacklist.testRegExRules(String, List)
    //#input(bool testRegExRules(String, List)): " matched by "._tainted
    //#input(bool testRegExRules(String, List)): mLogger
    //#input(bool testRegExRules(String, List)): regexRules
    //#input(bool testRegExRules(String, List)): str
    //#output(bool testRegExRules(String, List)): return_value
    //#pre[2] (bool testRegExRules(String, List)): regexRules != null
    //#pre[1] (bool testRegExRules(String, List)): (soft) mLogger != null
    //#presumption(bool testRegExRules(String, List)): java.util.Iterator:next(...)@357 != null
    //#presumption(bool testRegExRules(String, List)): java.util.regex.Pattern:matcher(...)@361 != null
    //#presumption(bool testRegExRules(String, List)): java.util.regex.Pattern:matcher(...)@368 != null
    //#post(bool testRegExRules(String, List)): init'ed(return_value)
    //#test_vector(bool testRegExRules(String, List)): java.util.Iterator:hasNext(...)@356: {0}, {1}
    //#test_vector(bool testRegExRules(String, List)): java.util.regex.Matcher:find(...)@362: {0}, {1}
    //#test_vector(bool testRegExRules(String, List)): java.util.regex.Matcher:find(...)@368: {0}, {1}
    //#test_vector(bool testRegExRules(String, List)): org.apache.commons.logging.Log:isDebugEnabled(...)@360: {0}, {1}
        Pattern testPattern = null;
    //#Blacklist.java:354: Warning: unused assignment
    //#    unused assignment into testPattern
    //#    severity: SUPPRESSED
    //#    class: org.apache.roller.weblogger.util.Blacklist
    //#    method: bool testRegExRules(String, List)
    //#    Attribs:  Uncertain
        Iterator iter = regexRules.iterator();
        while (iter.hasNext()) {
            testPattern = (Pattern)iter.next();
            
            // want to see what it is matching on, but only in debug mode
            if (mLogger.isDebugEnabled()) {
    //#Blacklist.java:360: Warning: method not available
    //#    -- call on bool org.apache.commons.logging.Log:isDebugEnabled()
    //#    severity: INFORMATIONAL
    //#    class: org.apache.roller.weblogger.util.Blacklist
    //#    method: bool testRegExRules(String, List)
    //#    unanalyzed callee: bool org.apache.commons.logging.Log:isDebugEnabled()
                Matcher matcher = testPattern.matcher(str);
                if (matcher.find()) {
                    mLogger.debug(matcher.group() 
    //#Blacklist.java:363: Warning: method not available
    //#    -- call on void org.apache.commons.logging.Log:debug(Object)
    //#    severity: INFORMATIONAL
    //#    class: org.apache.roller.weblogger.util.Blacklist
    //#    method: bool testRegExRules(String, List)
    //#    unanalyzed callee: void org.apache.commons.logging.Log:debug(Object)
                         + " matched by " + testPattern.pattern());
                    return true;
                }
            } else {
                if (testPattern.matcher(str).find()) {
                    return true;
                }
            }
        }
        return hit;
    //#Blacklist.java:373: end of method: bool org.apache.roller.weblogger.util.Blacklist.testRegExRules(String, List)
    }

    /**
     * Tests the source text against the String rules. Each String rule is
     * first treated as a word-boundary, case insensitive regular expression.
     * If a PatternSyntaxException is encountered, a simple contains test
     * is performed.
     *
     * @param source The text in which to apply the matching rules.
     * @param rules A list a simple matching rules.
     *
     * @return true if a match was found, otherwise false
     */
    private static boolean testStringRules(String source, List rules) {
        boolean matches = false;
    //#Blacklist.java:388: method: bool org.apache.roller.weblogger.util.Blacklist.testStringRules(String, List)
    //#input(bool testStringRules(String, List)): ")\b"._tainted
    //#input(bool testStringRules(String, List)): ":"._tainted
    //#input(bool testStringRules(String, List)): "\b("._tainted
    //#input(bool testStringRules(String, List)): "matched:"._tainted
    //#input(bool testStringRules(String, List)): mLogger
    //#input(bool testStringRules(String, List)): rules
    //#input(bool testStringRules(String, List)): source
    //#output(bool testStringRules(String, List)): return_value
    //#pre[2] (bool testStringRules(String, List)): rules != null
    //#pre[1] (bool testStringRules(String, List)): (soft) mLogger != null
    //#pre[3] (bool testStringRules(String, List)): (soft) source != null
    //#presumption(bool testStringRules(String, List)): java.util.regex.Pattern:compile(...)@402 != null
    //#presumption(bool testStringRules(String, List)): java.util.regex.Pattern:matcher(...)@406 != null
    //#post(bool testStringRules(String, List)): init'ed(return_value)
    //#test_vector(bool testStringRules(String, List)): java.util.Iterator:hasNext(...)@390: {0}, {1}
        
        for (Object ruleObj : rules) {
            String rule;
            rule = (String) ruleObj;

            try {
                StringBuilder patternBuilder;
                patternBuilder = new StringBuilder();
                patternBuilder.append("\\b(");
                patternBuilder.append(rule);
                patternBuilder.append(")\\b");

                Pattern pattern;
                pattern = Pattern.compile(patternBuilder.toString(),
                        Pattern.CASE_INSENSITIVE);

                Matcher matcher;
                matcher = pattern.matcher(source);

                matches = matcher.find();
                if (matches) {
                    break;
                }
            }
            catch (PatternSyntaxException e) {
    //#Blacklist.java:413: Warning: unused assignment
    //#    unused assignment into e
    //#    severity: LOW
    //#    class: org.apache.roller.weblogger.util.Blacklist
    //#    method: bool testStringRules(String, List)
                matches = source.contains(rule);
                if (matches) {
                    break;
                }
            }
            finally {
                if (matches) {
                    // Log the matched rule in debug mode
                    if (mLogger.isDebugEnabled()) {
    //#Blacklist.java:422: Warning: method not available
    //#    -- call on bool org.apache.commons.logging.Log:isDebugEnabled()
    //#    severity: INFORMATIONAL
    //#    class: org.apache.roller.weblogger.util.Blacklist
    //#    method: bool testStringRules(String, List)
    //#    unanalyzed callee: bool org.apache.commons.logging.Log:isDebugEnabled()
                        mLogger.debug("matched:" + rule + ":");
    //#Blacklist.java:423: Warning: method not available
    //#    -- call on void org.apache.commons.logging.Log:debug(Object)
    //#    severity: INFORMATIONAL
    //#    class: org.apache.roller.weblogger.util.Blacklist
    //#    method: bool testStringRules(String, List)
    //#    unanalyzed callee: void org.apache.commons.logging.Log:debug(Object)
                    }
                }
            }
        }
        
        return matches;
    //#Blacklist.java:429: end of method: bool org.apache.roller.weblogger.util.Blacklist.testStringRules(String, List)
    }   
    
    /** Utility method to populate lists based a blacklist in string form */
    public static void populateSpamRules(
        String blacklist, List stringRules, List regexRules, String addendum) {
        String weblogWords = blacklist;
    //#Blacklist.java:435: method: void org.apache.roller.weblogger.util.Blacklist.populateSpamRules(String, List, List, String)
    //#input(void populateSpamRules(String, List, List, String)): ""._tainted
    //#input(void populateSpamRules(String, List, List, String)): addendum
    //#input(void populateSpamRules(String, List, List, String)): addendum._tainted
    //#input(void populateSpamRules(String, List, List, String)): blacklist
    //#input(void populateSpamRules(String, List, List, String)): blacklist._tainted
    //#input(void populateSpamRules(String, List, List, String)): regexRules
    //#input(void populateSpamRules(String, List, List, String)): stringRules
    //#pre[5] (void populateSpamRules(String, List, List, String)): (soft) regexRules != null
    //#pre[6] (void populateSpamRules(String, List, List, String)): (soft) stringRules != null
    //#test_vector(void populateSpamRules(String, List, List, String)): java.lang.String:startsWith(...)@441: {0}, {1}
    //#test_vector(void populateSpamRules(String, List, List, String)): java.lang.String:startsWith(...)@442: {0}, {1}
    //#test_vector(void populateSpamRules(String, List, List, String)): java.util.StringTokenizer:hasMoreTokens(...)@439: {0}, {1}
        weblogWords = (weblogWords == null) ? "" : weblogWords;
        String siteWords = (addendum != null) ? addendum : "";
        StringTokenizer toker = new StringTokenizer(siteWords + weblogWords,"\n");
        while (toker.hasMoreTokens()) {
            String token = toker.nextToken().trim();
            if (token.startsWith("#")) continue;
            if (token.startsWith("(")) {
                regexRules.add(Pattern.compile(token));
            } else {
                stringRules.add(token);
            }
        }        
    }
    //#Blacklist.java:448: end of method: void org.apache.roller.weblogger.util.Blacklist.populateSpamRules(String, List, List, String)
        
    /** Return pretty list of String and RegEx rules. */
    public String toString() {
        StringBuffer buf = new StringBuffer("blacklist ");
    //#Blacklist.java:452: method: String org.apache.roller.weblogger.util.Blacklist.toString()
    //#input(String toString()): "&#10;"._tainted
    //#input(String toString()): "Regex blacklist "._tainted
    //#input(String toString()): "blacklist "._tainted
    //#input(String toString()): this
    //#input(String toString()): this.blacklistRegex
    //#input(String toString()): this.blacklistRegex._tainted
    //#input(String toString()): this.blacklistStr
    //#input(String toString()): this.blacklistStr._tainted
    //#output(String toString()): java.lang.StringBuffer:toString(...)._tainted
    //#output(String toString()): return_value
    //#new obj(String toString()): java.lang.StringBuffer:toString(...)
    //#pre[2] (String toString()): init'ed(this.blacklistRegex)
    //#pre[4] (String toString()): init'ed(this.blacklistStr)
    //#post(String toString()): java.lang.StringBuffer:toString(...)._tainted == 0
    //#post(String toString()): return_value == &java.lang.StringBuffer:toString(...)
        buf.append(blacklistStr).append("\n");
        buf.append("Regex blacklist ").append(blacklistRegex);
        return buf.toString();
    //#Blacklist.java:455: end of method: String org.apache.roller.weblogger.util.Blacklist.toString()
    }
}
    //#Blacklist.java:: end of class: org.apache.roller.weblogger.util.Blacklist
