//# 1 errors, 607 messages
//#
/*
    //#NowPlayingPlugin.java:1:1: class: com.dmdirc.addons.nowplaying.NowPlayingPlugin
    //#NowPlayingPlugin.java:1:1: method: com.dmdirc.addons.nowplaying.NowPlayingPlugin.com.dmdirc.addons.nowplaying.NowPlayingPlugin__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.addons.nowplaying;

import com.dmdirc.actions.ActionManager;
import com.dmdirc.actions.interfaces.ActionType;
import com.dmdirc.actions.CoreActionType;
import com.dmdirc.commandparser.CommandManager;
import com.dmdirc.config.IdentityManager;
import com.dmdirc.config.prefs.PreferencesCategory;
import com.dmdirc.config.prefs.PreferencesManager;
import com.dmdirc.interfaces.ActionListener;
import com.dmdirc.plugins.Plugin;
import com.dmdirc.plugins.PluginInfo;
import com.dmdirc.plugins.PluginManager;

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

/**
 * Plugin that allows users to advertise what they're currently playing or
 * listening to.
 * 
 * @author chris
 */
public class NowPlayingPlugin extends Plugin implements ActionListener  {
    
    /** The sources that we know of. */
    private final List<MediaSource> sources = new ArrayList<MediaSource>();

    /** The managers that we know of. */
    private final List<MediaSourceManager> managers = new ArrayList<MediaSourceManager>();
    
    /** The now playing command we're registering. */
    private NowPlayingCommand command;
    
    /** The user's preferred order for source usage. */
    private List<String> order;
    
    /**
     * Creates a new instance of NowPlayingPlugin.
     */
    public NowPlayingPlugin() {
        super();
    //#NowPlayingPlugin.java:65: method: void com.dmdirc.addons.nowplaying.NowPlayingPlugin.com.dmdirc.addons.nowplaying.NowPlayingPlugin()
    //#NowPlayingPlugin.java:65: Warning: method not available - call not analyzed
    //#    call on void com.dmdirc.plugins.Plugin()
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.nowplaying.NowPlayingPlugin
    //#    method: void com.dmdirc.addons.nowplaying.NowPlayingPlugin()
    //#    unanalyzed callee: void com.dmdirc.plugins.Plugin()
    //#input(void com.dmdirc.addons.nowplaying.NowPlayingPlugin()): this
    //#output(void com.dmdirc.addons.nowplaying.NowPlayingPlugin()): new ArrayList(NowPlayingPlugin#1) num objects
    //#output(void com.dmdirc.addons.nowplaying.NowPlayingPlugin()): new ArrayList(NowPlayingPlugin#2) num objects
    //#output(void com.dmdirc.addons.nowplaying.NowPlayingPlugin()): this.managers
    //#output(void com.dmdirc.addons.nowplaying.NowPlayingPlugin()): this.sources
    //#new obj(void com.dmdirc.addons.nowplaying.NowPlayingPlugin()): new ArrayList(NowPlayingPlugin#1)
    //#new obj(void com.dmdirc.addons.nowplaying.NowPlayingPlugin()): new ArrayList(NowPlayingPlugin#2)
    //#post(void com.dmdirc.addons.nowplaying.NowPlayingPlugin()): this.managers == &new ArrayList(NowPlayingPlugin#2)
    //#post(void com.dmdirc.addons.nowplaying.NowPlayingPlugin()): this.sources == &new ArrayList(NowPlayingPlugin#1)
    //#post(void com.dmdirc.addons.nowplaying.NowPlayingPlugin()): new ArrayList(NowPlayingPlugin#1) num objects == 1
    //#post(void com.dmdirc.addons.nowplaying.NowPlayingPlugin()): new ArrayList(NowPlayingPlugin#2) num objects == 1
    }
    //#NowPlayingPlugin.java:66: end of method: void com.dmdirc.addons.nowplaying.NowPlayingPlugin.com.dmdirc.addons.nowplaying.NowPlayingPlugin()
    
    /** {@inheritDoc} */
    @Override
    public void onLoad() {
        sources.clear();
    //#NowPlayingPlugin.java:71: method: void com.dmdirc.addons.nowplaying.NowPlayingPlugin.onLoad()
    //#input(void onLoad()): com.dmdirc.actions.CoreActionType.PLUGIN_LOADED
    //#input(void onLoad()): com.dmdirc.actions.CoreActionType.PLUGIN_UNLOADED
    //#input(void onLoad()): com/dmdirc/addons/mediasource_dcop/AmarokSource.__Dispatch_Table.getAppName()Ljava/lang/String;
    //#input(void onLoad()): com/dmdirc/addons/mediasource_dcop/DcopMediaSourcePlugin.__Dispatch_Table.getSources()Ljava/util/List;
    //#input(void onLoad()): com/dmdirc/addons/mediasource_dcop/KaffeineSource.__Dispatch_Table.getAppName()Ljava/lang/String;
    //#input(void onLoad()): com/dmdirc/addons/mediasource_dcop/NoatunSource.__Dispatch_Table.getAppName()Ljava/lang/String;
    //#input(void onLoad()): com/dmdirc/addons/mediasource_vlc/VlcMediaSourcePlugin.__Dispatch_Table.getAppName()Ljava/lang/String;
    //#input(void onLoad()): com/dmdirc/addons/mediasource_windows/DllSource.__Dispatch_Table.getAppName()Ljava/lang/String;
    //#input(void onLoad()): com/dmdirc/addons/mediasource_windows/WindowsMediaSourcePlugin.__Dispatch_Table.getSources()Ljava/util/List;
    //#input(void onLoad()): com/dmdirc/addons/nowplaying/ConfigPanel$DummyMediaSource.__Dispatch_Table.getAppName()Ljava/lang/String;
    //#input(void onLoad()): com/dmdirc/addons/nowplaying/MediaSource.__Descendant_Table[com/dmdirc/addons/mediasource_dcop/AmarokSource]
    //#input(void onLoad()): com/dmdirc/addons/nowplaying/MediaSource.__Descendant_Table[com/dmdirc/addons/mediasource_dcop/KaffeineSource]
    //#input(void onLoad()): com/dmdirc/addons/nowplaying/MediaSource.__Descendant_Table[com/dmdirc/addons/mediasource_dcop/NoatunSource]
    //#input(void onLoad()): com/dmdirc/addons/nowplaying/MediaSource.__Descendant_Table[com/dmdirc/addons/mediasource_vlc/VlcMediaSourcePlugin]
    //#input(void onLoad()): com/dmdirc/addons/nowplaying/MediaSource.__Descendant_Table[com/dmdirc/addons/mediasource_windows/DllSource]
    //#input(void onLoad()): com/dmdirc/addons/nowplaying/MediaSource.__Descendant_Table[com/dmdirc/addons/nowplaying/ConfigPanel$DummyMediaSource]
    //#input(void onLoad()): com/dmdirc/addons/nowplaying/MediaSource.__Descendant_Table[com/dmdirc/addons/nowplaying/MediaSource]
    //#input(void onLoad()): com/dmdirc/addons/nowplaying/MediaSource.__Descendant_Table[others]
    //#input(void onLoad()): com/dmdirc/addons/nowplaying/MediaSource.__Dispatch_Table.getAppName()Ljava/lang/String;
    //#input(void onLoad()): com/dmdirc/addons/nowplaying/MediaSourceManager.__Descendant_Table[com/dmdirc/addons/mediasource_dcop/DcopMediaSourcePlugin]
    //#input(void onLoad()): com/dmdirc/addons/nowplaying/MediaSourceManager.__Descendant_Table[com/dmdirc/addons/mediasource_windows/WindowsMediaSourcePlugin]
    //#input(void onLoad()): com/dmdirc/addons/nowplaying/MediaSourceManager.__Descendant_Table[com/dmdirc/addons/nowplaying/MediaSourceManager]
    //#input(void onLoad()): com/dmdirc/addons/nowplaying/MediaSourceManager.__Descendant_Table[others]
    //#input(void onLoad()): com/dmdirc/addons/nowplaying/MediaSourceManager.__Dispatch_Table.getSources()Ljava/util/List;
    //#input(void onLoad()): this
    //#input(void onLoad()): this.managers
    //#input(void onLoad()): this.sources
    //#output(void onLoad()): new ArrayList(loadSettings#1) num objects
    //#output(void onLoad()): new NowPlayingCommand(onLoad#2) num objects
    //#output(void onLoad()): this.command.__Tag
    //#output(void onLoad()): this.command.parent
    //#output(void onLoad()): this.command
    //#output(void onLoad()): this.order
    //#new obj(void onLoad()): new ArrayList(loadSettings#1)
    //#new obj(void onLoad()): new NowPlayingCommand(onLoad#2)
    //#pre[2] (void onLoad()): this.managers != null
    //#pre[3] (void onLoad()): this.sources != null
    //#presumption(void onLoad()): init'ed(com.dmdirc.actions.CoreActionType.PLUGIN_LOADED)
    //#presumption(void onLoad()): init'ed(com.dmdirc.actions.CoreActionType.PLUGIN_UNLOADED)
    //#presumption(void onLoad()): com.dmdirc.plugins.PluginManager:getPluginInfos(...)@79 != null
    //#presumption(void onLoad()): com.dmdirc.plugins.PluginManager:getPluginManager(...)@79 != null
    //#presumption(void onLoad()): java.util.Iterator:next(...)@79 != null
    //#post(void onLoad()): this.command == &new NowPlayingCommand(onLoad#2)
    //#post(void onLoad()): init'ed(this.order)
    //#post(void onLoad()): new ArrayList(loadSettings#1) num objects <= 1
    //#post(void onLoad()): new NowPlayingCommand(onLoad#2) num objects == 1
    //#post(void onLoad()): this.command.__Tag == com/dmdirc/addons/nowplaying/NowPlayingCommand
    //#post(void onLoad()): this.command.parent == this
    //#post(void onLoad()): this.command.parent != null
    //#unanalyzed(void onLoad()): Effects-of-calling:java.util.ArrayList
    //#unanalyzed(void onLoad()): Effects-of-calling:com.dmdirc.config.IdentityManager:getGlobalConfig
    //#unanalyzed(void onLoad()): Effects-of-calling:com.dmdirc.addons.nowplaying.NowPlayingPlugin:getDomain
    //#unanalyzed(void onLoad()): Effects-of-calling:com.dmdirc.config.ConfigManager:hasOptionString
    //#unanalyzed(void onLoad()): Effects-of-calling:com.dmdirc.config.ConfigManager:getOptionList
    //#unanalyzed(void onLoad()): Effects-of-calling:com.dmdirc.plugins.PluginInfo:getPlugin
    //#unanalyzed(void onLoad()): Effects-of-calling:java.util.List:iterator
    //#unanalyzed(void onLoad()): Effects-of-calling:java.util.Iterator:hasNext
    //#unanalyzed(void onLoad()): Effects-of-calling:java.util.Iterator:next
    //#unanalyzed(void onLoad()): Effects-of-calling:getSources
    //#unanalyzed(void onLoad()): Effects-of-calling:getAppName
    //#unanalyzed(void onLoad()): Effects-of-calling:java.util.List:contains
    //#unanalyzed(void onLoad()): Effects-of-calling:java.util.List:add
    //#unanalyzed(void onLoad()): Effects-of-calling:com.dmdirc.commandparser.commands.ChatCommand
    //#unanalyzed(void onLoad()): Effects-of-calling:com.dmdirc.commandparser.CommandManager:registerCommand
    //#test_vector(void onLoad()): com.dmdirc.plugins.PluginInfo:isLoaded(...)@80: {0}, {1}
    //#test_vector(void onLoad()): java.util.Iterator:hasNext(...)@79: {0}, {1}
        managers.clear();
        
        loadSettings();
        
        ActionManager.addListener(this, CoreActionType.PLUGIN_LOADED,
    //#NowPlayingPlugin.java:76: Warning: method not available - call not analyzed
    //#    call on void com.dmdirc.actions.ActionManager:addListener(ActionListener, ActionType[])
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.nowplaying.NowPlayingPlugin
    //#    method: void onLoad()
    //#    unanalyzed callee: void com.dmdirc.actions.ActionManager:addListener(ActionListener, ActionType[])
                CoreActionType.PLUGIN_UNLOADED);
        
        for (PluginInfo target : PluginManager.getPluginManager().getPluginInfos()) {
    //#NowPlayingPlugin.java:79: Warning: method not available - call not analyzed
    //#    call on PluginManager com.dmdirc.plugins.PluginManager:getPluginManager()
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.nowplaying.NowPlayingPlugin
    //#    method: void onLoad()
    //#    unanalyzed callee: PluginManager com.dmdirc.plugins.PluginManager:getPluginManager()
    //#NowPlayingPlugin.java:79: Warning: method not available - call not analyzed
    //#    call on Collection com.dmdirc.plugins.PluginManager:getPluginInfos()
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.nowplaying.NowPlayingPlugin
    //#    method: void onLoad()
    //#    unanalyzed callee: Collection com.dmdirc.plugins.PluginManager:getPluginInfos()
            if (target.isLoaded()) {
    //#NowPlayingPlugin.java:80: Warning: method not available - call not analyzed
    //#    call on bool com.dmdirc.plugins.PluginInfo:isLoaded()
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.nowplaying.NowPlayingPlugin
    //#    method: void onLoad()
    //#    unanalyzed callee: bool com.dmdirc.plugins.PluginInfo:isLoaded()
                addPlugin(target);
    //#NowPlayingPlugin.java:81: ?precondition failure
    //#    com/dmdirc/addons/nowplaying/NowPlayingPlugin.addPlugin: (soft) this.order != null
    //#    severity: SUPPRESSED
    //#    class: com.dmdirc.addons.nowplaying.NowPlayingPlugin
    //#    method: void onLoad()
    //#    basic block: bb_4
    //#    assertion: (soft) this.order != null
    //#    callee: void com/dmdirc/addons/nowplaying/NowPlayingPlugin.addPlugin(PluginInfo)
    //#    callee assertion: (soft) this.order != null
    //#    callee file: NowPlayingPlugin.java
    //#    callee precondition index: [4]
    //#    callee srcpos: 146
    //#    VN: this.order
    //#    Expected: Inverse{null}
    //#    Bad: Addr_Set{null}
    //#    Attribs:  Ptr  null in Bad  Soft
            }
        }
        
        command = new NowPlayingCommand(this);
    }
    //#NowPlayingPlugin.java:86: end of method: void com.dmdirc.addons.nowplaying.NowPlayingPlugin.onLoad()
    
    /** {@inheritDoc} */
    @Override
    public void onUnload() {
        sources.clear();
    //#NowPlayingPlugin.java:91: method: void com.dmdirc.addons.nowplaying.NowPlayingPlugin.onUnload()
    //#input(void onUnload()): this
    //#input(void onUnload()): this.command
    //#input(void onUnload()): this.managers
    //#input(void onUnload()): this.sources
    //#pre[2] (void onUnload()): init'ed(this.command)
    //#pre[3] (void onUnload()): this.managers != null
    //#pre[4] (void onUnload()): this.sources != null
        managers.clear();
        
        ActionManager.removeListener(this);
    //#NowPlayingPlugin.java:94: Warning: method not available - call not analyzed
    //#    call on void com.dmdirc.actions.ActionManager:removeListener(ActionListener)
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.nowplaying.NowPlayingPlugin
    //#    method: void onUnload()
    //#    unanalyzed callee: void com.dmdirc.actions.ActionManager:removeListener(ActionListener)
        
        CommandManager.unregisterCommand(command);
    //#NowPlayingPlugin.java:96: Warning: method not available - call not analyzed
    //#    call on void com.dmdirc.commandparser.CommandManager:unregisterCommand(CommandInfo)
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.nowplaying.NowPlayingPlugin
    //#    method: void onUnload()
    //#    unanalyzed callee: void com.dmdirc.commandparser.CommandManager:unregisterCommand(CommandInfo)
    }
    //#NowPlayingPlugin.java:97: end of method: void com.dmdirc.addons.nowplaying.NowPlayingPlugin.onUnload()
    
    /** {@inheritDoc} */
    @Override
    public void showConfig(final PreferencesManager manager) {
        final ConfigPanel configPanel = new ConfigPanel(this, order);
    //#NowPlayingPlugin.java:102: method: void com.dmdirc.addons.nowplaying.NowPlayingPlugin.showConfig(PreferencesManager)
    //#input(void showConfig(PreferencesManager)): com/dmdirc/addons/nowplaying/NowPlayingSubsitutionPanel.com.dmdirc.addons.ui_swing.components.substitutions.SubstitutionsPanel$Alignment.HORIZONTAL
    //#input(void showConfig(PreferencesManager)): manager
    //#input(void showConfig(PreferencesManager)): this
    //#input(void showConfig(PreferencesManager)): this.order
    //#pre[1] (void showConfig(PreferencesManager)): manager != null
    //#pre[3] (void showConfig(PreferencesManager)): init'ed(this.order)
    //#presumption(void showConfig(PreferencesManager)): com.dmdirc.config.prefs.PreferencesManager:getCategory(...)@106 != null
    //#unanalyzed(void showConfig(PreferencesManager)): Effects-of-calling:java.util.Timer:cancel
    //#unanalyzed(void showConfig(PreferencesManager)): Effects-of-calling:java.util.Timer
    //#unanalyzed(void showConfig(PreferencesManager)): Effects-of-calling:java.util.TimerTask
    //#unanalyzed(void showConfig(PreferencesManager)): Effects-of-calling:java.util.Timer:schedule
    //#unanalyzed(void showConfig(PreferencesManager)): Effects-of-calling:com.dmdirc.addons.ui_swing.components.reorderablelist.ReorderableJList
    //#unanalyzed(void showConfig(PreferencesManager)): Effects-of-calling:java.util.List:iterator
    //#unanalyzed(void showConfig(PreferencesManager)): Effects-of-calling:java.util.Iterator:hasNext
    //#unanalyzed(void showConfig(PreferencesManager)): Effects-of-calling:java.util.Iterator:next
    //#unanalyzed(void showConfig(PreferencesManager)): Effects-of-calling:com.dmdirc.addons.ui_swing.components.reorderablelist.ReorderableJList:getModel
    //#unanalyzed(void showConfig(PreferencesManager)): Effects-of-calling:javax.swing.DefaultListModel:addElement
    //#unanalyzed(void showConfig(PreferencesManager)): Effects-of-calling:com.dmdirc.config.IdentityManager:getGlobalConfig
    //#unanalyzed(void showConfig(PreferencesManager)): Effects-of-calling:com.dmdirc.addons.nowplaying.NowPlayingPlugin:getDomain
    //#unanalyzed(void showConfig(PreferencesManager)): Effects-of-calling:com.dmdirc.config.ConfigManager:getOption
    //#unanalyzed(void showConfig(PreferencesManager)): Effects-of-calling:javax.swing.JTextField
    //#unanalyzed(void showConfig(PreferencesManager)): Effects-of-calling:javax.swing.JTextField:addKeyListener
    //#unanalyzed(void showConfig(PreferencesManager)): Effects-of-calling:com.dmdirc.addons.ui_swing.components.text.TextLabel
    //#unanalyzed(void showConfig(PreferencesManager)): Effects-of-calling:net.miginfocom.swing.MigLayout
    //#unanalyzed(void showConfig(PreferencesManager)): Effects-of-calling:com.dmdirc.addons.nowplaying.ConfigPanel:setLayout
    //#unanalyzed(void showConfig(PreferencesManager)): Effects-of-calling:javax.swing.JPanel
    //#unanalyzed(void showConfig(PreferencesManager)): Effects-of-calling:javax.swing.BorderFactory:createTitledBorder
    //#unanalyzed(void showConfig(PreferencesManager)): Effects-of-calling:javax.swing.JPanel:setBorder
    //#unanalyzed(void showConfig(PreferencesManager)): Effects-of-calling:javax.swing.JPanel:setLayout
    //#unanalyzed(void showConfig(PreferencesManager)): Effects-of-calling:javax.swing.JLabel
    //#unanalyzed(void showConfig(PreferencesManager)): Effects-of-calling:javax.swing.JPanel:add
    //#unanalyzed(void showConfig(PreferencesManager)): Effects-of-calling:javax.swing.JScrollPane
    //#unanalyzed(void showConfig(PreferencesManager)): Effects-of-calling:com.dmdirc.addons.nowplaying.ConfigPanel:add
    //#unanalyzed(void showConfig(PreferencesManager)): Effects-of-calling:java.util.Arrays:asList
    //#unanalyzed(void showConfig(PreferencesManager)): Effects-of-calling:com.dmdirc.addons.ui_swing.components.substitutions.SubstitutionsPanel
    //#unanalyzed(void showConfig(PreferencesManager)): Effects-of-calling:java.util.LinkedList
        
        final PreferencesCategory category = new PreferencesCategory("Now Playing",
    //#NowPlayingPlugin.java:104: Warning: method not available - call not analyzed
    //#    call on void com.dmdirc.config.prefs.PreferencesCategory(String, String, String, PreferencesInterface)
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.nowplaying.NowPlayingPlugin
    //#    method: void showConfig(PreferencesManager)
    //#    unanalyzed callee: void com.dmdirc.config.prefs.PreferencesCategory(String, String, String, PreferencesInterface)
                "", "category-nowplaying", configPanel);
        manager.getCategory("Plugins").addSubCategory(category);
    //#NowPlayingPlugin.java:106: Warning: method not available - call not analyzed
    //#    call on PreferencesCategory com.dmdirc.config.prefs.PreferencesManager:getCategory(String)
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.nowplaying.NowPlayingPlugin
    //#    method: void showConfig(PreferencesManager)
    //#    unanalyzed callee: PreferencesCategory com.dmdirc.config.prefs.PreferencesManager:getCategory(String)
    //#NowPlayingPlugin.java:106: Warning: method not available - call not analyzed
    //#    call on void com.dmdirc.config.prefs.PreferencesCategory:addSubCategory(PreferencesCategory)
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.nowplaying.NowPlayingPlugin
    //#    method: void showConfig(PreferencesManager)
    //#    unanalyzed callee: void com.dmdirc.config.prefs.PreferencesCategory:addSubCategory(PreferencesCategory)
    }
    //#NowPlayingPlugin.java:107: end of method: void com.dmdirc.addons.nowplaying.NowPlayingPlugin.showConfig(PreferencesManager)
    
    /**
     * Saves the plugins settings.
     * 
     * @param newOrder The new order for sources
     */
    protected void saveSettings(final List<String> newOrder) {
        order = newOrder;
    //#NowPlayingPlugin.java:115: method: void com.dmdirc.addons.nowplaying.NowPlayingPlugin.saveSettings(List)
    //#input(void saveSettings(List)): newOrder
    //#input(void saveSettings(List)): this
    //#output(void saveSettings(List)): this.order
    //#presumption(void saveSettings(List)): com.dmdirc.config.IdentityManager:getConfigIdentity(...)@116 != null
    //#post(void saveSettings(List)): this.order == newOrder
    //#post(void saveSettings(List)): init'ed(this.order)
        IdentityManager.getConfigIdentity().setOption(getDomain(), "sourceOrder", order);
    //#NowPlayingPlugin.java:116: Warning: method not available - call not analyzed
    //#    call on Identity com.dmdirc.config.IdentityManager:getConfigIdentity()
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.nowplaying.NowPlayingPlugin
    //#    method: void saveSettings(List)
    //#    unanalyzed callee: Identity com.dmdirc.config.IdentityManager:getConfigIdentity()
    //#NowPlayingPlugin.java:116: Warning: method not available - call not analyzed
    //#    call on String com.dmdirc.addons.nowplaying.NowPlayingPlugin:getDomain()
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.nowplaying.NowPlayingPlugin
    //#    method: void saveSettings(List)
    //#    unanalyzed callee: String com.dmdirc.addons.nowplaying.NowPlayingPlugin:getDomain()
    //#NowPlayingPlugin.java:116: Warning: method not available - call not analyzed
    //#    call on void com.dmdirc.config.Identity:setOption(String, String, List)
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.nowplaying.NowPlayingPlugin
    //#    method: void saveSettings(List)
    //#    unanalyzed callee: void com.dmdirc.config.Identity:setOption(String, String, List)
    }
    //#NowPlayingPlugin.java:117: end of method: void com.dmdirc.addons.nowplaying.NowPlayingPlugin.saveSettings(List)
    
    /** Loads the plugins settings. */
    private void loadSettings() {
        if (IdentityManager.getGlobalConfig().hasOptionString(getDomain(), "sourceOrder")) {
    //#NowPlayingPlugin.java:121: method: void com.dmdirc.addons.nowplaying.NowPlayingPlugin.loadSettings()
    //#NowPlayingPlugin.java:121: Warning: method not available - call not analyzed
    //#    call on ConfigManager com.dmdirc.config.IdentityManager:getGlobalConfig()
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.nowplaying.NowPlayingPlugin
    //#    method: void loadSettings()
    //#    unanalyzed callee: ConfigManager com.dmdirc.config.IdentityManager:getGlobalConfig()
    //#NowPlayingPlugin.java:121: Warning: method not available - call not analyzed
    //#    call on String com.dmdirc.addons.nowplaying.NowPlayingPlugin:getDomain()
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.nowplaying.NowPlayingPlugin
    //#    method: void loadSettings()
    //#    unanalyzed callee: String com.dmdirc.addons.nowplaying.NowPlayingPlugin:getDomain()
    //#NowPlayingPlugin.java:121: Warning: method not available - call not analyzed
    //#    call on bool com.dmdirc.config.ConfigManager:hasOptionString(String, String)
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.nowplaying.NowPlayingPlugin
    //#    method: void loadSettings()
    //#    unanalyzed callee: bool com.dmdirc.config.ConfigManager:hasOptionString(String, String)
    //#input(void loadSettings()): this
    //#output(void loadSettings()): new ArrayList(loadSettings#1) num objects
    //#output(void loadSettings()): this.order
    //#new obj(void loadSettings()): new ArrayList(loadSettings#1)
    //#presumption(void loadSettings()): com.dmdirc.config.IdentityManager:getGlobalConfig(...)@121 != null
    //#presumption(void loadSettings()): com.dmdirc.config.IdentityManager:getGlobalConfig(...)@122 != null
    //#post(void loadSettings()): init'ed(this.order)
    //#post(void loadSettings()): new ArrayList(loadSettings#1) num objects <= 1
    //#test_vector(void loadSettings()): com.dmdirc.config.ConfigManager:hasOptionString(...)@121: {0}, {1}
            order = IdentityManager.getGlobalConfig().getOptionList(getDomain(), "sourceOrder");
    //#NowPlayingPlugin.java:122: Warning: method not available - call not analyzed
    //#    call on ConfigManager com.dmdirc.config.IdentityManager:getGlobalConfig()
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.nowplaying.NowPlayingPlugin
    //#    method: void loadSettings()
    //#    unanalyzed callee: ConfigManager com.dmdirc.config.IdentityManager:getGlobalConfig()
    //#NowPlayingPlugin.java:122: Warning: method not available - call not analyzed
    //#    call on String com.dmdirc.addons.nowplaying.NowPlayingPlugin:getDomain()
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.nowplaying.NowPlayingPlugin
    //#    method: void loadSettings()
    //#    unanalyzed callee: String com.dmdirc.addons.nowplaying.NowPlayingPlugin:getDomain()
    //#NowPlayingPlugin.java:122: Warning: method not available - call not analyzed
    //#    call on List com.dmdirc.config.ConfigManager:getOptionList(String, String)
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.nowplaying.NowPlayingPlugin
    //#    method: void loadSettings()
    //#    unanalyzed callee: List com.dmdirc.config.ConfigManager:getOptionList(String, String)
        } else {
            order = new ArrayList<String>();
        }
    }
    //#NowPlayingPlugin.java:126: end of method: void com.dmdirc.addons.nowplaying.NowPlayingPlugin.loadSettings()
    
    /** {@inheritDoc} */
    @Override
    public void processEvent(final ActionType type, final StringBuffer format,
            final Object... arguments) {
        if (type == CoreActionType.PLUGIN_LOADED) {
    //#NowPlayingPlugin.java:132: method: void com.dmdirc.addons.nowplaying.NowPlayingPlugin.processEvent(ActionType, StringBuffer, Object[])
    //#input(void processEvent(ActionType, StringBuffer, Object[])): arguments
    //#input(void processEvent(ActionType, StringBuffer, Object[])): arguments.length
    //#input(void processEvent(ActionType, StringBuffer, Object[])): arguments[0]
    //#input(void processEvent(ActionType, StringBuffer, Object[])): com.dmdirc.actions.CoreActionType.PLUGIN_LOADED
    //#input(void processEvent(ActionType, StringBuffer, Object[])): com.dmdirc.actions.CoreActionType.PLUGIN_UNLOADED
    //#input(void processEvent(ActionType, StringBuffer, Object[])): com/dmdirc/addons/mediasource_dcop/AmarokSource.__Dispatch_Table.getAppName()Ljava/lang/String;
    //#input(void processEvent(ActionType, StringBuffer, Object[])): com/dmdirc/addons/mediasource_dcop/DcopMediaSourcePlugin.__Dispatch_Table.getSources()Ljava/util/List;
    //#input(void processEvent(ActionType, StringBuffer, Object[])): com/dmdirc/addons/mediasource_dcop/KaffeineSource.__Dispatch_Table.getAppName()Ljava/lang/String;
    //#input(void processEvent(ActionType, StringBuffer, Object[])): com/dmdirc/addons/mediasource_dcop/NoatunSource.__Dispatch_Table.getAppName()Ljava/lang/String;
    //#input(void processEvent(ActionType, StringBuffer, Object[])): com/dmdirc/addons/mediasource_vlc/VlcMediaSourcePlugin.__Dispatch_Table.getAppName()Ljava/lang/String;
    //#input(void processEvent(ActionType, StringBuffer, Object[])): com/dmdirc/addons/mediasource_windows/DllSource.__Dispatch_Table.getAppName()Ljava/lang/String;
    //#input(void processEvent(ActionType, StringBuffer, Object[])): com/dmdirc/addons/mediasource_windows/WindowsMediaSourcePlugin.__Dispatch_Table.getSources()Ljava/util/List;
    //#input(void processEvent(ActionType, StringBuffer, Object[])): com/dmdirc/addons/nowplaying/ConfigPanel$DummyMediaSource.__Dispatch_Table.getAppName()Ljava/lang/String;
    //#input(void processEvent(ActionType, StringBuffer, Object[])): com/dmdirc/addons/nowplaying/MediaSource.__Descendant_Table[com/dmdirc/addons/mediasource_dcop/AmarokSource]
    //#input(void processEvent(ActionType, StringBuffer, Object[])): com/dmdirc/addons/nowplaying/MediaSource.__Descendant_Table[com/dmdirc/addons/mediasource_dcop/KaffeineSource]
    //#input(void processEvent(ActionType, StringBuffer, Object[])): com/dmdirc/addons/nowplaying/MediaSource.__Descendant_Table[com/dmdirc/addons/mediasource_dcop/NoatunSource]
    //#input(void processEvent(ActionType, StringBuffer, Object[])): com/dmdirc/addons/nowplaying/MediaSource.__Descendant_Table[com/dmdirc/addons/mediasource_vlc/VlcMediaSourcePlugin]
    //#input(void processEvent(ActionType, StringBuffer, Object[])): com/dmdirc/addons/nowplaying/MediaSource.__Descendant_Table[com/dmdirc/addons/mediasource_windows/DllSource]
    //#input(void processEvent(ActionType, StringBuffer, Object[])): com/dmdirc/addons/nowplaying/MediaSource.__Descendant_Table[com/dmdirc/addons/nowplaying/ConfigPanel$DummyMediaSource]
    //#input(void processEvent(ActionType, StringBuffer, Object[])): com/dmdirc/addons/nowplaying/MediaSource.__Descendant_Table[com/dmdirc/addons/nowplaying/MediaSource]
    //#input(void processEvent(ActionType, StringBuffer, Object[])): com/dmdirc/addons/nowplaying/MediaSource.__Descendant_Table[others]
    //#input(void processEvent(ActionType, StringBuffer, Object[])): com/dmdirc/addons/nowplaying/MediaSource.__Dispatch_Table.getAppName()Ljava/lang/String;
    //#input(void processEvent(ActionType, StringBuffer, Object[])): com/dmdirc/addons/nowplaying/MediaSourceManager.__Descendant_Table[com/dmdirc/addons/mediasource_dcop/DcopMediaSourcePlugin]
    //#input(void processEvent(ActionType, StringBuffer, Object[])): com/dmdirc/addons/nowplaying/MediaSourceManager.__Descendant_Table[com/dmdirc/addons/mediasource_windows/WindowsMediaSourcePlugin]
    //#input(void processEvent(ActionType, StringBuffer, Object[])): com/dmdirc/addons/nowplaying/MediaSourceManager.__Descendant_Table[com/dmdirc/addons/nowplaying/MediaSourceManager]
    //#input(void processEvent(ActionType, StringBuffer, Object[])): com/dmdirc/addons/nowplaying/MediaSourceManager.__Descendant_Table[others]
    //#input(void processEvent(ActionType, StringBuffer, Object[])): com/dmdirc/addons/nowplaying/MediaSourceManager.__Dispatch_Table.getSources()Ljava/util/List;
    //#input(void processEvent(ActionType, StringBuffer, Object[])): this
    //#input(void processEvent(ActionType, StringBuffer, Object[])): this.managers
    //#input(void processEvent(ActionType, StringBuffer, Object[])): this.order
    //#input(void processEvent(ActionType, StringBuffer, Object[])): this.sources
    //#input(void processEvent(ActionType, StringBuffer, Object[])): type
    //#pre[1] (void processEvent(ActionType, StringBuffer, Object[])): (soft) arguments != null
    //#pre[2] (void processEvent(ActionType, StringBuffer, Object[])): (soft) arguments.length >= 1
    //#pre[3] (void processEvent(ActionType, StringBuffer, Object[])): (soft) arguments[0] != null
    //#pre[5] (void processEvent(ActionType, StringBuffer, Object[])): (soft) this.managers != null
    //#pre[6] (void processEvent(ActionType, StringBuffer, Object[])): (soft) this.order != null
    //#pre[7] (void processEvent(ActionType, StringBuffer, Object[])): (soft) this.sources != null
    //#presumption(void processEvent(ActionType, StringBuffer, Object[])): init'ed(com.dmdirc.actions.CoreActionType.PLUGIN_LOADED)
    //#presumption(void processEvent(ActionType, StringBuffer, Object[])): init'ed(com.dmdirc.actions.CoreActionType.PLUGIN_UNLOADED)
    //#unanalyzed(void processEvent(ActionType, StringBuffer, Object[])): Effects-of-calling:com.dmdirc.plugins.PluginInfo:getPlugin
    //#unanalyzed(void processEvent(ActionType, StringBuffer, Object[])): Effects-of-calling:java.util.List:remove
    //#unanalyzed(void processEvent(ActionType, StringBuffer, Object[])): Effects-of-calling:java.util.List:iterator
    //#unanalyzed(void processEvent(ActionType, StringBuffer, Object[])): Effects-of-calling:java.util.Iterator:hasNext
    //#unanalyzed(void processEvent(ActionType, StringBuffer, Object[])): Effects-of-calling:java.util.Iterator:next
    //#unanalyzed(void processEvent(ActionType, StringBuffer, Object[])): Effects-of-calling:getSources
    //#unanalyzed(void processEvent(ActionType, StringBuffer, Object[])): Effects-of-calling:getAppName
    //#unanalyzed(void processEvent(ActionType, StringBuffer, Object[])): Effects-of-calling:java.util.List:contains
    //#unanalyzed(void processEvent(ActionType, StringBuffer, Object[])): Effects-of-calling:java.util.List:add
            addPlugin((PluginInfo) arguments[0]);
        } else if (type == CoreActionType.PLUGIN_UNLOADED) {
            removePlugin((PluginInfo) arguments[0]);
        }
    }
    //#NowPlayingPlugin.java:137: end of method: void com.dmdirc.addons.nowplaying.NowPlayingPlugin.processEvent(ActionType, StringBuffer, Object[])
    
    /**
     * Checks to see if a plugin implements one of the Media Source interfaces
     * and if it does, adds the source(s) to our list.
     *
     * @param target The plugin to be tested
     */
    private void addPlugin(final PluginInfo target) {
        final Plugin targetPlugin = target.getPlugin();
    //#NowPlayingPlugin.java:146: method: void com.dmdirc.addons.nowplaying.NowPlayingPlugin.addPlugin(PluginInfo)
    //#NowPlayingPlugin.java:146: Warning: method not available - call not analyzed
    //#    call on Plugin com.dmdirc.plugins.PluginInfo:getPlugin()
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.nowplaying.NowPlayingPlugin
    //#    method: void addPlugin(PluginInfo)
    //#    unanalyzed callee: Plugin com.dmdirc.plugins.PluginInfo:getPlugin()
    //#input(void addPlugin(PluginInfo)): com/dmdirc/addons/mediasource_dcop/AmarokSource.__Dispatch_Table.getAppName()Ljava/lang/String;
    //#input(void addPlugin(PluginInfo)): com/dmdirc/addons/mediasource_dcop/DcopMediaSourcePlugin.__Dispatch_Table.getSources()Ljava/util/List;
    //#input(void addPlugin(PluginInfo)): com/dmdirc/addons/mediasource_dcop/KaffeineSource.__Dispatch_Table.getAppName()Ljava/lang/String;
    //#input(void addPlugin(PluginInfo)): com/dmdirc/addons/mediasource_dcop/NoatunSource.__Dispatch_Table.getAppName()Ljava/lang/String;
    //#input(void addPlugin(PluginInfo)): com/dmdirc/addons/mediasource_vlc/VlcMediaSourcePlugin.__Dispatch_Table.getAppName()Ljava/lang/String;
    //#input(void addPlugin(PluginInfo)): com/dmdirc/addons/mediasource_windows/DllSource.__Dispatch_Table.getAppName()Ljava/lang/String;
    //#input(void addPlugin(PluginInfo)): com/dmdirc/addons/mediasource_windows/WindowsMediaSourcePlugin.__Dispatch_Table.getSources()Ljava/util/List;
    //#input(void addPlugin(PluginInfo)): com/dmdirc/addons/nowplaying/ConfigPanel$DummyMediaSource.__Dispatch_Table.getAppName()Ljava/lang/String;
    //#input(void addPlugin(PluginInfo)): com/dmdirc/addons/nowplaying/MediaSource.__Descendant_Table[com/dmdirc/addons/mediasource_dcop/AmarokSource]
    //#input(void addPlugin(PluginInfo)): com/dmdirc/addons/nowplaying/MediaSource.__Descendant_Table[com/dmdirc/addons/mediasource_dcop/KaffeineSource]
    //#input(void addPlugin(PluginInfo)): com/dmdirc/addons/nowplaying/MediaSource.__Descendant_Table[com/dmdirc/addons/mediasource_dcop/NoatunSource]
    //#input(void addPlugin(PluginInfo)): com/dmdirc/addons/nowplaying/MediaSource.__Descendant_Table[com/dmdirc/addons/mediasource_vlc/VlcMediaSourcePlugin]
    //#input(void addPlugin(PluginInfo)): com/dmdirc/addons/nowplaying/MediaSource.__Descendant_Table[com/dmdirc/addons/mediasource_windows/DllSource]
    //#input(void addPlugin(PluginInfo)): com/dmdirc/addons/nowplaying/MediaSource.__Descendant_Table[com/dmdirc/addons/nowplaying/ConfigPanel$DummyMediaSource]
    //#input(void addPlugin(PluginInfo)): com/dmdirc/addons/nowplaying/MediaSource.__Descendant_Table[com/dmdirc/addons/nowplaying/MediaSource]
    //#input(void addPlugin(PluginInfo)): com/dmdirc/addons/nowplaying/MediaSource.__Descendant_Table[others]
    //#input(void addPlugin(PluginInfo)): com/dmdirc/addons/nowplaying/MediaSource.__Dispatch_Table.getAppName()Ljava/lang/String;
    //#input(void addPlugin(PluginInfo)): com/dmdirc/addons/nowplaying/MediaSourceManager.__Descendant_Table[com/dmdirc/addons/mediasource_dcop/DcopMediaSourcePlugin]
    //#input(void addPlugin(PluginInfo)): com/dmdirc/addons/nowplaying/MediaSourceManager.__Descendant_Table[com/dmdirc/addons/mediasource_windows/WindowsMediaSourcePlugin]
    //#input(void addPlugin(PluginInfo)): com/dmdirc/addons/nowplaying/MediaSourceManager.__Descendant_Table[com/dmdirc/addons/nowplaying/MediaSourceManager]
    //#input(void addPlugin(PluginInfo)): com/dmdirc/addons/nowplaying/MediaSourceManager.__Descendant_Table[others]
    //#input(void addPlugin(PluginInfo)): com/dmdirc/addons/nowplaying/MediaSourceManager.__Dispatch_Table.getSources()Ljava/util/List;
    //#input(void addPlugin(PluginInfo)): target
    //#input(void addPlugin(PluginInfo)): this
    //#input(void addPlugin(PluginInfo)): this.managers
    //#input(void addPlugin(PluginInfo)): this.order
    //#input(void addPlugin(PluginInfo)): this.sources
    //#pre[1] (void addPlugin(PluginInfo)): target != null
    //#pre[3] (void addPlugin(PluginInfo)): (soft) this.managers != null
    //#pre[4] (void addPlugin(PluginInfo)): (soft) this.order != null
    //#pre[5] (void addPlugin(PluginInfo)): (soft) this.sources != null
    //#presumption(void addPlugin(PluginInfo)): java.util.Iterator:next(...).__Tag@156 in {com/dmdirc/addons/mediasource_dcop/AmarokSource, com/dmdirc/addons/mediasource_dcop/KaffeineSource, com/dmdirc/addons/mediasource_dcop/NoatunSource, com/dmdirc/addons/mediasource_vlc/VlcMediaSourcePlugin, com/dmdirc/addons/mediasource_windows/DllSource, com/dmdirc/addons/nowplaying/ConfigPanel$DummyMediaSource, com/dmdirc/addons/nowplaying/MediaSource}
    //#presumption(void addPlugin(PluginInfo)): java.util.Iterator:next(...)@156 != null
    //#presumption(void addPlugin(PluginInfo)): targetPlugin.sources@146 != null
    //#presumption(void addPlugin(PluginInfo)): targetPlugin.sources@146 != null
    //#unanalyzed(void addPlugin(PluginInfo)): Effects-of-calling:getAppName
    //#unanalyzed(void addPlugin(PluginInfo)): Effects-of-calling:java.util.List:contains
    //#unanalyzed(void addPlugin(PluginInfo)): Effects-of-calling:java.util.List:add
    //#test_vector(void addPlugin(PluginInfo)): java.util.Iterator:hasNext(...)@156: {0}, {1}
    //#test_vector(void addPlugin(PluginInfo)): targetPlugin.__Tag@146: {414_976, 416_256, 416_768, 418_048, 418_560, 423_936, 424_448}, {415_744, 419_840, 425_472}
        if (targetPlugin instanceof MediaSource) {
            sources.add((MediaSource) targetPlugin);
            addSourceToOrder((MediaSource) targetPlugin);
        }
        
        if (targetPlugin instanceof MediaSourceManager) {
            managers.add((MediaSourceManager) targetPlugin);

            if (((MediaSourceManager) targetPlugin).getSources() != null) {
    //#NowPlayingPlugin.java:155: Warning: test always goes same way
    //#    Test predetermined because getSources(...) != null
    //#    severity: LOW
    //#    class: com.dmdirc.addons.nowplaying.NowPlayingPlugin
    //#    method: void addPlugin(PluginInfo)
    //#    from bb: bb_23
    //#    live edge: bb_23-->bb_5
    //#    tested vn: getSources(...) == null
    //#    tested vn values: {0}
                for (MediaSource source : ((MediaSourceManager) targetPlugin).getSources()) {
                    addSourceToOrder(source);
                }
            }
        }
    }
    //#NowPlayingPlugin.java:161: end of method: void com.dmdirc.addons.nowplaying.NowPlayingPlugin.addPlugin(PluginInfo)
    
    /**
     * Checks to see if the specified media source needs to be added to our
     * order list, and adds it if neccessary.
     *
     * @param source The media source to be tested
     */
    private void addSourceToOrder(final MediaSource source) {
        if (!order.contains(source.getAppName())) {
    //#NowPlayingPlugin.java:170: method: void com.dmdirc.addons.nowplaying.NowPlayingPlugin.addSourceToOrder(MediaSource)
    //#NowPlayingPlugin.java:170: Warning: call too complex - analysis skipped
    //#    call on String getAppName()
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.nowplaying.NowPlayingPlugin
    //#    method: void addSourceToOrder(MediaSource)
    //#    unanalyzed callee: String getAppName()
    //#NowPlayingPlugin.java:170: Warning: suspicious precondition
    //#    The precondition for source.__Tag is not a contiguous range of values
    //#    severity: SUPPRESSED
    //#    class: com.dmdirc.addons.nowplaying.NowPlayingPlugin
    //#    method: void addSourceToOrder(MediaSource)
    //#    suspicious precondition index: [2]
    //#input(void addSourceToOrder(MediaSource)): com/dmdirc/addons/mediasource_dcop/AmarokSource.__Dispatch_Table.getAppName()Ljava/lang/String;
    //#input(void addSourceToOrder(MediaSource)): com/dmdirc/addons/mediasource_dcop/KaffeineSource.__Dispatch_Table.getAppName()Ljava/lang/String;
    //#input(void addSourceToOrder(MediaSource)): com/dmdirc/addons/mediasource_dcop/NoatunSource.__Dispatch_Table.getAppName()Ljava/lang/String;
    //#input(void addSourceToOrder(MediaSource)): com/dmdirc/addons/mediasource_vlc/VlcMediaSourcePlugin.__Dispatch_Table.getAppName()Ljava/lang/String;
    //#input(void addSourceToOrder(MediaSource)): com/dmdirc/addons/mediasource_windows/DllSource.__Dispatch_Table.getAppName()Ljava/lang/String;
    //#input(void addSourceToOrder(MediaSource)): com/dmdirc/addons/nowplaying/ConfigPanel$DummyMediaSource.__Dispatch_Table.getAppName()Ljava/lang/String;
    //#input(void addSourceToOrder(MediaSource)): com/dmdirc/addons/nowplaying/MediaSource.__Descendant_Table[com/dmdirc/addons/mediasource_dcop/AmarokSource]
    //#input(void addSourceToOrder(MediaSource)): com/dmdirc/addons/nowplaying/MediaSource.__Descendant_Table[com/dmdirc/addons/mediasource_dcop/KaffeineSource]
    //#input(void addSourceToOrder(MediaSource)): com/dmdirc/addons/nowplaying/MediaSource.__Descendant_Table[com/dmdirc/addons/mediasource_dcop/NoatunSource]
    //#input(void addSourceToOrder(MediaSource)): com/dmdirc/addons/nowplaying/MediaSource.__Descendant_Table[com/dmdirc/addons/mediasource_vlc/VlcMediaSourcePlugin]
    //#input(void addSourceToOrder(MediaSource)): com/dmdirc/addons/nowplaying/MediaSource.__Descendant_Table[com/dmdirc/addons/mediasource_windows/DllSource]
    //#input(void addSourceToOrder(MediaSource)): com/dmdirc/addons/nowplaying/MediaSource.__Descendant_Table[com/dmdirc/addons/nowplaying/ConfigPanel$DummyMediaSource]
    //#input(void addSourceToOrder(MediaSource)): com/dmdirc/addons/nowplaying/MediaSource.__Descendant_Table[com/dmdirc/addons/nowplaying/MediaSource]
    //#input(void addSourceToOrder(MediaSource)): com/dmdirc/addons/nowplaying/MediaSource.__Descendant_Table[others]
    //#input(void addSourceToOrder(MediaSource)): com/dmdirc/addons/nowplaying/MediaSource.__Dispatch_Table.getAppName()Ljava/lang/String;
    //#input(void addSourceToOrder(MediaSource)): source
    //#input(void addSourceToOrder(MediaSource)): source.__Tag
    //#input(void addSourceToOrder(MediaSource)): this
    //#input(void addSourceToOrder(MediaSource)): this.order
    //#pre[1] (void addSourceToOrder(MediaSource)): source != null
    //#pre[2] (void addSourceToOrder(MediaSource)): source.__Tag in {com/dmdirc/addons/mediasource_dcop/AmarokSource, com/dmdirc/addons/mediasource_dcop/KaffeineSource, com/dmdirc/addons/mediasource_dcop/NoatunSource, com/dmdirc/addons/mediasource_vlc/VlcMediaSourcePlugin, com/dmdirc/addons/mediasource_windows/DllSource, com/dmdirc/addons/nowplaying/ConfigPanel$DummyMediaSource, com/dmdirc/addons/nowplaying/MediaSource}
    //#pre[4] (void addSourceToOrder(MediaSource)): this.order != null
    //#test_vector(void addSourceToOrder(MediaSource)): java.util.List:contains(...)@170: {1}, {0}
            order.add(source.getAppName());
    //#NowPlayingPlugin.java:171: Warning: call too complex - analysis skipped
    //#    call on String getAppName()
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.nowplaying.NowPlayingPlugin
    //#    method: void addSourceToOrder(MediaSource)
    //#    unanalyzed callee: String getAppName()
        }
    }
    //#NowPlayingPlugin.java:173: end of method: void com.dmdirc.addons.nowplaying.NowPlayingPlugin.addSourceToOrder(MediaSource)
    
    /**
     * Checks to see if a plugin implements one of the Media Source interfaces
     * and if it does, removes the source(s) from our list.
     *
     * @param target The plugin to be tested
     */
    private void removePlugin(final PluginInfo target) {
        final Plugin targetPlugin = target.getPlugin();
    //#NowPlayingPlugin.java:182: method: void com.dmdirc.addons.nowplaying.NowPlayingPlugin.removePlugin(PluginInfo)
    //#NowPlayingPlugin.java:182: Warning: method not available - call not analyzed
    //#    call on Plugin com.dmdirc.plugins.PluginInfo:getPlugin()
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.nowplaying.NowPlayingPlugin
    //#    method: void removePlugin(PluginInfo)
    //#    unanalyzed callee: Plugin com.dmdirc.plugins.PluginInfo:getPlugin()
    //#input(void removePlugin(PluginInfo)): com/dmdirc/addons/nowplaying/MediaSource.__Descendant_Table[com/dmdirc/addons/mediasource_dcop/AmarokSource]
    //#input(void removePlugin(PluginInfo)): com/dmdirc/addons/nowplaying/MediaSource.__Descendant_Table[com/dmdirc/addons/mediasource_dcop/KaffeineSource]
    //#input(void removePlugin(PluginInfo)): com/dmdirc/addons/nowplaying/MediaSource.__Descendant_Table[com/dmdirc/addons/mediasource_dcop/NoatunSource]
    //#input(void removePlugin(PluginInfo)): com/dmdirc/addons/nowplaying/MediaSource.__Descendant_Table[com/dmdirc/addons/mediasource_vlc/VlcMediaSourcePlugin]
    //#input(void removePlugin(PluginInfo)): com/dmdirc/addons/nowplaying/MediaSource.__Descendant_Table[com/dmdirc/addons/mediasource_windows/DllSource]
    //#input(void removePlugin(PluginInfo)): com/dmdirc/addons/nowplaying/MediaSource.__Descendant_Table[com/dmdirc/addons/nowplaying/ConfigPanel$DummyMediaSource]
    //#input(void removePlugin(PluginInfo)): com/dmdirc/addons/nowplaying/MediaSource.__Descendant_Table[com/dmdirc/addons/nowplaying/MediaSource]
    //#input(void removePlugin(PluginInfo)): com/dmdirc/addons/nowplaying/MediaSource.__Descendant_Table[others]
    //#input(void removePlugin(PluginInfo)): com/dmdirc/addons/nowplaying/MediaSourceManager.__Descendant_Table[com/dmdirc/addons/mediasource_dcop/DcopMediaSourcePlugin]
    //#input(void removePlugin(PluginInfo)): com/dmdirc/addons/nowplaying/MediaSourceManager.__Descendant_Table[com/dmdirc/addons/mediasource_windows/WindowsMediaSourcePlugin]
    //#input(void removePlugin(PluginInfo)): com/dmdirc/addons/nowplaying/MediaSourceManager.__Descendant_Table[com/dmdirc/addons/nowplaying/MediaSourceManager]
    //#input(void removePlugin(PluginInfo)): com/dmdirc/addons/nowplaying/MediaSourceManager.__Descendant_Table[others]
    //#input(void removePlugin(PluginInfo)): target
    //#input(void removePlugin(PluginInfo)): this
    //#input(void removePlugin(PluginInfo)): this.managers
    //#input(void removePlugin(PluginInfo)): this.sources
    //#pre[1] (void removePlugin(PluginInfo)): target != null
    //#pre[3] (void removePlugin(PluginInfo)): (soft) this.managers != null
    //#pre[4] (void removePlugin(PluginInfo)): (soft) this.sources != null
    //#test_vector(void removePlugin(PluginInfo)): targetPlugin.__Tag@182: {414_976, 416_256, 416_768, 418_048, 418_560, 423_936, 424_448}, {415_744, 419_840, 425_472}
        if (targetPlugin instanceof MediaSource) {
            sources.remove(targetPlugin);
        }
        
        if (targetPlugin instanceof MediaSourceManager) {
            managers.remove((MediaSourceManager) targetPlugin);
        }
    }
    //#NowPlayingPlugin.java:190: end of method: void com.dmdirc.addons.nowplaying.NowPlayingPlugin.removePlugin(PluginInfo)
    
    /**
     * Determines if there are any valid sources (paused or not).
     *
     * @return True if there are running sources, false otherwise
     */
    public boolean hasRunningSource() {
        for (final MediaSource source : getSources()) {
    //#NowPlayingPlugin.java:198: method: bool com.dmdirc.addons.nowplaying.NowPlayingPlugin.hasRunningSource()
    //#input(bool hasRunningSource()): __Descendant_Table[com/dmdirc/addons/nowplaying/NowPlayingPlugin]
    //#input(bool hasRunningSource()): __Descendant_Table[others]
    //#input(bool hasRunningSource()): __Dispatch_Table.getSources()Ljava/util/List;
    //#input(bool hasRunningSource()): com/dmdirc/addons/mediasource_dcop/AmarokSource.__Dispatch_Table.getState()Lcom/dmdirc/addons/nowplaying/MediaSourceState;
    //#input(bool hasRunningSource()): com/dmdirc/addons/mediasource_dcop/DcopMediaSourcePlugin.__Dispatch_Table.getSources()Ljava/util/List;
    //#input(bool hasRunningSource()): com/dmdirc/addons/mediasource_dcop/KaffeineSource.__Dispatch_Table.getState()Lcom/dmdirc/addons/nowplaying/MediaSourceState;
    //#input(bool hasRunningSource()): com/dmdirc/addons/mediasource_dcop/NoatunSource.__Dispatch_Table.getState()Lcom/dmdirc/addons/nowplaying/MediaSourceState;
    //#input(bool hasRunningSource()): com/dmdirc/addons/mediasource_vlc/VlcMediaSourcePlugin.__Dispatch_Table.getState()Lcom/dmdirc/addons/nowplaying/MediaSourceState;
    //#input(bool hasRunningSource()): com/dmdirc/addons/mediasource_windows/DllSource.__Dispatch_Table.getState()Lcom/dmdirc/addons/nowplaying/MediaSourceState;
    //#input(bool hasRunningSource()): com/dmdirc/addons/mediasource_windows/WindowsMediaSourcePlugin.__Dispatch_Table.getSources()Ljava/util/List;
    //#input(bool hasRunningSource()): com/dmdirc/addons/nowplaying/ConfigPanel$DummyMediaSource.__Dispatch_Table.getState()Lcom/dmdirc/addons/nowplaying/MediaSourceState;
    //#input(bool hasRunningSource()): com/dmdirc/addons/nowplaying/MediaSource.__Descendant_Table[com/dmdirc/addons/mediasource_dcop/AmarokSource]
    //#input(bool hasRunningSource()): com/dmdirc/addons/nowplaying/MediaSource.__Descendant_Table[com/dmdirc/addons/mediasource_dcop/KaffeineSource]
    //#input(bool hasRunningSource()): com/dmdirc/addons/nowplaying/MediaSource.__Descendant_Table[com/dmdirc/addons/mediasource_dcop/NoatunSource]
    //#input(bool hasRunningSource()): com/dmdirc/addons/nowplaying/MediaSource.__Descendant_Table[com/dmdirc/addons/mediasource_vlc/VlcMediaSourcePlugin]
    //#input(bool hasRunningSource()): com/dmdirc/addons/nowplaying/MediaSource.__Descendant_Table[com/dmdirc/addons/mediasource_windows/DllSource]
    //#input(bool hasRunningSource()): com/dmdirc/addons/nowplaying/MediaSource.__Descendant_Table[com/dmdirc/addons/nowplaying/ConfigPanel$DummyMediaSource]
    //#input(bool hasRunningSource()): com/dmdirc/addons/nowplaying/MediaSource.__Descendant_Table[com/dmdirc/addons/nowplaying/MediaSource]
    //#input(bool hasRunningSource()): com/dmdirc/addons/nowplaying/MediaSource.__Descendant_Table[others]
    //#input(bool hasRunningSource()): com/dmdirc/addons/nowplaying/MediaSource.__Dispatch_Table.getState()Lcom/dmdirc/addons/nowplaying/MediaSourceState;
    //#input(bool hasRunningSource()): com/dmdirc/addons/nowplaying/MediaSourceManager.__Descendant_Table[com/dmdirc/addons/mediasource_dcop/DcopMediaSourcePlugin]
    //#input(bool hasRunningSource()): com/dmdirc/addons/nowplaying/MediaSourceManager.__Descendant_Table[com/dmdirc/addons/mediasource_windows/WindowsMediaSourcePlugin]
    //#input(bool hasRunningSource()): com/dmdirc/addons/nowplaying/MediaSourceManager.__Descendant_Table[com/dmdirc/addons/nowplaying/MediaSourceManager]
    //#input(bool hasRunningSource()): com/dmdirc/addons/nowplaying/MediaSourceManager.__Descendant_Table[others]
    //#input(bool hasRunningSource()): com/dmdirc/addons/nowplaying/MediaSourceManager.__Dispatch_Table.getSources()Ljava/util/List;
    //#input(bool hasRunningSource()): com/dmdirc/addons/nowplaying/MediaSourceState.CLOSED
    //#input(bool hasRunningSource()): this
    //#input(bool hasRunningSource()): this.__Tag
    //#input(bool hasRunningSource()): this.managers
    //#input(bool hasRunningSource()): this.sources
    //#output(bool hasRunningSource()): return_value
    //#pre[2] (bool hasRunningSource()): this.__Tag == com/dmdirc/addons/nowplaying/NowPlayingPlugin
    //#pre[3] (bool hasRunningSource()): this.managers != null
    //#presumption(bool hasRunningSource()): java.util.Iterator:next(...).__Tag@198 in {com/dmdirc/addons/mediasource_dcop/AmarokSource, com/dmdirc/addons/mediasource_dcop/KaffeineSource, com/dmdirc/addons/mediasource_dcop/NoatunSource, com/dmdirc/addons/mediasource_vlc/VlcMediaSourcePlugin, com/dmdirc/addons/mediasource_windows/DllSource, com/dmdirc/addons/nowplaying/ConfigPanel$DummyMediaSource, com/dmdirc/addons/nowplaying/MediaSource}
    //#presumption(bool hasRunningSource()): java.util.Iterator:next(...)@198 != null
    //#post(bool hasRunningSource()): init'ed(return_value)
    //#unanalyzed(bool hasRunningSource()): Effects-of-calling:java.util.ArrayList
    //#unanalyzed(bool hasRunningSource()): Effects-of-calling:java.util.List:iterator
    //#unanalyzed(bool hasRunningSource()): Effects-of-calling:java.util.Iterator:hasNext
    //#unanalyzed(bool hasRunningSource()): Effects-of-calling:java.util.Iterator:next
    //#unanalyzed(bool hasRunningSource()): Effects-of-calling:getSources
    //#unanalyzed(bool hasRunningSource()): Effects-of-calling:java.util.List:addAll
    //#test_vector(bool hasRunningSource()): getState(...)@199: Addr_Set{&com.dmdirc.addons.nowplaying.MediaSourceState__static_init.new MediaSourceState(MediaSourceState__static_init#1)}, Inverse{&com.dmdirc.addons.nowplaying.MediaSourceState__static_init.new MediaSourceState(MediaSourceState__static_init#1)}
    //#test_vector(bool hasRunningSource()): java.util.Iterator:hasNext(...)@198: {0}, {1}
            if (source.getState() != MediaSourceState.CLOSED) {
    //#NowPlayingPlugin.java:199: Warning: call too complex - analysis skipped
    //#    call on MediaSourceState getState()
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.nowplaying.NowPlayingPlugin
    //#    method: bool hasRunningSource()
    //#    unanalyzed callee: MediaSourceState getState()
                return true;
            }
        }
        
        return false;
    //#NowPlayingPlugin.java:204: end of method: bool com.dmdirc.addons.nowplaying.NowPlayingPlugin.hasRunningSource()
    }
    
    /**
     * Retrieves the "best" source to use for displaying media information.
     * The best source is defined as the earliest in the list that is running
     * and not paused, or, if no such source exists, the earliest in the list
     * that is running and paused. If neither condition is satisified returns
     * null.
     *
     * @return The best source to use for media info
     */
    public MediaSource getBestSource() {
        MediaSource paused = null;
    //#NowPlayingPlugin.java:217: method: MediaSource com.dmdirc.addons.nowplaying.NowPlayingPlugin.getBestSource()
    //#input(MediaSource getBestSource()): __Descendant_Table[com/dmdirc/addons/nowplaying/NowPlayingPlugin]
    //#input(MediaSource getBestSource()): __Descendant_Table[others]
    //#input(MediaSource getBestSource()): __Dispatch_Table.getSources()Ljava/util/List;
    //#input(MediaSource getBestSource()): com/dmdirc/addons/mediasource_dcop/AmarokSource.__Dispatch_Table.getState()Lcom/dmdirc/addons/nowplaying/MediaSourceState;
    //#input(MediaSource getBestSource()): com/dmdirc/addons/mediasource_dcop/DcopMediaSourcePlugin.__Dispatch_Table.getSources()Ljava/util/List;
    //#input(MediaSource getBestSource()): com/dmdirc/addons/mediasource_dcop/KaffeineSource.__Dispatch_Table.getState()Lcom/dmdirc/addons/nowplaying/MediaSourceState;
    //#input(MediaSource getBestSource()): com/dmdirc/addons/mediasource_dcop/NoatunSource.__Dispatch_Table.getState()Lcom/dmdirc/addons/nowplaying/MediaSourceState;
    //#input(MediaSource getBestSource()): com/dmdirc/addons/mediasource_vlc/VlcMediaSourcePlugin.__Dispatch_Table.getState()Lcom/dmdirc/addons/nowplaying/MediaSourceState;
    //#input(MediaSource getBestSource()): com/dmdirc/addons/mediasource_windows/DllSource.__Dispatch_Table.getState()Lcom/dmdirc/addons/nowplaying/MediaSourceState;
    //#input(MediaSource getBestSource()): com/dmdirc/addons/mediasource_windows/WindowsMediaSourcePlugin.__Dispatch_Table.getSources()Ljava/util/List;
    //#input(MediaSource getBestSource()): com/dmdirc/addons/nowplaying/ConfigPanel$DummyMediaSource.__Dispatch_Table.getState()Lcom/dmdirc/addons/nowplaying/MediaSourceState;
    //#input(MediaSource getBestSource()): com/dmdirc/addons/nowplaying/MediaSource.__Descendant_Table[com/dmdirc/addons/mediasource_dcop/AmarokSource]
    //#input(MediaSource getBestSource()): com/dmdirc/addons/nowplaying/MediaSource.__Descendant_Table[com/dmdirc/addons/mediasource_dcop/KaffeineSource]
    //#input(MediaSource getBestSource()): com/dmdirc/addons/nowplaying/MediaSource.__Descendant_Table[com/dmdirc/addons/mediasource_dcop/NoatunSource]
    //#input(MediaSource getBestSource()): com/dmdirc/addons/nowplaying/MediaSource.__Descendant_Table[com/dmdirc/addons/mediasource_vlc/VlcMediaSourcePlugin]
    //#input(MediaSource getBestSource()): com/dmdirc/addons/nowplaying/MediaSource.__Descendant_Table[com/dmdirc/addons/mediasource_windows/DllSource]
    //#input(MediaSource getBestSource()): com/dmdirc/addons/nowplaying/MediaSource.__Descendant_Table[com/dmdirc/addons/nowplaying/ConfigPanel$DummyMediaSource]
    //#input(MediaSource getBestSource()): com/dmdirc/addons/nowplaying/MediaSource.__Descendant_Table[com/dmdirc/addons/nowplaying/MediaSource]
    //#input(MediaSource getBestSource()): com/dmdirc/addons/nowplaying/MediaSource.__Descendant_Table[others]
    //#input(MediaSource getBestSource()): com/dmdirc/addons/nowplaying/MediaSource.__Dispatch_Table.getState()Lcom/dmdirc/addons/nowplaying/MediaSourceState;
    //#input(MediaSource getBestSource()): com/dmdirc/addons/nowplaying/MediaSourceManager.__Descendant_Table[com/dmdirc/addons/mediasource_dcop/DcopMediaSourcePlugin]
    //#input(MediaSource getBestSource()): com/dmdirc/addons/nowplaying/MediaSourceManager.__Descendant_Table[com/dmdirc/addons/mediasource_windows/WindowsMediaSourcePlugin]
    //#input(MediaSource getBestSource()): com/dmdirc/addons/nowplaying/MediaSourceManager.__Descendant_Table[com/dmdirc/addons/nowplaying/MediaSourceManager]
    //#input(MediaSource getBestSource()): com/dmdirc/addons/nowplaying/MediaSourceManager.__Descendant_Table[others]
    //#input(MediaSource getBestSource()): com/dmdirc/addons/nowplaying/MediaSourceManager.__Dispatch_Table.getSources()Ljava/util/List;
    //#input(MediaSource getBestSource()): com/dmdirc/addons/nowplaying/MediaSourceState.CLOSED
    //#input(MediaSource getBestSource()): com/dmdirc/addons/nowplaying/MediaSourceState.PLAYING
    //#input(MediaSource getBestSource()): this
    //#input(MediaSource getBestSource()): this.__Tag
    //#input(MediaSource getBestSource()): this.managers
    //#input(MediaSource getBestSource()): this.order
    //#input(MediaSource getBestSource()): this.sources
    //#output(MediaSource getBestSource()): return_value
    //#pre[2] (MediaSource getBestSource()): this.__Tag == com/dmdirc/addons/nowplaying/NowPlayingPlugin
    //#pre[3] (MediaSource getBestSource()): this.managers != null
    //#pre[4] (MediaSource getBestSource()): init'ed(this.order)
    //#presumption(MediaSource getBestSource()): java.util.Iterator:next(...).__Tag@221 in {com/dmdirc/addons/mediasource_dcop/AmarokSource, com/dmdirc/addons/mediasource_dcop/KaffeineSource, com/dmdirc/addons/mediasource_dcop/NoatunSource, com/dmdirc/addons/mediasource_vlc/VlcMediaSourcePlugin, com/dmdirc/addons/mediasource_windows/DllSource, com/dmdirc/addons/nowplaying/ConfigPanel$DummyMediaSource, com/dmdirc/addons/nowplaying/MediaSource}
    //#presumption(MediaSource getBestSource()): java.util.Iterator:next(...)@221 != null
    //#post(MediaSource getBestSource()): init'ed(return_value)
    //#unanalyzed(MediaSource getBestSource()): Effects-of-calling:java.util.ArrayList
    //#unanalyzed(MediaSource getBestSource()): Effects-of-calling:java.util.List:iterator
    //#unanalyzed(MediaSource getBestSource()): Effects-of-calling:java.util.Iterator:hasNext
    //#unanalyzed(MediaSource getBestSource()): Effects-of-calling:java.util.Iterator:next
    //#unanalyzed(MediaSource getBestSource()): Effects-of-calling:getSources
    //#unanalyzed(MediaSource getBestSource()): Effects-of-calling:java.util.List:addAll
    //#test_vector(MediaSource getBestSource()): getState(...)@222: Addr_Set{&com.dmdirc.addons.nowplaying.MediaSourceState__static_init.new MediaSourceState(MediaSourceState__static_init#1)}, Inverse{&com.dmdirc.addons.nowplaying.MediaSourceState__static_init.new MediaSourceState(MediaSourceState__static_init#1)}
    //#test_vector(MediaSource getBestSource()): getState(...)@223: Inverse{&com.dmdirc.addons.nowplaying.MediaSourceState__static_init.new MediaSourceState(MediaSourceState__static_init#4)}, Addr_Set{&com.dmdirc.addons.nowplaying.MediaSourceState__static_init.new MediaSourceState(MediaSourceState__static_init#4)}
    //#test_vector(MediaSource getBestSource()): java.util.Iterator:hasNext(...)@221: {0}, {1}
        
        Collections.sort(sources, new MediaSourceComparator(order));
        
        for (final MediaSource source : getSources()) {
            if (source.getState() != MediaSourceState.CLOSED) {
    //#NowPlayingPlugin.java:222: Warning: call too complex - analysis skipped
    //#    call on MediaSourceState getState()
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.nowplaying.NowPlayingPlugin
    //#    method: MediaSource getBestSource()
    //#    unanalyzed callee: MediaSourceState getState()
                if (source.getState() == MediaSourceState.PLAYING) {
    //#NowPlayingPlugin.java:223: Warning: call too complex - analysis skipped
    //#    call on MediaSourceState getState()
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.nowplaying.NowPlayingPlugin
    //#    method: MediaSource getBestSource()
    //#    unanalyzed callee: MediaSourceState getState()
                    return source;
                } else if (paused == null) {
                    paused = source;
                }
            }
        }
        
        return paused;
    //#NowPlayingPlugin.java:231: end of method: MediaSource com.dmdirc.addons.nowplaying.NowPlayingPlugin.getBestSource()
    }
    
    /**
     * Substitutes the keywords in the specified format with the values with
     * values from the specified source.
     * 
     * @param format The format to be substituted
     * @param source The source whose values should be used
     * @return The substituted string
     */
    public String doSubstitution(final String format, final MediaSource source) {
        final String artist = source.getArtist();
    //#NowPlayingPlugin.java:243: method: String com.dmdirc.addons.nowplaying.NowPlayingPlugin.doSubstitution(String, MediaSource)
    //#NowPlayingPlugin.java:243: Warning: call too complex - analysis skipped
    //#    call on String getArtist()
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.nowplaying.NowPlayingPlugin
    //#    method: String doSubstitution(String, MediaSource)
    //#    unanalyzed callee: String getArtist()
    //#NowPlayingPlugin.java:243: Warning: suspicious precondition
    //#    The precondition for source.__Tag is not a contiguous range of values
    //#    severity: SUPPRESSED
    //#    class: com.dmdirc.addons.nowplaying.NowPlayingPlugin
    //#    method: String doSubstitution(String, MediaSource)
    //#    suspicious precondition index: [3]
    //#input(String doSubstitution(String, MediaSource)): com/dmdirc/addons/mediasource_dcop/AmarokSource.__Dispatch_Table.getAlbum()Ljava/lang/String;
    //#input(String doSubstitution(String, MediaSource)): com/dmdirc/addons/mediasource_dcop/AmarokSource.__Dispatch_Table.getAppName()Ljava/lang/String;
    //#input(String doSubstitution(String, MediaSource)): com/dmdirc/addons/mediasource_dcop/AmarokSource.__Dispatch_Table.getArtist()Ljava/lang/String;
    //#input(String doSubstitution(String, MediaSource)): com/dmdirc/addons/mediasource_dcop/AmarokSource.__Dispatch_Table.getBitrate()Ljava/lang/String;
    //#input(String doSubstitution(String, MediaSource)): com/dmdirc/addons/mediasource_dcop/AmarokSource.__Dispatch_Table.getFormat()Ljava/lang/String;
    //#input(String doSubstitution(String, MediaSource)): com/dmdirc/addons/mediasource_dcop/AmarokSource.__Dispatch_Table.getLength()Ljava/lang/String;
    //#input(String doSubstitution(String, MediaSource)): com/dmdirc/addons/mediasource_dcop/AmarokSource.__Dispatch_Table.getState()Lcom/dmdirc/addons/nowplaying/MediaSourceState;
    //#input(String doSubstitution(String, MediaSource)): com/dmdirc/addons/mediasource_dcop/AmarokSource.__Dispatch_Table.getTime()Ljava/lang/String;
    //#input(String doSubstitution(String, MediaSource)): com/dmdirc/addons/mediasource_dcop/AmarokSource.__Dispatch_Table.getTitle()Ljava/lang/String;
    //#input(String doSubstitution(String, MediaSource)): com/dmdirc/addons/mediasource_dcop/KaffeineSource.__Dispatch_Table.getAlbum()Ljava/lang/String;
    //#input(String doSubstitution(String, MediaSource)): com/dmdirc/addons/mediasource_dcop/KaffeineSource.__Dispatch_Table.getAppName()Ljava/lang/String;
    //#input(String doSubstitution(String, MediaSource)): com/dmdirc/addons/mediasource_dcop/KaffeineSource.__Dispatch_Table.getArtist()Ljava/lang/String;
    //#input(String doSubstitution(String, MediaSource)): com/dmdirc/addons/mediasource_dcop/KaffeineSource.__Dispatch_Table.getBitrate()Ljava/lang/String;
    //#input(String doSubstitution(String, MediaSource)): com/dmdirc/addons/mediasource_dcop/KaffeineSource.__Dispatch_Table.getFormat()Ljava/lang/String;
    //#input(String doSubstitution(String, MediaSource)): com/dmdirc/addons/mediasource_dcop/KaffeineSource.__Dispatch_Table.getLength()Ljava/lang/String;
    //#input(String doSubstitution(String, MediaSource)): com/dmdirc/addons/mediasource_dcop/KaffeineSource.__Dispatch_Table.getState()Lcom/dmdirc/addons/nowplaying/MediaSourceState;
    //#input(String doSubstitution(String, MediaSource)): com/dmdirc/addons/mediasource_dcop/KaffeineSource.__Dispatch_Table.getTime()Ljava/lang/String;
    //#input(String doSubstitution(String, MediaSource)): com/dmdirc/addons/mediasource_dcop/KaffeineSource.__Dispatch_Table.getTitle()Ljava/lang/String;
    //#input(String doSubstitution(String, MediaSource)): com/dmdirc/addons/mediasource_dcop/NoatunSource.__Dispatch_Table.getAlbum()Ljava/lang/String;
    //#input(String doSubstitution(String, MediaSource)): com/dmdirc/addons/mediasource_dcop/NoatunSource.__Dispatch_Table.getAppName()Ljava/lang/String;
    //#input(String doSubstitution(String, MediaSource)): com/dmdirc/addons/mediasource_dcop/NoatunSource.__Dispatch_Table.getArtist()Ljava/lang/String;
    //#input(String doSubstitution(String, MediaSource)): com/dmdirc/addons/mediasource_dcop/NoatunSource.__Dispatch_Table.getBitrate()Ljava/lang/String;
    //#input(String doSubstitution(String, MediaSource)): com/dmdirc/addons/mediasource_dcop/NoatunSource.__Dispatch_Table.getFormat()Ljava/lang/String;
    //#input(String doSubstitution(String, MediaSource)): com/dmdirc/addons/mediasource_dcop/NoatunSource.__Dispatch_Table.getLength()Ljava/lang/String;
    //#input(String doSubstitution(String, MediaSource)): com/dmdirc/addons/mediasource_dcop/NoatunSource.__Dispatch_Table.getState()Lcom/dmdirc/addons/nowplaying/MediaSourceState;
    //#input(String doSubstitution(String, MediaSource)): com/dmdirc/addons/mediasource_dcop/NoatunSource.__Dispatch_Table.getTime()Ljava/lang/String;
    //#input(String doSubstitution(String, MediaSource)): com/dmdirc/addons/mediasource_dcop/NoatunSource.__Dispatch_Table.getTitle()Ljava/lang/String;
    //#input(String doSubstitution(String, MediaSource)): com/dmdirc/addons/mediasource_vlc/VlcMediaSourcePlugin.__Dispatch_Table.getAlbum()Ljava/lang/String;
    //#input(String doSubstitution(String, MediaSource)): com/dmdirc/addons/mediasource_vlc/VlcMediaSourcePlugin.__Dispatch_Table.getAppName()Ljava/lang/String;
    //#input(String doSubstitution(String, MediaSource)): com/dmdirc/addons/mediasource_vlc/VlcMediaSourcePlugin.__Dispatch_Table.getArtist()Ljava/lang/String;
    //#input(String doSubstitution(String, MediaSource)): com/dmdirc/addons/mediasource_vlc/VlcMediaSourcePlugin.__Dispatch_Table.getBitrate()Ljava/lang/String;
    //#input(String doSubstitution(String, MediaSource)): com/dmdirc/addons/mediasource_vlc/VlcMediaSourcePlugin.__Dispatch_Table.getFormat()Ljava/lang/String;
    //#input(String doSubstitution(String, MediaSource)): com/dmdirc/addons/mediasource_vlc/VlcMediaSourcePlugin.__Dispatch_Table.getLength()Ljava/lang/String;
    //#input(String doSubstitution(String, MediaSource)): com/dmdirc/addons/mediasource_vlc/VlcMediaSourcePlugin.__Dispatch_Table.getState()Lcom/dmdirc/addons/nowplaying/MediaSourceState;
    //#input(String doSubstitution(String, MediaSource)): com/dmdirc/addons/mediasource_vlc/VlcMediaSourcePlugin.__Dispatch_Table.getTime()Ljava/lang/String;
    //#input(String doSubstitution(String, MediaSource)): com/dmdirc/addons/mediasource_vlc/VlcMediaSourcePlugin.__Dispatch_Table.getTitle()Ljava/lang/String;
    //#input(String doSubstitution(String, MediaSource)): com/dmdirc/addons/mediasource_windows/DllSource.__Dispatch_Table.getAlbum()Ljava/lang/String;
    //#input(String doSubstitution(String, MediaSource)): com/dmdirc/addons/mediasource_windows/DllSource.__Dispatch_Table.getAppName()Ljava/lang/String;
    //#input(String doSubstitution(String, MediaSource)): com/dmdirc/addons/mediasource_windows/DllSource.__Dispatch_Table.getArtist()Ljava/lang/String;
    //#input(String doSubstitution(String, MediaSource)): com/dmdirc/addons/mediasource_windows/DllSource.__Dispatch_Table.getBitrate()Ljava/lang/String;
    //#input(String doSubstitution(String, MediaSource)): com/dmdirc/addons/mediasource_windows/DllSource.__Dispatch_Table.getFormat()Ljava/lang/String;
    //#input(String doSubstitution(String, MediaSource)): com/dmdirc/addons/mediasource_windows/DllSource.__Dispatch_Table.getLength()Ljava/lang/String;
    //#input(String doSubstitution(String, MediaSource)): com/dmdirc/addons/mediasource_windows/DllSource.__Dispatch_Table.getState()Lcom/dmdirc/addons/nowplaying/MediaSourceState;
    //#input(String doSubstitution(String, MediaSource)): com/dmdirc/addons/mediasource_windows/DllSource.__Dispatch_Table.getTime()Ljava/lang/String;
    //#input(String doSubstitution(String, MediaSource)): com/dmdirc/addons/mediasource_windows/DllSource.__Dispatch_Table.getTitle()Ljava/lang/String;
    //#input(String doSubstitution(String, MediaSource)): com/dmdirc/addons/nowplaying/ConfigPanel$DummyMediaSource.__Dispatch_Table.getAlbum()Ljava/lang/String;
    //#input(String doSubstitution(String, MediaSource)): com/dmdirc/addons/nowplaying/ConfigPanel$DummyMediaSource.__Dispatch_Table.getAppName()Ljava/lang/String;
    //#input(String doSubstitution(String, MediaSource)): com/dmdirc/addons/nowplaying/ConfigPanel$DummyMediaSource.__Dispatch_Table.getArtist()Ljava/lang/String;
    //#input(String doSubstitution(String, MediaSource)): com/dmdirc/addons/nowplaying/ConfigPanel$DummyMediaSource.__Dispatch_Table.getBitrate()Ljava/lang/String;
    //#input(String doSubstitution(String, MediaSource)): com/dmdirc/addons/nowplaying/ConfigPanel$DummyMediaSource.__Dispatch_Table.getFormat()Ljava/lang/String;
    //#input(String doSubstitution(String, MediaSource)): com/dmdirc/addons/nowplaying/ConfigPanel$DummyMediaSource.__Dispatch_Table.getLength()Ljava/lang/String;
    //#input(String doSubstitution(String, MediaSource)): com/dmdirc/addons/nowplaying/ConfigPanel$DummyMediaSource.__Dispatch_Table.getState()Lcom/dmdirc/addons/nowplaying/MediaSourceState;
    //#input(String doSubstitution(String, MediaSource)): com/dmdirc/addons/nowplaying/ConfigPanel$DummyMediaSource.__Dispatch_Table.getTime()Ljava/lang/String;
    //#input(String doSubstitution(String, MediaSource)): com/dmdirc/addons/nowplaying/ConfigPanel$DummyMediaSource.__Dispatch_Table.getTitle()Ljava/lang/String;
    //#input(String doSubstitution(String, MediaSource)): com/dmdirc/addons/nowplaying/MediaSource.__Descendant_Table[com/dmdirc/addons/mediasource_dcop/AmarokSource]
    //#input(String doSubstitution(String, MediaSource)): com/dmdirc/addons/nowplaying/MediaSource.__Descendant_Table[com/dmdirc/addons/mediasource_dcop/KaffeineSource]
    //#input(String doSubstitution(String, MediaSource)): com/dmdirc/addons/nowplaying/MediaSource.__Descendant_Table[com/dmdirc/addons/mediasource_dcop/NoatunSource]
    //#input(String doSubstitution(String, MediaSource)): com/dmdirc/addons/nowplaying/MediaSource.__Descendant_Table[com/dmdirc/addons/mediasource_vlc/VlcMediaSourcePlugin]
    //#input(String doSubstitution(String, MediaSource)): com/dmdirc/addons/nowplaying/MediaSource.__Descendant_Table[com/dmdirc/addons/mediasource_windows/DllSource]
    //#input(String doSubstitution(String, MediaSource)): com/dmdirc/addons/nowplaying/MediaSource.__Descendant_Table[com/dmdirc/addons/nowplaying/ConfigPanel$DummyMediaSource]
    //#input(String doSubstitution(String, MediaSource)): com/dmdirc/addons/nowplaying/MediaSource.__Descendant_Table[com/dmdirc/addons/nowplaying/MediaSource]
    //#input(String doSubstitution(String, MediaSource)): com/dmdirc/addons/nowplaying/MediaSource.__Descendant_Table[others]
    //#input(String doSubstitution(String, MediaSource)): com/dmdirc/addons/nowplaying/MediaSource.__Dispatch_Table.getAlbum()Ljava/lang/String;
    //#input(String doSubstitution(String, MediaSource)): com/dmdirc/addons/nowplaying/MediaSource.__Dispatch_Table.getAppName()Ljava/lang/String;
    //#input(String doSubstitution(String, MediaSource)): com/dmdirc/addons/nowplaying/MediaSource.__Dispatch_Table.getArtist()Ljava/lang/String;
    //#input(String doSubstitution(String, MediaSource)): com/dmdirc/addons/nowplaying/MediaSource.__Dispatch_Table.getBitrate()Ljava/lang/String;
    //#input(String doSubstitution(String, MediaSource)): com/dmdirc/addons/nowplaying/MediaSource.__Dispatch_Table.getFormat()Ljava/lang/String;
    //#input(String doSubstitution(String, MediaSource)): com/dmdirc/addons/nowplaying/MediaSource.__Dispatch_Table.getLength()Ljava/lang/String;
    //#input(String doSubstitution(String, MediaSource)): com/dmdirc/addons/nowplaying/MediaSource.__Dispatch_Table.getState()Lcom/dmdirc/addons/nowplaying/MediaSourceState;
    //#input(String doSubstitution(String, MediaSource)): com/dmdirc/addons/nowplaying/MediaSource.__Dispatch_Table.getTime()Ljava/lang/String;
    //#input(String doSubstitution(String, MediaSource)): com/dmdirc/addons/nowplaying/MediaSource.__Dispatch_Table.getTitle()Ljava/lang/String;
    //#input(String doSubstitution(String, MediaSource)): format
    //#input(String doSubstitution(String, MediaSource)): source
    //#input(String doSubstitution(String, MediaSource)): source.__Tag
    //#output(String doSubstitution(String, MediaSource)): return_value
    //#pre[1] (String doSubstitution(String, MediaSource)): format != null
    //#pre[2] (String doSubstitution(String, MediaSource)): source != null
    //#pre[3] (String doSubstitution(String, MediaSource)): source.__Tag in {com/dmdirc/addons/mediasource_dcop/AmarokSource, com/dmdirc/addons/mediasource_dcop/KaffeineSource, com/dmdirc/addons/mediasource_dcop/NoatunSource, com/dmdirc/addons/mediasource_vlc/VlcMediaSourcePlugin, com/dmdirc/addons/mediasource_windows/DllSource, com/dmdirc/addons/nowplaying/ConfigPanel$DummyMediaSource, com/dmdirc/addons/nowplaying/MediaSource}
    //#presumption(String doSubstitution(String, MediaSource)): getState(...)@251 != null
    //#post(String doSubstitution(String, MediaSource)): return_value != null
        final String title = source.getTitle();
    //#NowPlayingPlugin.java:244: Warning: call too complex - analysis skipped
    //#    call on String getTitle()
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.nowplaying.NowPlayingPlugin
    //#    method: String doSubstitution(String, MediaSource)
    //#    unanalyzed callee: String getTitle()
        final String album = source.getAlbum();
    //#NowPlayingPlugin.java:245: Warning: call too complex - analysis skipped
    //#    call on String getAlbum()
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.nowplaying.NowPlayingPlugin
    //#    method: String doSubstitution(String, MediaSource)
    //#    unanalyzed callee: String getAlbum()
        final String app = source.getAppName();
    //#NowPlayingPlugin.java:246: Warning: call too complex - analysis skipped
    //#    call on String getAppName()
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.nowplaying.NowPlayingPlugin
    //#    method: String doSubstitution(String, MediaSource)
    //#    unanalyzed callee: String getAppName()
        final String bitrate = source.getBitrate();
    //#NowPlayingPlugin.java:247: Warning: call too complex - analysis skipped
    //#    call on String getBitrate()
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.nowplaying.NowPlayingPlugin
    //#    method: String doSubstitution(String, MediaSource)
    //#    unanalyzed callee: String getBitrate()
        final String filetype = source.getFormat();
    //#NowPlayingPlugin.java:248: Warning: call too complex - analysis skipped
    //#    call on String getFormat()
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.nowplaying.NowPlayingPlugin
    //#    method: String doSubstitution(String, MediaSource)
    //#    unanalyzed callee: String getFormat()
        final String length = source.getLength();
    //#NowPlayingPlugin.java:249: Warning: call too complex - analysis skipped
    //#    call on String getLength()
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.nowplaying.NowPlayingPlugin
    //#    method: String doSubstitution(String, MediaSource)
    //#    unanalyzed callee: String getLength()
        final String time = source.getTime();
    //#NowPlayingPlugin.java:250: Warning: call too complex - analysis skipped
    //#    call on String getTime()
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.nowplaying.NowPlayingPlugin
    //#    method: String doSubstitution(String, MediaSource)
    //#    unanalyzed callee: String getTime()
        final String state = source.getState().getNiceName();
    //#NowPlayingPlugin.java:251: Warning: call too complex - analysis skipped
    //#    call on MediaSourceState getState()
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.nowplaying.NowPlayingPlugin
    //#    method: String doSubstitution(String, MediaSource)
    //#    unanalyzed callee: MediaSourceState getState()
        
        return format.replaceAll("\\$artist", artist)
    //#NowPlayingPlugin.java:253: end of method: String com.dmdirc.addons.nowplaying.NowPlayingPlugin.doSubstitution(String, MediaSource)
                     .replaceAll("\\$title", title)
                     .replaceAll("\\$album", album)
                     .replaceAll("\\$app", app)
                     .replaceAll("\\$bitrate", bitrate)
                     .replaceAll("\\$format", filetype)
                     .replaceAll("\\$length", length)
                     .replaceAll("\\$state", state)
                     .replaceAll("\\$time", time);
    }
    
    /**
     * Retrieves a source based on its name.
     *
     * @param name The name to search for
     * @return The source with the specified name or null if none were found.
     */
    public MediaSource getSource(final String name) {
        for (final MediaSource source : getSources()) {
    //#NowPlayingPlugin.java:271: method: MediaSource com.dmdirc.addons.nowplaying.NowPlayingPlugin.getSource(String)
    //#input(MediaSource getSource(String)): __Descendant_Table[com/dmdirc/addons/nowplaying/NowPlayingPlugin]
    //#input(MediaSource getSource(String)): __Descendant_Table[others]
    //#input(MediaSource getSource(String)): __Dispatch_Table.getSources()Ljava/util/List;
    //#input(MediaSource getSource(String)): com/dmdirc/addons/mediasource_dcop/AmarokSource.__Dispatch_Table.getAppName()Ljava/lang/String;
    //#input(MediaSource getSource(String)): com/dmdirc/addons/mediasource_dcop/DcopMediaSourcePlugin.__Dispatch_Table.getSources()Ljava/util/List;
    //#input(MediaSource getSource(String)): com/dmdirc/addons/mediasource_dcop/KaffeineSource.__Dispatch_Table.getAppName()Ljava/lang/String;
    //#input(MediaSource getSource(String)): com/dmdirc/addons/mediasource_dcop/NoatunSource.__Dispatch_Table.getAppName()Ljava/lang/String;
    //#input(MediaSource getSource(String)): com/dmdirc/addons/mediasource_vlc/VlcMediaSourcePlugin.__Dispatch_Table.getAppName()Ljava/lang/String;
    //#input(MediaSource getSource(String)): com/dmdirc/addons/mediasource_windows/DllSource.__Dispatch_Table.getAppName()Ljava/lang/String;
    //#input(MediaSource getSource(String)): com/dmdirc/addons/mediasource_windows/WindowsMediaSourcePlugin.__Dispatch_Table.getSources()Ljava/util/List;
    //#input(MediaSource getSource(String)): com/dmdirc/addons/nowplaying/ConfigPanel$DummyMediaSource.__Dispatch_Table.getAppName()Ljava/lang/String;
    //#input(MediaSource getSource(String)): com/dmdirc/addons/nowplaying/MediaSource.__Descendant_Table[com/dmdirc/addons/mediasource_dcop/AmarokSource]
    //#input(MediaSource getSource(String)): com/dmdirc/addons/nowplaying/MediaSource.__Descendant_Table[com/dmdirc/addons/mediasource_dcop/KaffeineSource]
    //#input(MediaSource getSource(String)): com/dmdirc/addons/nowplaying/MediaSource.__Descendant_Table[com/dmdirc/addons/mediasource_dcop/NoatunSource]
    //#input(MediaSource getSource(String)): com/dmdirc/addons/nowplaying/MediaSource.__Descendant_Table[com/dmdirc/addons/mediasource_vlc/VlcMediaSourcePlugin]
    //#input(MediaSource getSource(String)): com/dmdirc/addons/nowplaying/MediaSource.__Descendant_Table[com/dmdirc/addons/mediasource_windows/DllSource]
    //#input(MediaSource getSource(String)): com/dmdirc/addons/nowplaying/MediaSource.__Descendant_Table[com/dmdirc/addons/nowplaying/ConfigPanel$DummyMediaSource]
    //#input(MediaSource getSource(String)): com/dmdirc/addons/nowplaying/MediaSource.__Descendant_Table[com/dmdirc/addons/nowplaying/MediaSource]
    //#input(MediaSource getSource(String)): com/dmdirc/addons/nowplaying/MediaSource.__Descendant_Table[others]
    //#input(MediaSource getSource(String)): com/dmdirc/addons/nowplaying/MediaSource.__Dispatch_Table.getAppName()Ljava/lang/String;
    //#input(MediaSource getSource(String)): com/dmdirc/addons/nowplaying/MediaSourceManager.__Descendant_Table[com/dmdirc/addons/mediasource_dcop/DcopMediaSourcePlugin]
    //#input(MediaSource getSource(String)): com/dmdirc/addons/nowplaying/MediaSourceManager.__Descendant_Table[com/dmdirc/addons/mediasource_windows/WindowsMediaSourcePlugin]
    //#input(MediaSource getSource(String)): com/dmdirc/addons/nowplaying/MediaSourceManager.__Descendant_Table[com/dmdirc/addons/nowplaying/MediaSourceManager]
    //#input(MediaSource getSource(String)): com/dmdirc/addons/nowplaying/MediaSourceManager.__Descendant_Table[others]
    //#input(MediaSource getSource(String)): com/dmdirc/addons/nowplaying/MediaSourceManager.__Dispatch_Table.getSources()Ljava/util/List;
    //#input(MediaSource getSource(String)): name
    //#input(MediaSource getSource(String)): this
    //#input(MediaSource getSource(String)): this.__Tag
    //#input(MediaSource getSource(String)): this.managers
    //#input(MediaSource getSource(String)): this.sources
    //#output(MediaSource getSource(String)): return_value
    //#pre[3] (MediaSource getSource(String)): this.__Tag == com/dmdirc/addons/nowplaying/NowPlayingPlugin
    //#pre[4] (MediaSource getSource(String)): this.managers != null
    //#presumption(MediaSource getSource(String)): getAppName(...)@272 != null
    //#presumption(MediaSource getSource(String)): java.util.Iterator:next(...).__Tag@271 in {com/dmdirc/addons/mediasource_dcop/AmarokSource, com/dmdirc/addons/mediasource_dcop/KaffeineSource, com/dmdirc/addons/mediasource_dcop/NoatunSource, com/dmdirc/addons/mediasource_vlc/VlcMediaSourcePlugin, com/dmdirc/addons/mediasource_windows/DllSource, com/dmdirc/addons/nowplaying/ConfigPanel$DummyMediaSource, com/dmdirc/addons/nowplaying/MediaSource}
    //#presumption(MediaSource getSource(String)): java.util.Iterator:next(...)@271 != null
    //#post(MediaSource getSource(String)): init'ed(return_value)
    //#unanalyzed(MediaSource getSource(String)): Effects-of-calling:java.util.ArrayList
    //#unanalyzed(MediaSource getSource(String)): Effects-of-calling:java.util.List:iterator
    //#unanalyzed(MediaSource getSource(String)): Effects-of-calling:java.util.Iterator:hasNext
    //#unanalyzed(MediaSource getSource(String)): Effects-of-calling:java.util.Iterator:next
    //#unanalyzed(MediaSource getSource(String)): Effects-of-calling:getSources
    //#unanalyzed(MediaSource getSource(String)): Effects-of-calling:java.util.List:addAll
    //#test_vector(MediaSource getSource(String)): java.lang.String:equalsIgnoreCase(...)@272: {0}, {1}
    //#test_vector(MediaSource getSource(String)): java.util.Iterator:hasNext(...)@271: {0}, {1}
            if (source.getAppName().equalsIgnoreCase(name)) {
    //#NowPlayingPlugin.java:272: Warning: call too complex - analysis skipped
    //#    call on String getAppName()
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.addons.nowplaying.NowPlayingPlugin
    //#    method: MediaSource getSource(String)
    //#    unanalyzed callee: String getAppName()
                return source;
            }
        }
        
        return null;
    //#NowPlayingPlugin.java:277: end of method: MediaSource com.dmdirc.addons.nowplaying.NowPlayingPlugin.getSource(String)
    }
    
    /**
     * Retrieves all the sources registered with this plugin.
     *
     * @return All known media sources
     */
    public List<MediaSource> getSources() {
        final List<MediaSource> res = new ArrayList<MediaSource>(sources);
    //#NowPlayingPlugin.java:286: method: List com.dmdirc.addons.nowplaying.NowPlayingPlugin.getSources()
    //#input(List getSources()): com/dmdirc/addons/mediasource_dcop/DcopMediaSourcePlugin.__Dispatch_Table.getSources()Ljava/util/List;
    //#input(List getSources()): com/dmdirc/addons/mediasource_windows/WindowsMediaSourcePlugin.__Dispatch_Table.getSources()Ljava/util/List;
    //#input(List getSources()): com/dmdirc/addons/nowplaying/MediaSourceManager.__Descendant_Table[com/dmdirc/addons/mediasource_dcop/DcopMediaSourcePlugin]
    //#input(List getSources()): com/dmdirc/addons/nowplaying/MediaSourceManager.__Descendant_Table[com/dmdirc/addons/mediasource_windows/WindowsMediaSourcePlugin]
    //#input(List getSources()): com/dmdirc/addons/nowplaying/MediaSourceManager.__Descendant_Table[com/dmdirc/addons/nowplaying/MediaSourceManager]
    //#input(List getSources()): com/dmdirc/addons/nowplaying/MediaSourceManager.__Descendant_Table[others]
    //#input(List getSources()): com/dmdirc/addons/nowplaying/MediaSourceManager.__Dispatch_Table.getSources()Ljava/util/List;
    //#input(List getSources()): this
    //#input(List getSources()): this.managers
    //#input(List getSources()): this.sources
    //#output(List getSources()): new ArrayList(getSources#1) num objects
    //#output(List getSources()): return_value
    //#new obj(List getSources()): new ArrayList(getSources#1)
    //#pre[2] (List getSources()): this.managers != null
    //#presumption(List getSources()): java.util.Iterator:next(...).__Tag@288 in {com/dmdirc/addons/mediasource_dcop/DcopMediaSourcePlugin, com/dmdirc/addons/mediasource_windows/WindowsMediaSourcePlugin, com/dmdirc/addons/nowplaying/MediaSourceManager}
    //#presumption(List getSources()): java.util.Iterator:next(...)@288 != null
    //#post(List getSources()): return_value == &new ArrayList(getSources#1)
    //#post(List getSources()): new ArrayList(getSources#1) num objects == 1
    //#test_vector(List getSources()): java.util.Iterator:hasNext(...)@288: {0}, {1}

        for (MediaSourceManager manager : managers) {
            res.addAll(manager.getSources());
        }

        return res;
    //#NowPlayingPlugin.java:292: end of method: List com.dmdirc.addons.nowplaying.NowPlayingPlugin.getSources()
    }
}    //#output(com.dmdirc.addons.nowplaying.NowPlayingPlugin__static_init): __Descendant_Table[com/dmdirc/addons/nowplaying/NowPlayingPlugin]
    //#output(com.dmdirc.addons.nowplaying.NowPlayingPlugin__static_init): __Dispatch_Table.addPlugin(Lcom/dmdirc/plugins/PluginInfo;)V
    //#output(com.dmdirc.addons.nowplaying.NowPlayingPlugin__static_init): __Dispatch_Table.addSourceToOrder(Lcom/dmdirc/addons/nowplaying/MediaSource;)V
    //#output(com.dmdirc.addons.nowplaying.NowPlayingPlugin__static_init): __Dispatch_Table.doSubstitution(Ljava/lang/String;Lcom/dmdirc/addons/nowplaying/MediaSource;)Ljava/lang/String;
    //#output(com.dmdirc.addons.nowplaying.NowPlayingPlugin__static_init): __Dispatch_Table.getBestSource()Lcom/dmdirc/addons/nowplaying/MediaSource;
    //#output(com.dmdirc.addons.nowplaying.NowPlayingPlugin__static_init): __Dispatch_Table.getSource(Ljava/lang/String;)Lcom/dmdirc/addons/nowplaying/MediaSource;
    //#output(com.dmdirc.addons.nowplaying.NowPlayingPlugin__static_init): __Dispatch_Table.getSources()Ljava/util/List;
    //#output(com.dmdirc.addons.nowplaying.NowPlayingPlugin__static_init): __Dispatch_Table.hasRunningSource()Z
    //#output(com.dmdirc.addons.nowplaying.NowPlayingPlugin__static_init): __Dispatch_Table.loadSettings()V
    //#output(com.dmdirc.addons.nowplaying.NowPlayingPlugin__static_init): __Dispatch_Table.onLoad()V
    //#output(com.dmdirc.addons.nowplaying.NowPlayingPlugin__static_init): __Dispatch_Table.onUnload()V
    //#output(com.dmdirc.addons.nowplaying.NowPlayingPlugin__static_init): __Dispatch_Table.processEvent(Lcom/dmdirc/actions/interfaces/ActionType;Ljava/lang/StringBuffer;[Ljava/lang/Object;)V
    //#output(com.dmdirc.addons.nowplaying.NowPlayingPlugin__static_init): __Dispatch_Table.removePlugin(Lcom/dmdirc/plugins/PluginInfo;)V
    //#output(com.dmdirc.addons.nowplaying.NowPlayingPlugin__static_init): __Dispatch_Table.saveSettings(Ljava/util/List;)V
    //#output(com.dmdirc.addons.nowplaying.NowPlayingPlugin__static_init): __Dispatch_Table.showConfig(Lcom/dmdirc/config/prefs/PreferencesManager;)V
    //#post(com.dmdirc.addons.nowplaying.NowPlayingPlugin__static_init): __Descendant_Table[com/dmdirc/addons/nowplaying/NowPlayingPlugin] == &__Dispatch_Table
    //#post(com.dmdirc.addons.nowplaying.NowPlayingPlugin__static_init): __Dispatch_Table.addPlugin(Lcom/dmdirc/plugins/PluginInfo;)V == &addPlugin
    //#post(com.dmdirc.addons.nowplaying.NowPlayingPlugin__static_init): __Dispatch_Table.addSourceToOrder(Lcom/dmdirc/addons/nowplaying/MediaSource;)V == &addSourceToOrder
    //#post(com.dmdirc.addons.nowplaying.NowPlayingPlugin__static_init): __Dispatch_Table.doSubstitution(Ljava/lang/String;Lcom/dmdirc/addons/nowplaying/MediaSource;)Ljava/lang/String; == &doSubstitution
    //#post(com.dmdirc.addons.nowplaying.NowPlayingPlugin__static_init): __Dispatch_Table.getBestSource()Lcom/dmdirc/addons/nowplaying/MediaSource; == &getBestSource
    //#post(com.dmdirc.addons.nowplaying.NowPlayingPlugin__static_init): __Dispatch_Table.getSource(Ljava/lang/String;)Lcom/dmdirc/addons/nowplaying/MediaSource; == &getSource
    //#post(com.dmdirc.addons.nowplaying.NowPlayingPlugin__static_init): __Dispatch_Table.getSources()Ljava/util/List; == &getSources
    //#post(com.dmdirc.addons.nowplaying.NowPlayingPlugin__static_init): __Dispatch_Table.hasRunningSource()Z == &hasRunningSource
    //#post(com.dmdirc.addons.nowplaying.NowPlayingPlugin__static_init): __Dispatch_Table.loadSettings()V == &loadSettings
    //#post(com.dmdirc.addons.nowplaying.NowPlayingPlugin__static_init): __Dispatch_Table.onLoad()V == &onLoad
    //#post(com.dmdirc.addons.nowplaying.NowPlayingPlugin__static_init): __Dispatch_Table.onUnload()V == &onUnload
    //#post(com.dmdirc.addons.nowplaying.NowPlayingPlugin__static_init): __Dispatch_Table.processEvent(Lcom/dmdirc/actions/interfaces/ActionType;Ljava/lang/StringBuffer;[Ljava/lang/Object;)V == &processEvent
    //#post(com.dmdirc.addons.nowplaying.NowPlayingPlugin__static_init): __Dispatch_Table.removePlugin(Lcom/dmdirc/plugins/PluginInfo;)V == &removePlugin
    //#post(com.dmdirc.addons.nowplaying.NowPlayingPlugin__static_init): __Dispatch_Table.saveSettings(Ljava/util/List;)V == &saveSettings
    //#post(com.dmdirc.addons.nowplaying.NowPlayingPlugin__static_init): __Dispatch_Table.showConfig(Lcom/dmdirc/config/prefs/PreferencesManager;)V == &showConfig
    //#NowPlayingPlugin.java:: end of method: com.dmdirc.addons.nowplaying.NowPlayingPlugin.com.dmdirc.addons.nowplaying.NowPlayingPlugin__static_init
    //#NowPlayingPlugin.java:: end of class: com.dmdirc.addons.nowplaying.NowPlayingPlugin
