//# 0 errors, 191 messages
//#
/*
    //#Service.java:1:1: class: com.dmdirc.plugins.Service
    //#Service.java:1:1: method: com.dmdirc.plugins.Service.com.dmdirc.plugins.Service__static_init
 * Copyright (c) 2006-2009 Chris Smith, Shane Mc Cormack, Gregory Holmes
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package com.dmdirc.plugins;

import java.util.List;
import java.util.ArrayList;

/**
 * Defines a service provided by a ServiceProvider.
 */
public class Service {
	/** Service Type. */
	private final String type;
	
	/** Service Name. */
	private final String name;
	
	/** List of ServiceProviders that implement this service. */
	private List<ServiceProvider> serviceproviders = new ArrayList<ServiceProvider>();
	
	/**
	 * Create a new Service
	 *
	 * @param type Type of this service
	 * @param name Name of this service
	 */
	protected Service(final String type, final String name) {
    //#Service.java:46: method: void com.dmdirc.plugins.Service.com.dmdirc.plugins.Service(String, String)
    //#input(void com.dmdirc.plugins.Service(String, String)): name
    //#input(void com.dmdirc.plugins.Service(String, String)): this
    //#input(void com.dmdirc.plugins.Service(String, String)): type
    //#output(void com.dmdirc.plugins.Service(String, String)): new ArrayList(Service#1) num objects
    //#output(void com.dmdirc.plugins.Service(String, String)): this.name
    //#output(void com.dmdirc.plugins.Service(String, String)): this.serviceproviders
    //#output(void com.dmdirc.plugins.Service(String, String)): this.type
    //#new obj(void com.dmdirc.plugins.Service(String, String)): new ArrayList(Service#1)
    //#post(void com.dmdirc.plugins.Service(String, String)): this.name == name
    //#post(void com.dmdirc.plugins.Service(String, String)): init'ed(this.name)
    //#post(void com.dmdirc.plugins.Service(String, String)): this.serviceproviders == &new ArrayList(Service#1)
    //#post(void com.dmdirc.plugins.Service(String, String)): this.type == type
    //#post(void com.dmdirc.plugins.Service(String, String)): init'ed(this.type)
    //#post(void com.dmdirc.plugins.Service(String, String)): new ArrayList(Service#1) num objects == 1
		this.type = type;
		this.name = name;
	}
    //#Service.java:49: end of method: void com.dmdirc.plugins.Service.com.dmdirc.plugins.Service(String, String)
	
	/**
	 * Get the name of this service
	 *
	 * @return The name of this service
	 */
	public String getName() {
		return name;
    //#Service.java:57: method: String com.dmdirc.plugins.Service.getName()
    //#input(String getName()): this
    //#input(String getName()): this.name
    //#output(String getName()): return_value
    //#post(String getName()): return_value == this.name
    //#post(String getName()): init'ed(return_value)
    //#Service.java:57: end of method: String com.dmdirc.plugins.Service.getName()
	}
	
	/**
	 * Get the type of this service
	 *
	 * @return The type of this service
	 */
	public String getType() {
		return type;
    //#Service.java:66: method: String com.dmdirc.plugins.Service.getType()
    //#input(String getType()): this
    //#input(String getType()): this.type
    //#output(String getType()): return_value
    //#post(String getType()): return_value == this.type
    //#post(String getType()): init'ed(return_value)
    //#Service.java:66: end of method: String com.dmdirc.plugins.Service.getType()
	}
	
	/**
	 * Add the given ServiceProvider as a provider for this service.
	 *
	 * @param provider ServiceProvider that provides this service
	 */
	public void addProvider(final ServiceProvider provider) {
		serviceproviders.add(provider);
    //#Service.java:75: method: void com.dmdirc.plugins.Service.addProvider(ServiceProvider)
    //#input(void addProvider(ServiceProvider)): provider
    //#input(void addProvider(ServiceProvider)): this
    //#input(void addProvider(ServiceProvider)): this.serviceproviders
    //#pre[3] (void addProvider(ServiceProvider)): this.serviceproviders != null
	}
    //#Service.java:76: end of method: void com.dmdirc.plugins.Service.addProvider(ServiceProvider)
	
	/**
	 * Remove the given ServiceProvider as a provider for this service.
	 *
	 * @param provider ServiceProvider that no longer provides this service
	 */
	public void delProvider(final ServiceProvider provider) {
		serviceproviders.remove(provider);
    //#Service.java:84: method: void com.dmdirc.plugins.Service.delProvider(ServiceProvider)
    //#input(void delProvider(ServiceProvider)): provider
    //#input(void delProvider(ServiceProvider)): this
    //#input(void delProvider(ServiceProvider)): this.serviceproviders
    //#pre[3] (void delProvider(ServiceProvider)): this.serviceproviders != null
	}
    //#Service.java:85: end of method: void com.dmdirc.plugins.Service.delProvider(ServiceProvider)
	
	/**
	 * Get a list of ServiceProviders for this service
	 *
	 * @return List of ServiceProvider that provide this service
	 */
	public List<ServiceProvider> getProviders() {
		return new ArrayList<ServiceProvider>(serviceproviders);
    //#Service.java:93: method: List com.dmdirc.plugins.Service.getProviders()
    //#input(List getProviders()): this
    //#input(List getProviders()): this.serviceproviders
    //#output(List getProviders()): new ArrayList(getProviders#1) num objects
    //#output(List getProviders()): return_value
    //#new obj(List getProviders()): new ArrayList(getProviders#1)
    //#pre[2] (List getProviders()): init'ed(this.serviceproviders)
    //#post(List getProviders()): return_value == &new ArrayList(getProviders#1)
    //#post(List getProviders()): new ArrayList(getProviders#1) num objects == 1
    //#Service.java:93: end of method: List com.dmdirc.plugins.Service.getProviders()
	}
	
	/**
	 * Get the first active ServiceProvider for this service, or null.
	 *
	 * @return First active ServiceProvider for this service, or null.
	 */
	public ServiceProvider getActiveProvider() {
		for (ServiceProvider provider : getProviders()) {
    //#Service.java:102: method: ServiceProvider com.dmdirc.plugins.Service.getActiveProvider()
    //#input(ServiceProvider getActiveProvider()): __Descendant_Table[com/dmdirc/plugins/Service]
    //#input(ServiceProvider getActiveProvider()): __Descendant_Table[others]
    //#input(ServiceProvider getActiveProvider()): __Dispatch_Table.getProviders()Ljava/util/List;
    //#input(ServiceProvider getActiveProvider()): com/dmdirc/plugins/PluginInfo.__Descendant_Table[com/dmdirc/plugins/PluginInfo]
    //#input(ServiceProvider getActiveProvider()): com/dmdirc/plugins/PluginInfo.__Descendant_Table[others]
    //#input(ServiceProvider getActiveProvider()): com/dmdirc/plugins/PluginInfo.__Dispatch_Table.isActive()Z
    //#input(ServiceProvider getActiveProvider()): com/dmdirc/plugins/PluginInfo.__Dispatch_Table.isLoaded()Z
    //#input(ServiceProvider getActiveProvider()): com/dmdirc/plugins/ServiceProvider.__Descendant_Table[com/dmdirc/plugins/PluginInfo]
    //#input(ServiceProvider getActiveProvider()): com/dmdirc/plugins/ServiceProvider.__Descendant_Table[com/dmdirc/plugins/ServiceProvider]
    //#input(ServiceProvider getActiveProvider()): com/dmdirc/plugins/ServiceProvider.__Descendant_Table[others]
    //#input(ServiceProvider getActiveProvider()): com/dmdirc/plugins/ServiceProvider.__Dispatch_Table.isActive()Z
    //#input(ServiceProvider getActiveProvider()): this
    //#input(ServiceProvider getActiveProvider()): this.__Tag
    //#input(ServiceProvider getActiveProvider()): this.serviceproviders
    //#output(ServiceProvider getActiveProvider()): return_value
    //#pre[2] (ServiceProvider getActiveProvider()): this.__Tag == com/dmdirc/plugins/Service
    //#pre[3] (ServiceProvider getActiveProvider()): init'ed(this.serviceproviders)
    //#presumption(ServiceProvider getActiveProvider()): java.util.Iterator:next(...).__Tag@102 == com/dmdirc/plugins/PluginInfo
    //#presumption(ServiceProvider getActiveProvider()): java.util.Iterator:next(...)@102 != null
    //#post(ServiceProvider getActiveProvider()): init'ed(return_value)
    //#unanalyzed(ServiceProvider getActiveProvider()): Effects-of-calling:java.util.ArrayList
    //#test_vector(ServiceProvider getActiveProvider()): java.util.Iterator:hasNext(...)@102: {0}, {1}
			if (provider.isActive()) {
				return provider;
			}
		}
		
		return null;
    //#Service.java:108: end of method: ServiceProvider com.dmdirc.plugins.Service.getActiveProvider()
	}
	
	/**
	 * Check if this service is active.
	 *
	 * @return True if this service is currently active.
	 */
	public boolean isActive() {
		// Service is known, check that at least 1 plugin that provides it is loaded
		for (ServiceProvider provider : getProviders()) {
    //#Service.java:118: method: bool com.dmdirc.plugins.Service.isActive()
    //#input(bool isActive()): __Descendant_Table[com/dmdirc/plugins/Service]
    //#input(bool isActive()): __Descendant_Table[others]
    //#input(bool isActive()): __Dispatch_Table.getProviders()Ljava/util/List;
    //#input(bool isActive()): com/dmdirc/plugins/PluginInfo.__Descendant_Table[com/dmdirc/plugins/PluginInfo]
    //#input(bool isActive()): com/dmdirc/plugins/PluginInfo.__Descendant_Table[others]
    //#input(bool isActive()): com/dmdirc/plugins/PluginInfo.__Dispatch_Table.isActive()Z
    //#input(bool isActive()): com/dmdirc/plugins/PluginInfo.__Dispatch_Table.isLoaded()Z
    //#input(bool isActive()): com/dmdirc/plugins/ServiceProvider.__Descendant_Table[com/dmdirc/plugins/PluginInfo]
    //#input(bool isActive()): com/dmdirc/plugins/ServiceProvider.__Descendant_Table[com/dmdirc/plugins/ServiceProvider]
    //#input(bool isActive()): com/dmdirc/plugins/ServiceProvider.__Descendant_Table[others]
    //#input(bool isActive()): com/dmdirc/plugins/ServiceProvider.__Dispatch_Table.isActive()Z
    //#input(bool isActive()): this
    //#input(bool isActive()): this.__Tag
    //#input(bool isActive()): this.serviceproviders
    //#output(bool isActive()): return_value
    //#pre[2] (bool isActive()): this.__Tag == com/dmdirc/plugins/Service
    //#pre[3] (bool isActive()): init'ed(this.serviceproviders)
    //#presumption(bool isActive()): java.util.Iterator:next(...).__Tag@118 == com/dmdirc/plugins/PluginInfo
    //#presumption(bool isActive()): java.util.Iterator:next(...)@118 != null
    //#post(bool isActive()): init'ed(return_value)
    //#unanalyzed(bool isActive()): Effects-of-calling:java.util.ArrayList
    //#test_vector(bool isActive()): java.util.Iterator:hasNext(...)@118: {0}, {1}
			if (provider.isActive()) {
				return true;
			}
		}
		
		return false;
    //#Service.java:124: end of method: bool com.dmdirc.plugins.Service.isActive()
	}
		
	
	/**
	 * Activate this service.
	 *
	 * @return True if this service is already active, or if it was activated.
	 */
	public boolean activate() {
		if (isActive()) { return true; }
    //#Service.java:134: method: bool com.dmdirc.plugins.Service.activate()
    //#input(bool activate()): __Descendant_Table[com/dmdirc/plugins/Service]
    //#input(bool activate()): __Descendant_Table[others]
    //#input(bool activate()): __Dispatch_Table.getProviders()Ljava/util/List;
    //#input(bool activate()): __Dispatch_Table.isActive()Z
    //#input(bool activate()): com/dmdirc/plugins/PluginInfo.__Descendant_Table[com/dmdirc/plugins/PluginInfo]
    //#input(bool activate()): com/dmdirc/plugins/PluginInfo.__Descendant_Table[others]
    //#input(bool activate()): com/dmdirc/plugins/PluginInfo.__Dispatch_Table.activateServices()V
    //#input(bool activate()): com/dmdirc/plugins/PluginInfo.__Dispatch_Table.isActive()Z
    //#input(bool activate()): com/dmdirc/plugins/PluginInfo.__Dispatch_Table.isLoaded()Z
    //#input(bool activate()): com/dmdirc/plugins/PluginInfo.__Dispatch_Table.loadPlugin()V
    //#input(bool activate()): com/dmdirc/plugins/ServiceProvider.__Descendant_Table[com/dmdirc/plugins/PluginInfo]
    //#input(bool activate()): com/dmdirc/plugins/ServiceProvider.__Descendant_Table[com/dmdirc/plugins/ServiceProvider]
    //#input(bool activate()): com/dmdirc/plugins/ServiceProvider.__Descendant_Table[others]
    //#input(bool activate()): com/dmdirc/plugins/ServiceProvider.__Dispatch_Table.activateServices()V
    //#input(bool activate()): com/dmdirc/plugins/ServiceProvider.__Dispatch_Table.isActive()Z
    //#input(bool activate()): this
    //#input(bool activate()): this.__Tag
    //#input(bool activate()): this.serviceproviders
    //#output(bool activate()): return_value
    //#pre[2] (bool activate()): this.__Tag == com/dmdirc/plugins/Service
    //#pre[3] (bool activate()): (soft) init'ed(this.serviceproviders)
    //#presumption(bool activate()): java.util.Iterator:next(...).__Tag@138 == com/dmdirc/plugins/PluginInfo
    //#presumption(bool activate()): java.util.Iterator:next(...)@138 != null
    //#post(bool activate()): init'ed(return_value)
    //#unanalyzed(bool activate()): Effects-of-calling:java.util.ArrayList
    //#unanalyzed(bool activate()): Effects-of-calling:java.util.List:iterator
    //#unanalyzed(bool activate()): Effects-of-calling:java.util.Iterator:hasNext
    //#unanalyzed(bool activate()): Effects-of-calling:java.util.Iterator:next
    //#unanalyzed(bool activate()): Effects-of-calling:isActive
    //#unanalyzed(bool activate()): Effects-of-calling:java.lang.Throwable:__curr_excep_obj
    //#unanalyzed(bool activate()): Effects-of-calling:java.lang.StringBuilder
    //#unanalyzed(bool activate()): Effects-of-calling:java.lang.StringBuilder:append
    //#unanalyzed(bool activate()): Effects-of-calling:java.lang.StringBuilder:toString
    //#unanalyzed(bool activate()): Effects-of-calling:updateProvides
    //#unanalyzed(bool activate()): Effects-of-calling:checkRequirements
    //#unanalyzed(bool activate()): Effects-of-calling:loadRequired
    //#unanalyzed(bool activate()): Effects-of-calling:onLoad
    //#unanalyzed(bool activate()): Effects-of-calling:getName
    //#unanalyzed(bool activate()): Effects-of-calling:java.lang.Throwable:getMessage
    //#unanalyzed(bool activate()): Effects-of-calling:addError
    //#unanalyzed(bool activate()): Effects-of-calling:unloadPlugin
    //#unanalyzed(bool activate()): Effects-of-calling:getMainClass
    //#unanalyzed(bool activate()): Effects-of-calling:loadClass
    //#unanalyzed(bool activate()): Effects-of-calling:com.dmdirc.actions.ActionManager:processEvent
    //#unanalyzed(bool activate()): Effects-of-calling:loadPlugin
    //#test_vector(bool activate()): java.util.Iterator:hasNext(...)@138: {0}, {1}
    //#test_vector(bool activate()): provider.plugin@138: Inverse{null}, Addr_Set{null}
		
		// If none of the plugins that provide the service are loaded, load the
		// first one that registered itself as the provider
		for (ServiceProvider provider : getProviders()) {
			if (!provider.isActive()) {
				provider.activateServices();
				if (provider.isActive()) {
					return true;
				}
			}
		}
		
		return false;
    //#Service.java:147: end of method: bool com.dmdirc.plugins.Service.activate()
	}
	
	/**
	 * Get this service as a String
	 *
	 * @return String representation of this service
	 */
	public String toString() {
		return "Service: "+type+"->"+name+" (Providers: "+serviceproviders.size()+")";
    //#Service.java:156: method: String com.dmdirc.plugins.Service.toString()
    //#input(String toString()): " (Providers: "._tainted
    //#input(String toString()): ")"._tainted
    //#input(String toString()): "->"._tainted
    //#input(String toString()): "Service: "._tainted
    //#input(String toString()): this
    //#input(String toString()): this.name
    //#input(String toString()): this.name._tainted
    //#input(String toString()): this.serviceproviders
    //#input(String toString()): this.type
    //#input(String toString()): this.type._tainted
    //#output(String toString()): java.lang.StringBuilder:toString(...)._tainted
    //#output(String toString()): return_value
    //#new obj(String toString()): java.lang.StringBuilder:toString(...)
    //#pre[4] (String toString()): this.serviceproviders != null
    //#post(String toString()): java.lang.StringBuilder:toString(...)._tainted == 0
    //#post(String toString()): return_value == &java.lang.StringBuilder:toString(...)
    //#Service.java:156: end of method: String com.dmdirc.plugins.Service.toString()
	}
}
    //#output(com.dmdirc.plugins.Service__static_init): __Descendant_Table[com/dmdirc/plugins/Service]
    //#output(com.dmdirc.plugins.Service__static_init): __Dispatch_Table.activate()Z
    //#output(com.dmdirc.plugins.Service__static_init): __Dispatch_Table.addProvider(Lcom/dmdirc/plugins/ServiceProvider;)V
    //#output(com.dmdirc.plugins.Service__static_init): __Dispatch_Table.delProvider(Lcom/dmdirc/plugins/ServiceProvider;)V
    //#output(com.dmdirc.plugins.Service__static_init): __Dispatch_Table.getActiveProvider()Lcom/dmdirc/plugins/ServiceProvider;
    //#output(com.dmdirc.plugins.Service__static_init): __Dispatch_Table.getName()Ljava/lang/String;
    //#output(com.dmdirc.plugins.Service__static_init): __Dispatch_Table.getProviders()Ljava/util/List;
    //#output(com.dmdirc.plugins.Service__static_init): __Dispatch_Table.getType()Ljava/lang/String;
    //#output(com.dmdirc.plugins.Service__static_init): __Dispatch_Table.isActive()Z
    //#output(com.dmdirc.plugins.Service__static_init): __Dispatch_Table.toString()Ljava/lang/String;
    //#post(com.dmdirc.plugins.Service__static_init): __Descendant_Table[com/dmdirc/plugins/Service] == &__Dispatch_Table
    //#post(com.dmdirc.plugins.Service__static_init): __Dispatch_Table.activate()Z == &activate
    //#post(com.dmdirc.plugins.Service__static_init): __Dispatch_Table.addProvider(Lcom/dmdirc/plugins/ServiceProvider;)V == &addProvider
    //#post(com.dmdirc.plugins.Service__static_init): __Dispatch_Table.delProvider(Lcom/dmdirc/plugins/ServiceProvider;)V == &delProvider
    //#post(com.dmdirc.plugins.Service__static_init): __Dispatch_Table.getActiveProvider()Lcom/dmdirc/plugins/ServiceProvider; == &getActiveProvider
    //#post(com.dmdirc.plugins.Service__static_init): __Dispatch_Table.getName()Ljava/lang/String; == &getName
    //#post(com.dmdirc.plugins.Service__static_init): __Dispatch_Table.getProviders()Ljava/util/List; == &getProviders
    //#post(com.dmdirc.plugins.Service__static_init): __Dispatch_Table.getType()Ljava/lang/String; == &getType
    //#post(com.dmdirc.plugins.Service__static_init): __Dispatch_Table.isActive()Z == &isActive
    //#post(com.dmdirc.plugins.Service__static_init): __Dispatch_Table.toString()Ljava/lang/String; == &toString
    //#Service.java:: end of method: com.dmdirc.plugins.Service.com.dmdirc.plugins.Service__static_init
    //#Service.java:: end of class: com.dmdirc.plugins.Service
