//# 3 errors, 159 messages
//#
/*
    //#ThreadManagerImpl.java:1:1: class: org.apache.roller.weblogger.business.runnable.ThreadManagerImpl
 * 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.
 */

package org.apache.roller.weblogger.business.runnable;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.roller.weblogger.WebloggerException;
import org.apache.roller.weblogger.business.InitializationException;
import org.apache.roller.weblogger.config.WebloggerConfig;
import org.apache.roller.weblogger.pojos.TaskLock;


/**
 * Manage Roller's thread use.
 */
@com.google.inject.Singleton
public abstract class ThreadManagerImpl implements ThreadManager {
    
    private static final Log log = LogFactory.getLog(ThreadManagerImpl.class);
    //#ThreadManagerImpl.java:42: method: org.apache.roller.weblogger.business.runnable.ThreadManagerImpl.org.apache.roller.weblogger.business.runnable.ThreadManagerImpl__static_init
    //#ThreadManagerImpl.java:42: Warning: method not available
    //#    -- call on Log org.apache.commons.logging.LogFactory:getLog(Class)
    //#    severity: INFORMATIONAL
    //#    class: org.apache.roller.weblogger.business.runnable.ThreadManagerImpl
    //#    method: org.apache.roller.weblogger.business.runnable.ThreadManagerImpl__static_init
    //#    unanalyzed callee: Log org.apache.commons.logging.LogFactory:getLog(Class)
    //#output(org.apache.roller.weblogger.business.runnable.ThreadManagerImpl__static_init): __Descendant_Table[org/apache/roller/weblogger/business/runnable/ThreadManagerImpl]
    //#output(org.apache.roller.weblogger.business.runnable.ThreadManagerImpl__static_init): __Dispatch_Table.executeInBackground(Ljava/lang/Runnable;)V
    //#output(org.apache.roller.weblogger.business.runnable.ThreadManagerImpl__static_init): __Dispatch_Table.executeInForeground(Ljava/lang/Runnable;)V
    //#output(org.apache.roller.weblogger.business.runnable.ThreadManagerImpl__static_init): __Dispatch_Table.initialize()V
    //#output(org.apache.roller.weblogger.business.runnable.ThreadManagerImpl__static_init): __Dispatch_Table.registerLease(Lorg/apache/roller/weblogger/business/runnable/RollerTask;)Z
    //#output(org.apache.roller.weblogger.business.runnable.ThreadManagerImpl__static_init): __Dispatch_Table.release()V
    //#output(org.apache.roller.weblogger.business.runnable.ThreadManagerImpl__static_init): __Dispatch_Table.shutdown()V
    //#output(org.apache.roller.weblogger.business.runnable.ThreadManagerImpl__static_init): __Dispatch_Table.unregisterLease(Lorg/apache/roller/weblogger/business/runnable/RollerTask;)Z
    //#output(org.apache.roller.weblogger.business.runnable.ThreadManagerImpl__static_init): log
    //#output(org.apache.roller.weblogger.business.runnable.ThreadManagerImpl__static_init): org/apache/roller/weblogger/business/runnable/ThreadManager.__Descendant_Table[org/apache/roller/weblogger/business/runnable/ThreadManagerImpl]
    //#post(org.apache.roller.weblogger.business.runnable.ThreadManagerImpl__static_init): __Descendant_Table[org/apache/roller/weblogger/business/runnable/ThreadManagerImpl] == &__Dispatch_Table
    //#post(org.apache.roller.weblogger.business.runnable.ThreadManagerImpl__static_init): org/apache/roller/weblogger/business/runnable/ThreadManager.__Descendant_Table[org/apache/roller/weblogger/business/runnable/ThreadManagerImpl] == &__Dispatch_Table
    //#post(org.apache.roller.weblogger.business.runnable.ThreadManagerImpl__static_init): __Dispatch_Table.executeInBackground(Ljava/lang/Runnable;)V == &executeInBackground
    //#post(org.apache.roller.weblogger.business.runnable.ThreadManagerImpl__static_init): __Dispatch_Table.executeInForeground(Ljava/lang/Runnable;)V == &executeInForeground
    //#post(org.apache.roller.weblogger.business.runnable.ThreadManagerImpl__static_init): __Dispatch_Table.initialize()V == &initialize
    //#post(org.apache.roller.weblogger.business.runnable.ThreadManagerImpl__static_init): __Dispatch_Table.registerLease(Lorg/apache/roller/weblogger/business/runnable/RollerTask;)Z == &registerLease
    //#post(org.apache.roller.weblogger.business.runnable.ThreadManagerImpl__static_init): __Dispatch_Table.release()V == &release
    //#post(org.apache.roller.weblogger.business.runnable.ThreadManagerImpl__static_init): __Dispatch_Table.shutdown()V == &shutdown
    //#post(org.apache.roller.weblogger.business.runnable.ThreadManagerImpl__static_init): __Dispatch_Table.unregisterLease(Lorg/apache/roller/weblogger/business/runnable/RollerTask;)Z == &unregisterLease
    //#post(org.apache.roller.weblogger.business.runnable.ThreadManagerImpl__static_init): init'ed(log)
    //#ThreadManagerImpl.java:42: end of method: org.apache.roller.weblogger.business.runnable.ThreadManagerImpl.org.apache.roller.weblogger.business.runnable.ThreadManagerImpl__static_init
    
    // our own scheduler thread
    private Thread schedulerThread = null;
    
    // a simple thread executor
    private final ExecutorService serviceScheduler;
    
    
    public ThreadManagerImpl() {
    //#ThreadManagerImpl.java:51: method: void org.apache.roller.weblogger.business.runnable.ThreadManagerImpl.org.apache.roller.weblogger.business.runnable.ThreadManagerImpl()
    //#input(void org.apache.roller.weblogger.business.runnable.ThreadManagerImpl()): log
    //#input(void org.apache.roller.weblogger.business.runnable.ThreadManagerImpl()): this
    //#output(void org.apache.roller.weblogger.business.runnable.ThreadManagerImpl()): this.schedulerThread
    //#output(void org.apache.roller.weblogger.business.runnable.ThreadManagerImpl()): this.serviceScheduler
    //#presumption(void org.apache.roller.weblogger.business.runnable.ThreadManagerImpl()): org.apache.commons.logging.LogFactory:getLog(...)@42 != null
    //#post(void org.apache.roller.weblogger.business.runnable.ThreadManagerImpl()): this.schedulerThread == null
    //#post(void org.apache.roller.weblogger.business.runnable.ThreadManagerImpl()): init'ed(this.serviceScheduler)
        
        log.info("Instantiating Thread Manager");
    //#ThreadManagerImpl.java:53: Warning: method not available
    //#    -- call on void org.apache.commons.logging.Log:info(Object)
    //#    severity: INFORMATIONAL
    //#    class: org.apache.roller.weblogger.business.runnable.ThreadManagerImpl
    //#    method: void org.apache.roller.weblogger.business.runnable.ThreadManagerImpl()
    //#    unanalyzed callee: void org.apache.commons.logging.Log:info(Object)
        
        serviceScheduler = Executors.newCachedThreadPool();
    }
    //#ThreadManagerImpl.java:56: end of method: void org.apache.roller.weblogger.business.runnable.ThreadManagerImpl.org.apache.roller.weblogger.business.runnable.ThreadManagerImpl()
    
    
    public void initialize() throws InitializationException {
                    
        // initialize tasks, making sure that each task has a tasklock record in the db
        List<RollerTask> webloggerTasks = new ArrayList<RollerTask>();
    //#ThreadManagerImpl.java:62: method: void org.apache.roller.weblogger.business.runnable.ThreadManagerImpl.initialize()
    //#input(void initialize()): ".class"._tainted
    //#input(void initialize()): "="._tainted
    //#input(void initialize()): "Fetching property ["._tainted
    //#input(void initialize()): "Initializing task: "._tainted
    //#input(void initialize()): "]"._tainted
    //#input(void initialize()): "tasks."._tainted
    //#input(void initialize()): "tasks.enabled"._tainted
    //#input(void initialize()): log
    //#input(void initialize()): org/apache/roller/weblogger/business/pings/PingQueueTask.__Dispatch_Table.getName()Ljava/lang/String;
    //#input(void initialize()): org/apache/roller/weblogger/business/pings/PingQueueTask.__Dispatch_Table.init()V
    //#input(void initialize()): org/apache/roller/weblogger/business/runnable/ResetHitCountsTask.__Dispatch_Table.getName()Ljava/lang/String;
    //#input(void initialize()): org/apache/roller/weblogger/business/runnable/ResetHitCountsTask.__Dispatch_Table.init()V
    //#input(void initialize()): org/apache/roller/weblogger/business/runnable/RollerTask.__Descendant_Table[org/apache/roller/weblogger/business/pings/PingQueueTask]
    //#input(void initialize()): org/apache/roller/weblogger/business/runnable/RollerTask.__Descendant_Table[org/apache/roller/weblogger/business/runnable/ResetHitCountsTask]
    //#input(void initialize()): org/apache/roller/weblogger/business/runnable/RollerTask.__Descendant_Table[org/apache/roller/weblogger/business/runnable/RollerTaskWithLeasing]
    //#input(void initialize()): org/apache/roller/weblogger/business/runnable/RollerTask.__Descendant_Table[org/apache/roller/weblogger/business/runnable/RollerTask]
    //#input(void initialize()): org/apache/roller/weblogger/business/runnable/RollerTask.__Descendant_Table[org/apache/roller/weblogger/business/runnable/ScheduledEntriesTask]
    //#input(void initialize()): org/apache/roller/weblogger/business/runnable/RollerTask.__Descendant_Table[org/apache/roller/weblogger/business/runnable/TurnoverReferersTask]
    //#input(void initialize()): org/apache/roller/weblogger/business/runnable/RollerTask.__Descendant_Table[others]
    //#input(void initialize()): org/apache/roller/weblogger/business/runnable/RollerTask.__Dispatch_Table.getName()Ljava/lang/String;
    //#input(void initialize()): org/apache/roller/weblogger/business/runnable/RollerTask.__Dispatch_Table.init()V
    //#input(void initialize()): org/apache/roller/weblogger/business/runnable/RollerTaskWithLeasing.__Dispatch_Table.getName()Ljava/lang/String;
    //#input(void initialize()): org/apache/roller/weblogger/business/runnable/RollerTaskWithLeasing.__Dispatch_Table.init()V
    //#input(void initialize()): org/apache/roller/weblogger/business/runnable/ScheduledEntriesTask.__Dispatch_Table.getName()Ljava/lang/String;
    //#input(void initialize()): org/apache/roller/weblogger/business/runnable/ScheduledEntriesTask.__Dispatch_Table.init()V
    //#input(void initialize()): org/apache/roller/weblogger/business/runnable/TurnoverReferersTask.__Dispatch_Table.getName()Ljava/lang/String;
    //#input(void initialize()): org/apache/roller/weblogger/business/runnable/TurnoverReferersTask.__Dispatch_Table.init()V
    //#input(void initialize()): org/apache/roller/weblogger/config/WebloggerConfig.config
    //#input(void initialize()): org/apache/roller/weblogger/config/WebloggerConfig.log
    //#input(void initialize()): this
    //#input(void initialize()): this.schedulerThread
    //#output(void initialize()): new PingQueueProcessor(init#1*) num objects
    //#output(void initialize()): new PingQueueProcessor(init#1*).__Tag
    //#output(void initialize()): new PingQueueProcessor(init#1*).pingQueueMgr
    //#output(void initialize()): new Thread(initialize#8) num objects
    //#output(void initialize()): org/apache/roller/weblogger/business/pings/PingQueueProcessor.theInstance
    //#output(void initialize()): this.schedulerThread
    //#new obj(void initialize()): new PingQueueProcessor(init#1*)
    //#new obj(void initialize()): new Thread(initialize#8)
    //#pre[2] (void initialize()): init'ed(this.schedulerThread)
    //#pre[7] (void initialize()): org/apache/roller/weblogger/config/WebloggerConfig.config != null
    //#pre[8] (void initialize()): org/apache/roller/weblogger/config/WebloggerConfig.log != null
    //#presumption(void initialize()): arr$.length@64 <= 4_294_967_295
    //#presumption(void initialize()): java.lang.Class:forName(...)@72 != null
    //#presumption(void initialize()): java.lang.Class:newInstance(...).__Tag@73 in {org/apache/roller/weblogger/business/pings/PingQueueTask, org/apache/roller/weblogger/business/runnable/ResetHitCountsTask, org/apache/roller/weblogger/business/runnable/RollerTask, org/apache/roller/weblogger/business/runnable/RollerTaskWithLeasing, org/apache/roller/weblogger/business/runnable/ScheduledEntriesTask, org/apache/roller/weblogger/business/runnable/TurnoverReferersTask}
    //#presumption(void initialize()): org.apache.commons.lang.StringUtils:stripAll(...)@64 != null
    //#presumption(void initialize()): org.apache.commons.logging.LogFactory:getLog(...)@42 != null
    //#post(void initialize()): org/apache/roller/weblogger/business/pings/PingQueueProcessor.theInstance == old org/apache/roller/weblogger/business/pings/PingQueueProcessor.theInstance
    //#post(void initialize()): this.schedulerThread == One-of{old this.schedulerThread, &new Thread(initialize#8)}
    //#post(void initialize()): this.schedulerThread != null
    //#post(void initialize()): new PingQueueProcessor(init#1*) num objects == undefined
    //#post(void initialize()): new PingQueueProcessor(init#1*) num objects == 0, if init'ed
    //#post(void initialize()): new PingQueueProcessor(init#1*).__Tag == new PingQueueProcessor(init#1*) num objects
    //#post(void initialize()): new PingQueueProcessor(init#1*).pingQueueMgr == undefined
    //#post(void initialize()): new PingQueueProcessor(init#1*).pingQueueMgr == null
    //#post(void initialize()): new Thread(initialize#8) num objects <= 1
    //#unanalyzed(void initialize()): Effects-of-calling:java.lang.StringBuilder
    //#unanalyzed(void initialize()): Effects-of-calling:java.lang.StringBuilder:append
    //#unanalyzed(void initialize()): Effects-of-calling:java.lang.StringBuilder:toString
    //#unanalyzed(void initialize()): Effects-of-calling:java.lang.String:trim
    //#unanalyzed(void initialize()): Effects-of-calling:org.apache.commons.logging.Log:debug
    //#unanalyzed(void initialize()): Effects-of-calling:java.util.Properties:getProperty
    //#unanalyzed(void initialize()): Effects-of-calling:java.util.concurrent.Executors:newCachedThreadPool
    //#test_vector(void initialize()): this.schedulerThread: Inverse{null}, Addr_Set{null}
    //#test_vector(void initialize()): org.apache.roller.weblogger.business.runnable.ThreadManagerImpl:getTaskLockByName(...)@77: Inverse{null}, Addr_Set{null}
        String tasksStr = WebloggerConfig.getProperty("tasks.enabled");
        String[] tasks = StringUtils.stripAll(StringUtils.split(tasksStr, ","));
    //#ThreadManagerImpl.java:64: Warning: method not available
    //#    -- call on String[] org.apache.commons.lang.StringUtils:split(String, String)
    //#    severity: INFORMATIONAL
    //#    class: org.apache.roller.weblogger.business.runnable.ThreadManagerImpl
    //#    method: void initialize()
    //#    unanalyzed callee: String[] org.apache.commons.lang.StringUtils:split(String, String)
    //#ThreadManagerImpl.java:64: Warning: method not available
    //#    -- call on String[] org.apache.commons.lang.StringUtils:stripAll(String[])
    //#    severity: INFORMATIONAL
    //#    class: org.apache.roller.weblogger.business.runnable.ThreadManagerImpl
    //#    method: void initialize()
    //#    unanalyzed callee: String[] org.apache.commons.lang.StringUtils:stripAll(String[])
        for ( String taskName : tasks ) {
    //#ThreadManagerImpl.java:65: ?use of default init
    //#    init'ed(arr$[i$])
    //#    severity: SUPPRESSED
    //#    class: org.apache.roller.weblogger.business.runnable.ThreadManagerImpl
    //#    method: void initialize()
    //#    basic block: bb_3
    //#    assertion: init'ed(arr$[i$])
    //#    VN: undefined
    //#    Expected: Univ-VN-Set
    //#    Bad: {Invalid}
    //#    Attribs:  Ptr  Bad only invalid
            
            String taskClassName = WebloggerConfig.getProperty("tasks."+taskName+".class");
    //#ThreadManagerImpl.java:67: ?use of default init
    //#    init'ed(taskName)
    //#    severity: SUPPRESSED
    //#    class: org.apache.roller.weblogger.business.runnable.ThreadManagerImpl
    //#    method: void initialize()
    //#    basic block: bb_3
    //#    assertion: init'ed(taskName)
    //#    VN: undefined
    //#    Expected: Univ-VN-Set
    //#    Bad: {Invalid}
    //#    Attribs:  Ptr  Bad only invalid
            if(taskClassName != null) {
                log.info("Initializing task: "+taskName);
    //#ThreadManagerImpl.java:69: ?use of default init
    //#    init'ed(taskName)
    //#    severity: SUPPRESSED
    //#    class: org.apache.roller.weblogger.business.runnable.ThreadManagerImpl
    //#    method: void initialize()
    //#    basic block: bb_4
    //#    assertion: init'ed(taskName)
    //#    VN: undefined
    //#    Expected: Univ-VN-Set
    //#    Bad: {Invalid}
    //#    Attribs:  Ptr  Bad only invalid
    //#ThreadManagerImpl.java:69: Warning: method not available
    //#    -- call on void org.apache.commons.logging.Log:info(Object)
    //#    severity: INFORMATIONAL
    //#    class: org.apache.roller.weblogger.business.runnable.ThreadManagerImpl
    //#    method: void initialize()
    //#    unanalyzed callee: void org.apache.commons.logging.Log:info(Object)
                
                try {
                    Class taskClass = Class.forName(taskClassName);
                    RollerTask task = (RollerTask) taskClass.newInstance();
                    task.init();
    //#ThreadManagerImpl.java:74: Warning: call too complex - analysis skipped
    //#    -- call on void init()
    //#    severity: INFORMATIONAL
    //#    class: org.apache.roller.weblogger.business.runnable.ThreadManagerImpl
    //#    method: void initialize()
    //#    unanalyzed callee: void init()
                    
                    // make sure there is a tasklock record in the db
                    TaskLock taskLock = getTaskLockByName(task.getName());
    //#ThreadManagerImpl.java:77: Warning: method not available
    //#    -- call on TaskLock org.apache.roller.weblogger.business.runnable.ThreadManagerImpl:getTaskLockByName(String)
    //#    severity: INFORMATIONAL
    //#    class: org.apache.roller.weblogger.business.runnable.ThreadManagerImpl
    //#    method: void initialize()
    //#    unanalyzed callee: TaskLock org.apache.roller.weblogger.business.runnable.ThreadManagerImpl:getTaskLockByName(String)
                    if (taskLock == null) {
                        log.debug("Task record does not exist, inserting empty record to start with");
    //#ThreadManagerImpl.java:79: Warning: method not available
    //#    -- call on void org.apache.commons.logging.Log:debug(Object)
    //#    severity: INFORMATIONAL
    //#    class: org.apache.roller.weblogger.business.runnable.ThreadManagerImpl
    //#    method: void initialize()
    //#    unanalyzed callee: void org.apache.commons.logging.Log:debug(Object)

                        // insert an empty record
                        taskLock = new TaskLock();
    //#ThreadManagerImpl.java:82: Warning: method not available
    //#    -- call on void org.apache.roller.weblogger.pojos.TaskLock()
    //#    severity: INFORMATIONAL
    //#    class: org.apache.roller.weblogger.business.runnable.ThreadManagerImpl
    //#    method: void initialize()
    //#    unanalyzed callee: void org.apache.roller.weblogger.pojos.TaskLock()
                        taskLock.setName(task.getName());
    //#ThreadManagerImpl.java:83: Warning: method not available
    //#    -- call on void org.apache.roller.weblogger.pojos.TaskLock:setName(String)
    //#    severity: INFORMATIONAL
    //#    class: org.apache.roller.weblogger.business.runnable.ThreadManagerImpl
    //#    method: void initialize()
    //#    unanalyzed callee: void org.apache.roller.weblogger.pojos.TaskLock:setName(String)
                        taskLock.setLastRun(new Date(0));
    //#ThreadManagerImpl.java:84: Warning: method not available
    //#    -- call on void org.apache.roller.weblogger.pojos.TaskLock:setLastRun(Date)
    //#    severity: INFORMATIONAL
    //#    class: org.apache.roller.weblogger.business.runnable.ThreadManagerImpl
    //#    method: void initialize()
    //#    unanalyzed callee: void org.apache.roller.weblogger.pojos.TaskLock:setLastRun(Date)
                        taskLock.setTimeAquired(new Date(0));
    //#ThreadManagerImpl.java:85: Warning: method not available
    //#    -- call on void org.apache.roller.weblogger.pojos.TaskLock:setTimeAquired(Date)
    //#    severity: INFORMATIONAL
    //#    class: org.apache.roller.weblogger.business.runnable.ThreadManagerImpl
    //#    method: void initialize()
    //#    unanalyzed callee: void org.apache.roller.weblogger.pojos.TaskLock:setTimeAquired(Date)
                        taskLock.setTimeLeased(0);
    //#ThreadManagerImpl.java:86: Warning: method not available
    //#    -- call on void org.apache.roller.weblogger.pojos.TaskLock:setTimeLeased(int)
    //#    severity: INFORMATIONAL
    //#    class: org.apache.roller.weblogger.business.runnable.ThreadManagerImpl
    //#    method: void initialize()
    //#    unanalyzed callee: void org.apache.roller.weblogger.pojos.TaskLock:setTimeLeased(int)

                        // save it
                        this.saveTaskLock(taskLock);
    //#ThreadManagerImpl.java:89: Warning: method not available
    //#    -- call on void org.apache.roller.weblogger.business.runnable.ThreadManagerImpl:saveTaskLock(TaskLock)
    //#    severity: INFORMATIONAL
    //#    class: org.apache.roller.weblogger.business.runnable.ThreadManagerImpl
    //#    method: void initialize()
    //#    unanalyzed callee: void org.apache.roller.weblogger.business.runnable.ThreadManagerImpl:saveTaskLock(TaskLock)
                    }
                    
                    // add it to the list of configured tasks
                    webloggerTasks.add(task);
                    
                } catch (ClassCastException ex) {
                    log.warn("Task does not extend RollerTask class", ex);
    //#ThreadManagerImpl.java:96: Warning: method not available
    //#    -- call on void org.apache.commons.logging.Log:warn(Object, Throwable)
    //#    severity: INFORMATIONAL
    //#    class: org.apache.roller.weblogger.business.runnable.ThreadManagerImpl
    //#    method: void initialize()
    //#    unanalyzed callee: void org.apache.commons.logging.Log:warn(Object, Throwable)
                } catch (WebloggerException ex) {
                    log.error("Error scheduling task", ex);
    //#ThreadManagerImpl.java:98: Warning: method not available
    //#    -- call on void org.apache.commons.logging.Log:error(Object, Throwable)
    //#    severity: INFORMATIONAL
    //#    class: org.apache.roller.weblogger.business.runnable.ThreadManagerImpl
    //#    method: void initialize()
    //#    unanalyzed callee: void org.apache.commons.logging.Log:error(Object, Throwable)
                } catch (Exception ex) {
                    log.error("Error instantiating task", ex);
    //#ThreadManagerImpl.java:100: Warning: method not available
    //#    -- call on void org.apache.commons.logging.Log:error(Object, Throwable)
    //#    severity: INFORMATIONAL
    //#    class: org.apache.roller.weblogger.business.runnable.ThreadManagerImpl
    //#    method: void initialize()
    //#    unanalyzed callee: void org.apache.commons.logging.Log:error(Object, Throwable)
                }
            }
        }
        
        // create scheduler
        TaskScheduler scheduler = new TaskScheduler(webloggerTasks);
        
        // start scheduler thread, but only if it's not already running
        if (schedulerThread == null && scheduler != null) {
    //#ThreadManagerImpl.java:109: Warning: test always goes same way
    //#    test predetermined because scheduler != null
    //#    severity: LOW
    //#    class: org.apache.roller.weblogger.business.runnable.ThreadManagerImpl
    //#    method: void initialize()
    //#    from bb: bb_13
    //#    live edge: bb_13-->bb_14
    //#    tested vn: 0
    //#    tested vn values: {0}
            log.debug("Starting scheduler thread");
    //#ThreadManagerImpl.java:110: Warning: method not available
    //#    -- call on void org.apache.commons.logging.Log:debug(Object)
    //#    severity: INFORMATIONAL
    //#    class: org.apache.roller.weblogger.business.runnable.ThreadManagerImpl
    //#    method: void initialize()
    //#    unanalyzed callee: void org.apache.commons.logging.Log:debug(Object)
            schedulerThread = new Thread(scheduler, "Roller Weblogger Task Scheduler");
            // set thread priority between MAX and NORM so we get slightly preferential treatment
            schedulerThread.setPriority((Thread.MAX_PRIORITY + Thread.NORM_PRIORITY)/2);
            schedulerThread.start();
        }
    }
    //#ThreadManagerImpl.java:116: end of method: void org.apache.roller.weblogger.business.runnable.ThreadManagerImpl.initialize()
    
    
    public void executeInBackground(Runnable runnable)
            throws InterruptedException {
        Future task = serviceScheduler.submit(runnable);
    //#ThreadManagerImpl.java:121: method: void org.apache.roller.weblogger.business.runnable.ThreadManagerImpl.executeInBackground(Runnable)
    //#ThreadManagerImpl.java:121: Warning: unused assignment
    //#    unused assignment into task
    //#    severity: LOW
    //#    class: org.apache.roller.weblogger.business.runnable.ThreadManagerImpl
    //#    method: void executeInBackground(Runnable)
    //#input(void executeInBackground(Runnable)): runnable
    //#input(void executeInBackground(Runnable)): this
    //#input(void executeInBackground(Runnable)): this.serviceScheduler
    //#pre[3] (void executeInBackground(Runnable)): this.serviceScheduler != null
    }
    //#ThreadManagerImpl.java:122: end of method: void org.apache.roller.weblogger.business.runnable.ThreadManagerImpl.executeInBackground(Runnable)
    
    
    public void executeInForeground(Runnable runnable)
            throws InterruptedException {
        Future task = serviceScheduler.submit(runnable);
    //#ThreadManagerImpl.java:127: method: void org.apache.roller.weblogger.business.runnable.ThreadManagerImpl.executeInForeground(Runnable)
    //#input(void executeInForeground(Runnable)): runnable
    //#input(void executeInForeground(Runnable)): this
    //#input(void executeInForeground(Runnable)): this.serviceScheduler
    //#pre[3] (void executeInForeground(Runnable)): this.serviceScheduler != null
    //#presumption(void executeInForeground(Runnable)): java.util.concurrent.ExecutorService:submit(...)@127 != null
    //#test_vector(void executeInForeground(Runnable)): java.util.concurrent.Future:isDone(...)@132: {1}, {0}
        
        // since this task is really meant to be executed within this calling 
        // thread, here we can add a little code here to loop until it realizes 
        // the task is done
        while(!task.isDone()) {
            Thread.sleep(500);
        }
    }
    //#ThreadManagerImpl.java:135: end of method: void org.apache.roller.weblogger.business.runnable.ThreadManagerImpl.executeInForeground(Runnable)
    
    
    public void shutdown() {
        
        log.debug("starting shutdown sequence");
    //#ThreadManagerImpl.java:140: method: void org.apache.roller.weblogger.business.runnable.ThreadManagerImpl.shutdown()
    //#ThreadManagerImpl.java:140: Warning: method not available
    //#    -- call on void org.apache.commons.logging.Log:debug(Object)
    //#    severity: INFORMATIONAL
    //#    class: org.apache.roller.weblogger.business.runnable.ThreadManagerImpl
    //#    method: void shutdown()
    //#    unanalyzed callee: void org.apache.commons.logging.Log:debug(Object)
    //#input(void shutdown()): log
    //#input(void shutdown()): this
    //#input(void shutdown()): this.schedulerThread
    //#input(void shutdown()): this.serviceScheduler
    //#pre[2] (void shutdown()): init'ed(this.schedulerThread)
    //#pre[3] (void shutdown()): this.serviceScheduler != null
    //#presumption(void shutdown()): org.apache.commons.logging.LogFactory:getLog(...)@42 != null
    //#test_vector(void shutdown()): this.schedulerThread: Addr_Set{null}, Inverse{null}
        
        // trigger an immediate shutdown of any backgrounded tasks
        serviceScheduler.shutdownNow();
        
        // only stop if we are already running
        if(schedulerThread != null) {
            log.debug("Stopping scheduler");
    //#ThreadManagerImpl.java:147: Warning: method not available
    //#    -- call on void org.apache.commons.logging.Log:debug(Object)
    //#    severity: INFORMATIONAL
    //#    class: org.apache.roller.weblogger.business.runnable.ThreadManagerImpl
    //#    method: void shutdown()
    //#    unanalyzed callee: void org.apache.commons.logging.Log:debug(Object)
            schedulerThread.interrupt();
        }
    }
    //#ThreadManagerImpl.java:150: end of method: void org.apache.roller.weblogger.business.runnable.ThreadManagerImpl.shutdown()
    
    
    public void release() {
        // no-op
    }
    //#ThreadManagerImpl.java:155: method: void org.apache.roller.weblogger.business.runnable.ThreadManagerImpl.release()
    //#ThreadManagerImpl.java:155: end of method: void org.apache.roller.weblogger.business.runnable.ThreadManagerImpl.release()
    
    
    /**
     * Default implementation of lease registration, always returns true.
     * 
     * Subclasses should override this method if they plan to run in an
     * environment that supports clustered deployments.
     */
    public boolean registerLease(RollerTask task) {
        return true;
    //#ThreadManagerImpl.java:165: method: bool org.apache.roller.weblogger.business.runnable.ThreadManagerImpl.registerLease(RollerTask)
    //#output(bool registerLease(RollerTask)): return_value
    //#post(bool registerLease(RollerTask)): return_value == 1
    //#ThreadManagerImpl.java:165: end of method: bool org.apache.roller.weblogger.business.runnable.ThreadManagerImpl.registerLease(RollerTask)
    }
    
    
    /**
     * Default implementation of lease unregistration, always returns true.
     * 
     * Subclasses should override this method if they plan to run in an
     * environment that supports clustered deployments.
     */
    public boolean unregisterLease(RollerTask task) {
        return true;
    //#ThreadManagerImpl.java:176: method: bool org.apache.roller.weblogger.business.runnable.ThreadManagerImpl.unregisterLease(RollerTask)
    //#output(bool unregisterLease(RollerTask)): return_value
    //#post(bool unregisterLease(RollerTask)): return_value == 1
    //#ThreadManagerImpl.java:176: end of method: bool org.apache.roller.weblogger.business.runnable.ThreadManagerImpl.unregisterLease(RollerTask)
    }
    
}
    //#ThreadManagerImpl.java:: end of class: org.apache.roller.weblogger.business.runnable.ThreadManagerImpl
