//# 5 errors, 708 messages
//#
/*
    //#ConditionTree.java:1:1: class: com.dmdirc.actions.ConditionTree$OPERATION
    //#ConditionTree.java:1:1: class: com.dmdirc.actions.ConditionTree$1
    //#ConditionTree.java:1:1: class: com.dmdirc.actions.ConditionTree
    //#ConditionTree.java:1:1: method: com.dmdirc.actions.ConditionTree.com.dmdirc.actions.ConditionTree__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.actions;

import java.util.ArrayDeque;
import java.util.Deque;

/**
 * A condition tree specifies in which order a group of conditions will be
 * executed.
 *
 * @author chris
 */
public class ConditionTree {

    /** The possible operations on a condition tree. */
    public static enum OPERATION {
    //#ConditionTree.java:37: method: ConditionTree$OPERATION[] com.dmdirc.actions.ConditionTree$OPERATION.values()
    //#input(ConditionTree$OPERATION[] values()): $VALUES
    //#input(ConditionTree$OPERATION[] values()): $VALUES.length
    //#input(ConditionTree$OPERATION[] values()): $VALUES[0..5]
    //#output(ConditionTree$OPERATION[] values()): new ConditionTree$OPERATION[](values#1) num objects
    //#output(ConditionTree$OPERATION[] values()): return_value.length
    //#output(ConditionTree$OPERATION[] values()): return_value[0..5]
    //#output(ConditionTree$OPERATION[] values()): return_value
    //#new obj(ConditionTree$OPERATION[] values()): new ConditionTree$OPERATION[](values#1)
    //#pre[1] (ConditionTree$OPERATION[] values()): (soft) init'ed($VALUES[0..5])
    //#post(ConditionTree$OPERATION[] values()): return_value == &new ConditionTree$OPERATION[](values#1)
    //#post(ConditionTree$OPERATION[] values()): new ConditionTree$OPERATION[](values#1) num objects == 1
    //#post(ConditionTree$OPERATION[] values()): return_value.length == 5
    //#post(ConditionTree$OPERATION[] values()): return_value[0..5] == One-of{$VALUES[0..5], undefined}
    //#ConditionTree.java:37: end of method: ConditionTree$OPERATION[] com.dmdirc.actions.ConditionTree$OPERATION.values()
    //#ConditionTree.java:37: method: ConditionTree$OPERATION com.dmdirc.actions.ConditionTree$OPERATION.valueOf(String)
    //#input(ConditionTree$OPERATION valueOf(String)): __Descendant_Table[com/dmdirc/actions/ConditionTree$OPERATION]
    //#input(ConditionTree$OPERATION valueOf(String)): __Descendant_Table[others]
    //#input(ConditionTree$OPERATION valueOf(String)): name
    //#output(ConditionTree$OPERATION valueOf(String)): return_value
    //#presumption(ConditionTree$OPERATION valueOf(String)): java.lang.Enum:valueOf(...).__Tag@37 == com/dmdirc/actions/ConditionTree$OPERATION
    //#post(ConditionTree$OPERATION valueOf(String)): init'ed(return_value)
    //#ConditionTree.java:37: end of method: ConditionTree$OPERATION com.dmdirc.actions.ConditionTree$OPERATION.valueOf(String)
    //#ConditionTree.java:37: method: void com.dmdirc.actions.ConditionTree$OPERATION.com.dmdirc.actions.ConditionTree$OPERATION(String, int)
    //#input(void com.dmdirc.actions.ConditionTree$OPERATION(String, int)): Param_1
    //#input(void com.dmdirc.actions.ConditionTree$OPERATION(String, int)): Param_2
    //#input(void com.dmdirc.actions.ConditionTree$OPERATION(String, int)): this
    //#ConditionTree.java:37: end of method: void com.dmdirc.actions.ConditionTree$OPERATION.com.dmdirc.actions.ConditionTree$OPERATION(String, int)
        /** Only passes if both subtrees are true. */
        AND,
    //#ConditionTree.java:39: method: com.dmdirc.actions.ConditionTree$OPERATION.com.dmdirc.actions.ConditionTree$OPERATION__static_init
    //#output(com.dmdirc.actions.ConditionTree$OPERATION__static_init): $VALUES
    //#output(com.dmdirc.actions.ConditionTree$OPERATION__static_init): AND
    //#output(com.dmdirc.actions.ConditionTree$OPERATION__static_init): NOOP
    //#output(com.dmdirc.actions.ConditionTree$OPERATION__static_init): NOT
    //#output(com.dmdirc.actions.ConditionTree$OPERATION__static_init): OR
    //#output(com.dmdirc.actions.ConditionTree$OPERATION__static_init): VAR
    //#output(com.dmdirc.actions.ConditionTree$OPERATION__static_init): __Descendant_Table[com/dmdirc/actions/ConditionTree$OPERATION]
    //#output(com.dmdirc.actions.ConditionTree$OPERATION__static_init): new ConditionTree$OPERATION(ConditionTree$OPERATION__static_init#1) num objects
    //#output(com.dmdirc.actions.ConditionTree$OPERATION__static_init): AND.__Tag
    //#output(com.dmdirc.actions.ConditionTree$OPERATION__static_init): new ConditionTree$OPERATION(ConditionTree$OPERATION__static_init#2) num objects
    //#output(com.dmdirc.actions.ConditionTree$OPERATION__static_init): OR.__Tag
    //#output(com.dmdirc.actions.ConditionTree$OPERATION__static_init): new ConditionTree$OPERATION(ConditionTree$OPERATION__static_init#3) num objects
    //#output(com.dmdirc.actions.ConditionTree$OPERATION__static_init): VAR.__Tag
    //#output(com.dmdirc.actions.ConditionTree$OPERATION__static_init): new ConditionTree$OPERATION(ConditionTree$OPERATION__static_init#4) num objects
    //#output(com.dmdirc.actions.ConditionTree$OPERATION__static_init): NOT.__Tag
    //#output(com.dmdirc.actions.ConditionTree$OPERATION__static_init): new ConditionTree$OPERATION(ConditionTree$OPERATION__static_init#5) num objects
    //#output(com.dmdirc.actions.ConditionTree$OPERATION__static_init): NOOP.__Tag
    //#output(com.dmdirc.actions.ConditionTree$OPERATION__static_init): new ConditionTree$OPERATION[](ConditionTree$OPERATION__static_init#6) num objects
    //#output(com.dmdirc.actions.ConditionTree$OPERATION__static_init): $VALUES.length
    //#output(com.dmdirc.actions.ConditionTree$OPERATION__static_init): $VALUES[0]
    //#output(com.dmdirc.actions.ConditionTree$OPERATION__static_init): $VALUES[1]
    //#output(com.dmdirc.actions.ConditionTree$OPERATION__static_init): $VALUES[2]
    //#output(com.dmdirc.actions.ConditionTree$OPERATION__static_init): $VALUES[3]
    //#output(com.dmdirc.actions.ConditionTree$OPERATION__static_init): $VALUES[4]
    //#new obj(com.dmdirc.actions.ConditionTree$OPERATION__static_init): new ConditionTree$OPERATION(ConditionTree$OPERATION__static_init#1)
    //#new obj(com.dmdirc.actions.ConditionTree$OPERATION__static_init): new ConditionTree$OPERATION(ConditionTree$OPERATION__static_init#2)
    //#new obj(com.dmdirc.actions.ConditionTree$OPERATION__static_init): new ConditionTree$OPERATION(ConditionTree$OPERATION__static_init#3)
    //#new obj(com.dmdirc.actions.ConditionTree$OPERATION__static_init): new ConditionTree$OPERATION(ConditionTree$OPERATION__static_init#4)
    //#new obj(com.dmdirc.actions.ConditionTree$OPERATION__static_init): new ConditionTree$OPERATION(ConditionTree$OPERATION__static_init#5)
    //#new obj(com.dmdirc.actions.ConditionTree$OPERATION__static_init): new ConditionTree$OPERATION[](ConditionTree$OPERATION__static_init#6)
    //#post(com.dmdirc.actions.ConditionTree$OPERATION__static_init): $VALUES == &new ConditionTree$OPERATION[](ConditionTree$OPERATION__static_init#6)
    //#post(com.dmdirc.actions.ConditionTree$OPERATION__static_init): AND == &new ConditionTree$OPERATION(ConditionTree$OPERATION__static_init#1)
    //#post(com.dmdirc.actions.ConditionTree$OPERATION__static_init): $VALUES[0] == &new ConditionTree$OPERATION(ConditionTree$OPERATION__static_init#1)
    //#post(com.dmdirc.actions.ConditionTree$OPERATION__static_init): NOOP == &new ConditionTree$OPERATION(ConditionTree$OPERATION__static_init#5)
    //#post(com.dmdirc.actions.ConditionTree$OPERATION__static_init): $VALUES[4] == &new ConditionTree$OPERATION(ConditionTree$OPERATION__static_init#5)
    //#post(com.dmdirc.actions.ConditionTree$OPERATION__static_init): NOT == &new ConditionTree$OPERATION(ConditionTree$OPERATION__static_init#4)
    //#post(com.dmdirc.actions.ConditionTree$OPERATION__static_init): $VALUES[3] == &new ConditionTree$OPERATION(ConditionTree$OPERATION__static_init#4)
    //#post(com.dmdirc.actions.ConditionTree$OPERATION__static_init): OR == &new ConditionTree$OPERATION(ConditionTree$OPERATION__static_init#2)
    //#post(com.dmdirc.actions.ConditionTree$OPERATION__static_init): $VALUES[1] == &new ConditionTree$OPERATION(ConditionTree$OPERATION__static_init#2)
    //#post(com.dmdirc.actions.ConditionTree$OPERATION__static_init): VAR == &new ConditionTree$OPERATION(ConditionTree$OPERATION__static_init#3)
    //#post(com.dmdirc.actions.ConditionTree$OPERATION__static_init): $VALUES[2] == &new ConditionTree$OPERATION(ConditionTree$OPERATION__static_init#3)
    //#post(com.dmdirc.actions.ConditionTree$OPERATION__static_init): __Descendant_Table[com/dmdirc/actions/ConditionTree$OPERATION] == &__Dispatch_Table
    //#post(com.dmdirc.actions.ConditionTree$OPERATION__static_init): new ConditionTree$OPERATION(ConditionTree$OPERATION__static_init#1) num objects == 1
    //#post(com.dmdirc.actions.ConditionTree$OPERATION__static_init): new ConditionTree$OPERATION(ConditionTree$OPERATION__static_init#2) num objects == 1
    //#post(com.dmdirc.actions.ConditionTree$OPERATION__static_init): new ConditionTree$OPERATION(ConditionTree$OPERATION__static_init#3) num objects == 1
    //#post(com.dmdirc.actions.ConditionTree$OPERATION__static_init): new ConditionTree$OPERATION(ConditionTree$OPERATION__static_init#4) num objects == 1
    //#post(com.dmdirc.actions.ConditionTree$OPERATION__static_init): new ConditionTree$OPERATION(ConditionTree$OPERATION__static_init#5) num objects == 1
    //#post(com.dmdirc.actions.ConditionTree$OPERATION__static_init): new ConditionTree$OPERATION[](ConditionTree$OPERATION__static_init#6) num objects == 1
    //#post(com.dmdirc.actions.ConditionTree$OPERATION__static_init): AND.__Tag == com/dmdirc/actions/ConditionTree$OPERATION
    //#post(com.dmdirc.actions.ConditionTree$OPERATION__static_init): OR.__Tag == com/dmdirc/actions/ConditionTree$OPERATION
    //#post(com.dmdirc.actions.ConditionTree$OPERATION__static_init): VAR.__Tag == com/dmdirc/actions/ConditionTree$OPERATION
    //#post(com.dmdirc.actions.ConditionTree$OPERATION__static_init): NOT.__Tag == com/dmdirc/actions/ConditionTree$OPERATION
    //#post(com.dmdirc.actions.ConditionTree$OPERATION__static_init): NOOP.__Tag == com/dmdirc/actions/ConditionTree$OPERATION
    //#post(com.dmdirc.actions.ConditionTree$OPERATION__static_init): $VALUES.length == 5
    //#unanalyzed(com.dmdirc.actions.ConditionTree$OPERATION__static_init): Effects-of-calling:java.lang.Enum
        /** Passes if either of the subtrees are true. */
        OR,
        /** Passes if the specified argument is true. */
        VAR,
        /** Only passes iof the left subtree fails to pass. */
        NOT,
        /** Doesn't do anything (an empty tree). */
        NOOP
    //#ConditionTree.java:47: end of method: com.dmdirc.actions.ConditionTree$OPERATION.com.dmdirc.actions.ConditionTree$OPERATION__static_init
    }

    /** The left subtree of this tree. */
    private ConditionTree leftArg = null;

    /** The right subtree of this tree. */
    private ConditionTree rightArg = null;

    /** The argument of this tree (only used for VAR ops). */
    private int argument = -1;

    /** The operation that this tree performs. */
    private final OPERATION op;

    /**
     * Creates a new ConditionTree for a binary operation.
     *
     * @param op The binary operation to perform
     * @param leftArg The left argument/subtree
     * @param rightArg The right argument/subtree
     */
    private ConditionTree(final OPERATION op, final ConditionTree leftArg,
            final ConditionTree rightArg) {
    //#ConditionTree.java:70: method: void com.dmdirc.actions.ConditionTree.com.dmdirc.actions.ConditionTree(ConditionTree$OPERATION, ConditionTree, ConditionTree)
    //#input(void com.dmdirc.actions.ConditionTree(ConditionTree$OPERATION, ConditionTree, ConditionTree)): leftArg
    //#input(void com.dmdirc.actions.ConditionTree(ConditionTree$OPERATION, ConditionTree, ConditionTree)): op
    //#input(void com.dmdirc.actions.ConditionTree(ConditionTree$OPERATION, ConditionTree, ConditionTree)): rightArg
    //#input(void com.dmdirc.actions.ConditionTree(ConditionTree$OPERATION, ConditionTree, ConditionTree)): this
    //#output(void com.dmdirc.actions.ConditionTree(ConditionTree$OPERATION, ConditionTree, ConditionTree)): this.argument
    //#output(void com.dmdirc.actions.ConditionTree(ConditionTree$OPERATION, ConditionTree, ConditionTree)): this.leftArg
    //#output(void com.dmdirc.actions.ConditionTree(ConditionTree$OPERATION, ConditionTree, ConditionTree)): this.op
    //#output(void com.dmdirc.actions.ConditionTree(ConditionTree$OPERATION, ConditionTree, ConditionTree)): this.rightArg
    //#post(void com.dmdirc.actions.ConditionTree(ConditionTree$OPERATION, ConditionTree, ConditionTree)): this.argument == -1
    //#post(void com.dmdirc.actions.ConditionTree(ConditionTree$OPERATION, ConditionTree, ConditionTree)): this.leftArg == leftArg
    //#post(void com.dmdirc.actions.ConditionTree(ConditionTree$OPERATION, ConditionTree, ConditionTree)): init'ed(this.leftArg)
    //#post(void com.dmdirc.actions.ConditionTree(ConditionTree$OPERATION, ConditionTree, ConditionTree)): this.op == op
    //#post(void com.dmdirc.actions.ConditionTree(ConditionTree$OPERATION, ConditionTree, ConditionTree)): init'ed(this.op)
    //#post(void com.dmdirc.actions.ConditionTree(ConditionTree$OPERATION, ConditionTree, ConditionTree)): this.rightArg == rightArg
    //#post(void com.dmdirc.actions.ConditionTree(ConditionTree$OPERATION, ConditionTree, ConditionTree)): init'ed(this.rightArg)
        this.op = op;
        this.leftArg = leftArg;
        this.rightArg = rightArg;
    }
    //#ConditionTree.java:74: end of method: void com.dmdirc.actions.ConditionTree.com.dmdirc.actions.ConditionTree(ConditionTree$OPERATION, ConditionTree, ConditionTree)

    /**
     * Creates a new ConditionTree for a unary operation.
     *
     * @param op
     * @param argument
     */
    private ConditionTree(final OPERATION op, final ConditionTree argument) {
    //#ConditionTree.java:82: method: void com.dmdirc.actions.ConditionTree.com.dmdirc.actions.ConditionTree(ConditionTree$OPERATION, ConditionTree)
    //#input(void com.dmdirc.actions.ConditionTree(ConditionTree$OPERATION, ConditionTree)): argument
    //#input(void com.dmdirc.actions.ConditionTree(ConditionTree$OPERATION, ConditionTree)): op
    //#input(void com.dmdirc.actions.ConditionTree(ConditionTree$OPERATION, ConditionTree)): this
    //#output(void com.dmdirc.actions.ConditionTree(ConditionTree$OPERATION, ConditionTree)): this.argument
    //#output(void com.dmdirc.actions.ConditionTree(ConditionTree$OPERATION, ConditionTree)): this.leftArg
    //#output(void com.dmdirc.actions.ConditionTree(ConditionTree$OPERATION, ConditionTree)): this.op
    //#output(void com.dmdirc.actions.ConditionTree(ConditionTree$OPERATION, ConditionTree)): this.rightArg
    //#post(void com.dmdirc.actions.ConditionTree(ConditionTree$OPERATION, ConditionTree)): this.argument == -1
    //#post(void com.dmdirc.actions.ConditionTree(ConditionTree$OPERATION, ConditionTree)): this.leftArg == argument
    //#post(void com.dmdirc.actions.ConditionTree(ConditionTree$OPERATION, ConditionTree)): init'ed(this.leftArg)
    //#post(void com.dmdirc.actions.ConditionTree(ConditionTree$OPERATION, ConditionTree)): this.op == op
    //#post(void com.dmdirc.actions.ConditionTree(ConditionTree$OPERATION, ConditionTree)): init'ed(this.op)
    //#post(void com.dmdirc.actions.ConditionTree(ConditionTree$OPERATION, ConditionTree)): this.rightArg == null
        this.op = op;
        this.leftArg = argument;
    }
    //#ConditionTree.java:85: end of method: void com.dmdirc.actions.ConditionTree.com.dmdirc.actions.ConditionTree(ConditionTree$OPERATION, ConditionTree)

    /**
     * Creates a new ConditionTree for a VAR operation with the specified
     * argument number.
     *
     * @param argument The number of the argument that's to be tested.
     */
    private ConditionTree(final int argument) {
    //#ConditionTree.java:93: method: void com.dmdirc.actions.ConditionTree.com.dmdirc.actions.ConditionTree(int)
    //#input(void com.dmdirc.actions.ConditionTree(int)): argument
    //#input(void com.dmdirc.actions.ConditionTree(int)): com/dmdirc/actions/ConditionTree$OPERATION.VAR
    //#input(void com.dmdirc.actions.ConditionTree(int)): this
    //#output(void com.dmdirc.actions.ConditionTree(int)): this.argument
    //#output(void com.dmdirc.actions.ConditionTree(int)): this.leftArg
    //#output(void com.dmdirc.actions.ConditionTree(int)): this.op
    //#output(void com.dmdirc.actions.ConditionTree(int)): this.rightArg
    //#post(void com.dmdirc.actions.ConditionTree(int)): this.argument == argument
    //#post(void com.dmdirc.actions.ConditionTree(int)): init'ed(this.argument)
    //#post(void com.dmdirc.actions.ConditionTree(int)): this.leftArg == null
    //#post(void com.dmdirc.actions.ConditionTree(int)): this.rightArg == null
    //#post(void com.dmdirc.actions.ConditionTree(int)): this.op == &com.dmdirc.actions.ConditionTree$OPERATION__static_init.new ConditionTree$OPERATION(ConditionTree$OPERATION__static_init#3)
        this.op = OPERATION.VAR;
        this.argument = argument;
    }
    //#ConditionTree.java:96: end of method: void com.dmdirc.actions.ConditionTree.com.dmdirc.actions.ConditionTree(int)

    /**
     * Creates a new ConditionTree for a NOOP operation.
     */
    private ConditionTree() {
    //#ConditionTree.java:101: method: void com.dmdirc.actions.ConditionTree.com.dmdirc.actions.ConditionTree()
    //#input(void com.dmdirc.actions.ConditionTree()): com/dmdirc/actions/ConditionTree$OPERATION.NOOP
    //#input(void com.dmdirc.actions.ConditionTree()): this
    //#output(void com.dmdirc.actions.ConditionTree()): this.argument
    //#output(void com.dmdirc.actions.ConditionTree()): this.leftArg
    //#output(void com.dmdirc.actions.ConditionTree()): this.op
    //#output(void com.dmdirc.actions.ConditionTree()): this.rightArg
    //#post(void com.dmdirc.actions.ConditionTree()): this.argument == -1
    //#post(void com.dmdirc.actions.ConditionTree()): this.leftArg == null
    //#post(void com.dmdirc.actions.ConditionTree()): this.rightArg == null
    //#post(void com.dmdirc.actions.ConditionTree()): this.op == &com.dmdirc.actions.ConditionTree$OPERATION__static_init.new ConditionTree$OPERATION(ConditionTree$OPERATION__static_init#5)
        this.op = OPERATION.NOOP;
    }
    //#ConditionTree.java:103: end of method: void com.dmdirc.actions.ConditionTree.com.dmdirc.actions.ConditionTree()

    /**
     * Retrieves the highest argument number that is used in this condition tree.
     *
     * @return The highest argument number used in this tree
     */
    public int getMaximumArgument() {
        if (this.op == OPERATION.NOOP) {
    //#ConditionTree.java:111: method: int com.dmdirc.actions.ConditionTree.getMaximumArgument()
    //#input(int getMaximumArgument()): __Descendant_Table[com/dmdirc/actions/ConditionTree]
    //#input(int getMaximumArgument()): __Descendant_Table[others]
    //#input(int getMaximumArgument()): __Dispatch_Table.getMaximumArgument()I
    //#input(int getMaximumArgument()): com/dmdirc/actions/ConditionTree$OPERATION.NOOP
    //#input(int getMaximumArgument()): com/dmdirc/actions/ConditionTree$OPERATION.NOT
    //#input(int getMaximumArgument()): com/dmdirc/actions/ConditionTree$OPERATION.VAR
    //#input(int getMaximumArgument()): this
    //#input(int getMaximumArgument()): this...__Tag
    //#input(int getMaximumArgument()): this...argument
    //#input(int getMaximumArgument()): this...leftArg
    //#input(int getMaximumArgument()): this...op
    //#input(int getMaximumArgument()): this...rightArg
    //#input(int getMaximumArgument()): this.argument
    //#input(int getMaximumArgument()): this.leftArg
    //#input(int getMaximumArgument()): this.op
    //#input(int getMaximumArgument()): this.rightArg
    //#output(int getMaximumArgument()): return_value
    //#pre[2] (int getMaximumArgument()): (soft) this...__Tag == com/dmdirc/actions/ConditionTree
    //#pre[3] (int getMaximumArgument()): (soft) init'ed(this...argument)
    //#pre[4] (int getMaximumArgument()): (soft) this...leftArg != null
    //#pre[6] (int getMaximumArgument()): (soft) this...rightArg != null
    //#pre[7] (int getMaximumArgument()): (soft) init'ed(this.argument)
    //#pre[8] (int getMaximumArgument()): (soft) this.leftArg != null
    //#pre[10] (int getMaximumArgument()): (soft) this.rightArg != null
    //#post(int getMaximumArgument()): init'ed(return_value)
    //#unanalyzed(int getMaximumArgument()): Effects-of-calling:getMaximumArgument
    //#unanalyzed(int getMaximumArgument()): Effects-of-calling:java.lang.Math:max
            return 0;
        } else if (this.op == OPERATION.VAR) {
            return argument;
        } else if (this.op == OPERATION.NOT) {
            return leftArg.getMaximumArgument();
        } else {
            return Math.max(leftArg.getMaximumArgument(), rightArg.getMaximumArgument());
    //#ConditionTree.java:118: end of method: int com.dmdirc.actions.ConditionTree.getMaximumArgument()
        }
    }

    /**
     * Evaluates this tree with the specified conditions. Returns the result
     * of the evaluation.
     *
     * @param conditions The binary values of each of the conditions used in
     * this three
     * @return The result of the evaluation of this tree
     */
    public boolean evaluate(final boolean[] conditions) {
        switch (op) {
    //#ConditionTree.java:131: method: com.dmdirc.actions.ConditionTree$1.com.dmdirc.actions.ConditionTree$1__static_init
    //#ConditionTree.java:131: Warning: method not available - call not analyzed
    //#    call on int com.dmdirc.actions.ConditionTree$OPERATION:ordinal()
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.actions.ConditionTree$1
    //#    method: com.dmdirc.actions.ConditionTree$1__static_init
    //#    unanalyzed callee: int com.dmdirc.actions.ConditionTree$OPERATION:ordinal()
    //#input(com.dmdirc.actions.ConditionTree$1__static_init): com.dmdirc.actions.ConditionTree$OPERATION__static_init.new ConditionTree$OPERATION[](ConditionTree$OPERATION__static_init#6).length
    //#input(com.dmdirc.actions.ConditionTree$1__static_init): com.dmdirc.actions.ConditionTree$OPERATION__static_init.new ConditionTree$OPERATION[](ConditionTree$OPERATION__static_init#6)[0..5]
    //#input(com.dmdirc.actions.ConditionTree$1__static_init): com/dmdirc/actions/ConditionTree$OPERATION.$VALUES
    //#input(com.dmdirc.actions.ConditionTree$1__static_init): com/dmdirc/actions/ConditionTree$OPERATION.AND
    //#input(com.dmdirc.actions.ConditionTree$1__static_init): com/dmdirc/actions/ConditionTree$OPERATION.NOT
    //#input(com.dmdirc.actions.ConditionTree$1__static_init): com/dmdirc/actions/ConditionTree$OPERATION.OR
    //#input(com.dmdirc.actions.ConditionTree$1__static_init): com/dmdirc/actions/ConditionTree$OPERATION.VAR
    //#output(com.dmdirc.actions.ConditionTree$1__static_init): $SwitchMap$com$dmdirc$actions$ConditionTree$OPERATION
    //#output(com.dmdirc.actions.ConditionTree$1__static_init): __Descendant_Table[com/dmdirc/actions/ConditionTree$1]
    //#output(com.dmdirc.actions.ConditionTree$1__static_init): new int[](ConditionTree$1__static_init#1) num objects
    //#output(com.dmdirc.actions.ConditionTree$1__static_init): $SwitchMap$com$dmdirc$actions$ConditionTree$OPERATION.length
    //#output(com.dmdirc.actions.ConditionTree$1__static_init): $SwitchMap$com$dmdirc$actions$ConditionTree$OPERATION[0..4_294_967_295]
    //#new obj(com.dmdirc.actions.ConditionTree$1__static_init): new int[](ConditionTree$1__static_init#1)
    //#pre[1] (com.dmdirc.actions.ConditionTree$1__static_init): (soft) init'ed(com.dmdirc.actions.ConditionTree$OPERATION__static_init.new ConditionTree$OPERATION[](ConditionTree$OPERATION__static_init#6)[0..5])
    //#presumption(com.dmdirc.actions.ConditionTree$1__static_init): com.dmdirc.actions.ConditionTree_OPERATION:ordinal(...)@131 in {0..4}
    //#presumption(com.dmdirc.actions.ConditionTree$1__static_init): com.dmdirc.actions.ConditionTree_OPERATION:ordinal(...)@131 in {0..4}
    //#presumption(com.dmdirc.actions.ConditionTree$1__static_init): com.dmdirc.actions.ConditionTree_OPERATION:ordinal(...)@131 in {0..4}
    //#presumption(com.dmdirc.actions.ConditionTree$1__static_init): com.dmdirc.actions.ConditionTree_OPERATION:ordinal(...)@131 in {0..4}
    //#presumption(com.dmdirc.actions.ConditionTree$1__static_init): com.dmdirc.actions.ConditionTree_OPERATION:ordinal(...)@131 - values(...).length in range
    //#presumption(com.dmdirc.actions.ConditionTree$1__static_init): com.dmdirc.actions.ConditionTree_OPERATION:ordinal(...)@131 - values(...).length in range
    //#presumption(com.dmdirc.actions.ConditionTree$1__static_init): com.dmdirc.actions.ConditionTree_OPERATION:ordinal(...)@131 - values(...).length in range
    //#presumption(com.dmdirc.actions.ConditionTree$1__static_init): com.dmdirc.actions.ConditionTree_OPERATION:ordinal(...)@131 - values(...).length in range
    //#post(com.dmdirc.actions.ConditionTree$1__static_init): $SwitchMap$com$dmdirc$actions$ConditionTree$OPERATION == &new int[](ConditionTree$1__static_init#1)
    //#post(com.dmdirc.actions.ConditionTree$1__static_init): __Descendant_Table[com/dmdirc/actions/ConditionTree$1] == &__Dispatch_Table
    //#post(com.dmdirc.actions.ConditionTree$1__static_init): new int[](ConditionTree$1__static_init#1) num objects == 1
    //#post(com.dmdirc.actions.ConditionTree$1__static_init): $SwitchMap$com$dmdirc$actions$ConditionTree$OPERATION.length == 5
    //#post(com.dmdirc.actions.ConditionTree$1__static_init): $SwitchMap$com$dmdirc$actions$ConditionTree$OPERATION[0..4_294_967_295] in {0..4}, if init'ed
    //#ConditionTree.java:131: end of method: com.dmdirc.actions.ConditionTree$1.com.dmdirc.actions.ConditionTree$1__static_init
    //#ConditionTree.java:131: method: bool com.dmdirc.actions.ConditionTree.evaluate(bool[])
    //#ConditionTree.java:131: Warning: method not available - call not analyzed
    //#    call on int com.dmdirc.actions.ConditionTree$OPERATION:ordinal()
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.actions.ConditionTree
    //#    method: bool evaluate(bool[])
    //#    unanalyzed callee: int com.dmdirc.actions.ConditionTree$OPERATION:ordinal()
    //#input(bool evaluate(bool[])): __Descendant_Table[com/dmdirc/actions/ConditionTree]
    //#input(bool evaluate(bool[])): __Descendant_Table[others]
    //#input(bool evaluate(bool[])): __Dispatch_Table.evaluate([Z)Z
    //#input(bool evaluate(bool[])): com.dmdirc.actions.ConditionTree$1__static_init.new int[](ConditionTree$1__static_init#1).length
    //#input(bool evaluate(bool[])): com.dmdirc.actions.ConditionTree$1__static_init.new int[](ConditionTree$1__static_init#1)[0..4_294_967_295]
    //#input(bool evaluate(bool[])): com/dmdirc/actions/ConditionTree$1.$SwitchMap$com$dmdirc$actions$ConditionTree$OPERATION
    //#input(bool evaluate(bool[])): conditions
    //#input(bool evaluate(bool[])): conditions.length
    //#input(bool evaluate(bool[])): conditions[0..4_294_967_295]
    //#input(bool evaluate(bool[])): this
    //#input(bool evaluate(bool[])): this...__Tag
    //#input(bool evaluate(bool[])): this...argument
    //#input(bool evaluate(bool[])): this...leftArg
    //#input(bool evaluate(bool[])): this...op
    //#input(bool evaluate(bool[])): this...rightArg
    //#input(bool evaluate(bool[])): this.argument
    //#input(bool evaluate(bool[])): this.leftArg
    //#input(bool evaluate(bool[])): this.op
    //#input(bool evaluate(bool[])): this.rightArg
    //#output(bool evaluate(bool[])): return_value
    //#pre[14] (bool evaluate(bool[])): this.op != null
    //#pre[1] (bool evaluate(bool[])): (soft) init'ed(com.dmdirc.actions.ConditionTree$1__static_init.new int[](ConditionTree$1__static_init#1)[0..4_294_967_295])
    //#pre[2] (bool evaluate(bool[])): (soft) conditions != null
    //#pre[3] (bool evaluate(bool[])): (soft) conditions.length >= 1
    //#pre[4] (bool evaluate(bool[])): (soft) this.argument < conditions.length
    //#pre[5] (bool evaluate(bool[])): (soft) init'ed(conditions[0..4_294_967_295])
    //#pre[7] (bool evaluate(bool[])): (soft) this...__Tag == com/dmdirc/actions/ConditionTree
    //#pre[8] (bool evaluate(bool[])): (soft) this...argument >= 0
    //#pre[9] (bool evaluate(bool[])): (soft) this...leftArg != null
    //#pre[10] (bool evaluate(bool[])): (soft) this...op != null
    //#pre[11] (bool evaluate(bool[])): (soft) this...rightArg != null
    //#pre[12] (bool evaluate(bool[])): (soft) this.argument >= 0
    //#pre[13] (bool evaluate(bool[])): (soft) this.leftArg != null
    //#pre[15] (bool evaluate(bool[])): (soft) this.rightArg != null
    //#presumption(bool evaluate(bool[])): com.dmdirc.actions.ConditionTree_OPERATION:ordinal(...)@131 in {0..4}
    //#post(bool evaluate(bool[])): init'ed(return_value)
    //#unanalyzed(bool evaluate(bool[])): Effects-of-calling:com.dmdirc.actions.ConditionTree$OPERATION:ordinal
    //#unanalyzed(bool evaluate(bool[])): Effects-of-calling:evaluate
    //#test_vector(bool evaluate(bool[])): com.dmdirc.actions.ConditionTree$1__static_init.new int[](ConditionTree$1__static_init#1)[0..4_294_967_295]: {1}, {2}, {3}, {4}, {-2_147_483_648..0, 5..4_294_967_295}
            case VAR:
                return conditions[argument];
            case NOT:
                return !leftArg.evaluate(conditions);
    //#ConditionTree.java:135: ?precondition failure
    //#    com/dmdirc/actions/ConditionTree.evaluate: (soft) this.argument < conditions.length
    //#    severity: SUPPRESSED
    //#    class: com.dmdirc.actions.ConditionTree
    //#    method: bool evaluate(bool[])
    //#    basic block: bb_3
    //#    assertion: (soft) this.leftArg.argument < conditions.length
    //#    callee: bool com/dmdirc/actions/ConditionTree.evaluate(bool[])
    //#    callee assertion: (soft) this.argument < conditions.length
    //#    callee file: ConditionTree.java
    //#    callee precondition index: [4]
    //#    callee srcpos: 131
    //#    VN: -(this.leftArg.argument - conditions.length)
    //#    Expected: {1..+Inf}
    //#    Bad: {-4_294_967_294..0}
    //#    Attribs:  Int  Bad overlaps +/-1000  Soft  Bad < Exp
            case AND:
                return leftArg.evaluate(conditions) && rightArg.evaluate(conditions);
    //#ConditionTree.java:137: ?precondition failure
    //#    com/dmdirc/actions/ConditionTree.evaluate: (soft) this.argument < conditions.length
    //#    severity: SUPPRESSED
    //#    class: com.dmdirc.actions.ConditionTree
    //#    method: bool evaluate(bool[])
    //#    basic block: bb_7
    //#    assertion: (soft) this.leftArg.argument < conditions.length
    //#    callee: bool com/dmdirc/actions/ConditionTree.evaluate(bool[])
    //#    callee assertion: (soft) this.argument < conditions.length
    //#    callee file: ConditionTree.java
    //#    callee precondition index: [4]
    //#    callee srcpos: 131
    //#    VN: -(this.leftArg.argument - conditions.length)
    //#    Expected: {1..+Inf}
    //#    Bad: {-4_294_967_294..0}
    //#    Attribs:  Int  Bad overlaps +/-1000  Soft  Bad < Exp
    //#ConditionTree.java:137: ?precondition failure
    //#    com/dmdirc/actions/ConditionTree.evaluate: (soft) this.argument < conditions.length
    //#    severity: SUPPRESSED
    //#    class: com.dmdirc.actions.ConditionTree
    //#    method: bool evaluate(bool[])
    //#    basic block: bb_8
    //#    assertion: (soft) this.rightArg.argument < conditions.length
    //#    callee: bool com/dmdirc/actions/ConditionTree.evaluate(bool[])
    //#    callee assertion: (soft) this.argument < conditions.length
    //#    callee file: ConditionTree.java
    //#    callee precondition index: [4]
    //#    callee srcpos: 131
    //#    VN: -(this.rightArg.argument - conditions.length)
    //#    Expected: {1..+Inf}
    //#    Bad: {-4_294_967_294..0}
    //#    Attribs:  Int  Bad overlaps +/-1000  Soft  Bad < Exp
            case OR:
                return leftArg.evaluate(conditions) || rightArg.evaluate(conditions);
    //#ConditionTree.java:139: ?precondition failure
    //#    com/dmdirc/actions/ConditionTree.evaluate: (soft) this.argument < conditions.length
    //#    severity: SUPPRESSED
    //#    class: com.dmdirc.actions.ConditionTree
    //#    method: bool evaluate(bool[])
    //#    basic block: bb_12
    //#    assertion: (soft) this.leftArg.argument < conditions.length
    //#    callee: bool com/dmdirc/actions/ConditionTree.evaluate(bool[])
    //#    callee assertion: (soft) this.argument < conditions.length
    //#    callee file: ConditionTree.java
    //#    callee precondition index: [4]
    //#    callee srcpos: 131
    //#    VN: -(this.leftArg.argument - conditions.length)
    //#    Expected: {1..+Inf}
    //#    Bad: {-4_294_967_294..0}
    //#    Attribs:  Int  Bad overlaps +/-1000  Soft  Bad < Exp
    //#ConditionTree.java:139: ?precondition failure
    //#    com/dmdirc/actions/ConditionTree.evaluate: (soft) this.argument < conditions.length
    //#    severity: SUPPRESSED
    //#    class: com.dmdirc.actions.ConditionTree
    //#    method: bool evaluate(bool[])
    //#    basic block: bb_13
    //#    assertion: (soft) this.rightArg.argument < conditions.length
    //#    callee: bool com/dmdirc/actions/ConditionTree.evaluate(bool[])
    //#    callee assertion: (soft) this.argument < conditions.length
    //#    callee file: ConditionTree.java
    //#    callee precondition index: [4]
    //#    callee srcpos: 131
    //#    VN: -(this.rightArg.argument - conditions.length)
    //#    Expected: {1..+Inf}
    //#    Bad: {-4_294_967_294..0}
    //#    Attribs:  Int  Bad overlaps +/-1000  Soft  Bad < Exp
            default:
                return true;
    //#ConditionTree.java:141: end of method: bool com.dmdirc.actions.ConditionTree.evaluate(bool[])
        }
    }

    /** {@inheritDoc} */
    @Override
    public boolean equals(final Object obj) {
        return obj instanceof ConditionTree
    //#ConditionTree.java:148: method: bool com.dmdirc.actions.ConditionTree.equals(Object)
    //#input(bool equals(Object)): "!"._tainted
    //#input(bool equals(Object)): "&amp;"._tainted
    //#input(bool equals(Object)): "("._tainted
    //#input(bool equals(Object)): ")"._tainted
    //#input(bool equals(Object)): "|"._tainted
    //#input(bool equals(Object)): __Descendant_Table[com/dmdirc/actions/ConditionTree]
    //#input(bool equals(Object)): __Descendant_Table[others]
    //#input(bool equals(Object)): __Dispatch_Table.toString()Ljava/lang/String;
    //#input(bool equals(Object)): com.dmdirc.actions.ConditionTree$1__static_init.new int[](ConditionTree$1__static_init#1).length
    //#input(bool equals(Object)): com.dmdirc.actions.ConditionTree$1__static_init.new int[](ConditionTree$1__static_init#1)[0..4_294_967_295]
    //#input(bool equals(Object)): com/dmdirc/actions/ConditionTree$1.$SwitchMap$com$dmdirc$actions$ConditionTree$OPERATION
    //#input(bool equals(Object)): obj
    //#input(bool equals(Object)): obj..._tainted
    //#input(bool equals(Object)): obj.__Tag
    //#input(bool equals(Object)): obj.argument
    //#input(bool equals(Object)): obj.leftArg
    //#input(bool equals(Object)): obj.op
    //#input(bool equals(Object)): obj.rightArg
    //#input(bool equals(Object)): this
    //#input(bool equals(Object)): this..._tainted
    //#input(bool equals(Object)): this.__Tag
    //#input(bool equals(Object)): this.argument
    //#input(bool equals(Object)): this.leftArg
    //#input(bool equals(Object)): this.op
    //#input(bool equals(Object)): this.rightArg
    //#output(bool equals(Object)): return_value
    //#pre[1] (bool equals(Object)): (soft) init'ed(com.dmdirc.actions.ConditionTree$1__static_init.new int[](ConditionTree$1__static_init#1)[0..4_294_967_295])
    //#pre[5] (bool equals(Object)): (soft) init'ed(obj.argument)
    //#pre[6] (bool equals(Object)): (soft) init'ed(obj.leftArg)
    //#pre[7] (bool equals(Object)): (soft) obj.op != null
    //#pre[8] (bool equals(Object)): (soft) init'ed(obj.rightArg)
    //#pre[11] (bool equals(Object)): (soft) this.__Tag == com/dmdirc/actions/ConditionTree
    //#pre[12] (bool equals(Object)): (soft) init'ed(this.argument)
    //#pre[13] (bool equals(Object)): (soft) init'ed(this.leftArg)
    //#pre[14] (bool equals(Object)): (soft) this.op != null
    //#pre[15] (bool equals(Object)): (soft) init'ed(this.rightArg)
    //#post(bool equals(Object)): init'ed(return_value)
    //#unanalyzed(bool equals(Object)): Effects-of-calling:com.dmdirc.actions.ConditionTree$OPERATION:ordinal
    //#unanalyzed(bool equals(Object)): Effects-of-calling:java.lang.String:valueOf
    //#unanalyzed(bool equals(Object)): Effects-of-calling:java.lang.StringBuilder
    //#unanalyzed(bool equals(Object)): Effects-of-calling:java.lang.StringBuilder:append
    //#unanalyzed(bool equals(Object)): Effects-of-calling:java.lang.StringBuilder:toString
    //#ConditionTree.java:148: end of method: bool com.dmdirc.actions.ConditionTree.equals(Object)
                && toString().equals(((ConditionTree) obj).toString());
    }

    /** {@inheritDoc} */
    @Override
    public int hashCode() {
        return toString().hashCode();
    //#ConditionTree.java:155: method: int com.dmdirc.actions.ConditionTree.hashCode()
    //#input(int hashCode()): "!"._tainted
    //#input(int hashCode()): "&amp;"._tainted
    //#input(int hashCode()): "("._tainted
    //#input(int hashCode()): ")"._tainted
    //#input(int hashCode()): "|"._tainted
    //#input(int hashCode()): __Descendant_Table[com/dmdirc/actions/ConditionTree]
    //#input(int hashCode()): __Descendant_Table[others]
    //#input(int hashCode()): __Dispatch_Table.toString()Ljava/lang/String;
    //#input(int hashCode()): com.dmdirc.actions.ConditionTree$1__static_init.new int[](ConditionTree$1__static_init#1).length
    //#input(int hashCode()): com.dmdirc.actions.ConditionTree$1__static_init.new int[](ConditionTree$1__static_init#1)[0..4_294_967_295]
    //#input(int hashCode()): com/dmdirc/actions/ConditionTree$1.$SwitchMap$com$dmdirc$actions$ConditionTree$OPERATION
    //#input(int hashCode()): this
    //#input(int hashCode()): this..._tainted
    //#input(int hashCode()): this.__Tag
    //#input(int hashCode()): this.argument
    //#input(int hashCode()): this.leftArg
    //#input(int hashCode()): this.op
    //#input(int hashCode()): this.rightArg
    //#output(int hashCode()): return_value
    //#pre[4] (int hashCode()): this.__Tag == com/dmdirc/actions/ConditionTree
    //#pre[7] (int hashCode()): this.op != null
    //#pre[1] (int hashCode()): (soft) init'ed(com.dmdirc.actions.ConditionTree$1__static_init.new int[](ConditionTree$1__static_init#1)[0..4_294_967_295])
    //#pre[5] (int hashCode()): (soft) init'ed(this.argument)
    //#pre[6] (int hashCode()): (soft) init'ed(this.leftArg)
    //#pre[8] (int hashCode()): (soft) init'ed(this.rightArg)
    //#post(int hashCode()): init'ed(return_value)
    //#unanalyzed(int hashCode()): Effects-of-calling:com.dmdirc.actions.ConditionTree$OPERATION:ordinal
    //#unanalyzed(int hashCode()): Effects-of-calling:java.lang.String:valueOf
    //#unanalyzed(int hashCode()): Effects-of-calling:java.lang.StringBuilder
    //#unanalyzed(int hashCode()): Effects-of-calling:java.lang.StringBuilder:append
    //#unanalyzed(int hashCode()): Effects-of-calling:java.lang.StringBuilder:toString
    //#ConditionTree.java:155: end of method: int com.dmdirc.actions.ConditionTree.hashCode()
    }

    /**
     * Retrieves a String representation of this ConditionTree. The string
     * representation is a normalised formula describing this tree and all of
     * its children. The output of this method will generate an identical tree
     * if passed to parseString.
     *
     * @return A string representation of this tree
     */
    @Override
    public String toString() {
        switch (op) {
    //#ConditionTree.java:168: method: String com.dmdirc.actions.ConditionTree.toString()
    //#ConditionTree.java:168: Warning: method not available - call not analyzed
    //#    call on int com.dmdirc.actions.ConditionTree$OPERATION:ordinal()
    //#    severity: INFORMATIONAL
    //#    class: com.dmdirc.actions.ConditionTree
    //#    method: String toString()
    //#    unanalyzed callee: int com.dmdirc.actions.ConditionTree$OPERATION:ordinal()
    //#input(String toString()): "!"._tainted
    //#input(String toString()): "&amp;"._tainted
    //#input(String toString()): "("._tainted
    //#input(String toString()): ")"._tainted
    //#input(String toString()): "|"._tainted
    //#input(String toString()): com.dmdirc.actions.ConditionTree$1__static_init.new int[](ConditionTree$1__static_init#1).length
    //#input(String toString()): com.dmdirc.actions.ConditionTree$1__static_init.new int[](ConditionTree$1__static_init#1)[0..4_294_967_295]
    //#input(String toString()): com/dmdirc/actions/ConditionTree$1.$SwitchMap$com$dmdirc$actions$ConditionTree$OPERATION
    //#input(String toString()): this
    //#input(String toString()): this..._tainted
    //#input(String toString()): this.argument
    //#input(String toString()): this.leftArg
    //#input(String toString()): this.op
    //#input(String toString()): this.rightArg
    //#output(String toString()): java.lang.String:valueOf(...)._tainted
    //#output(String toString()): java.lang.StringBuilder:toString(...)._tainted
    //#output(String toString()): return_value
    //#new obj(String toString()): java.lang.String:valueOf(...)
    //#new obj(String toString()): java.lang.StringBuilder:toString(...)
    //#pre[6] (String toString()): this.op != null
    //#pre[1] (String toString()): (soft) init'ed(com.dmdirc.actions.ConditionTree$1__static_init.new int[](ConditionTree$1__static_init#1)[0..4_294_967_295])
    //#pre[4] (String toString()): (soft) init'ed(this.argument)
    //#pre[5] (String toString()): (soft) init'ed(this.leftArg)
    //#pre[7] (String toString()): (soft) init'ed(this.rightArg)
    //#presumption(String toString()): com.dmdirc.actions.ConditionTree_OPERATION:ordinal(...)@168 in {0..4}
    //#post(String toString()): java.lang.String:valueOf(...)._tainted == 0
    //#post(String toString()): init'ed(java.lang.StringBuilder:toString(...)._tainted)
    //#post(String toString()): return_value in Addr_Set{&java.lang.String:valueOf(...),&java.lang.StringBuilder:toString(...),&java.lang.StringBuilder:toString(...),&java.lang.StringBuilder:toString(...),&""}
    //#test_vector(String toString()): com.dmdirc.actions.ConditionTree$1__static_init.new int[](ConditionTree$1__static_init#1)[0..4_294_967_295]: {1}, {2}, {3}, {4}, {-2_147_483_648..0, 5..4_294_967_295}
        case VAR:
            return String.valueOf(argument);
        case NOT:
            return "!" + leftArg;
        case AND:
            return "(" + leftArg + "&" + rightArg + ")";
        case OR:
            return "(" + leftArg + "|" + rightArg + ")";
        default:
            return "";
    //#ConditionTree.java:178: end of method: String com.dmdirc.actions.ConditionTree.toString()
        }
    }

    /**
     * Parses the specified string into a condition tree.
     *
     * @param string The string to be parsed
     * @return The corresponding condition tree, or null if there was an error
     * while parsing the data
     */
    public static ConditionTree parseString(final String string) {
        final Deque<Object> stack = new ArrayDeque<Object>();
    //#ConditionTree.java:190: method: ConditionTree com.dmdirc.actions.ConditionTree.parseString(String)
    //#input(ConditionTree parseString(String)): __Descendant_Table[com/dmdirc/actions/ConditionTree]
    //#input(ConditionTree parseString(String)): __Descendant_Table[others]
    //#input(ConditionTree parseString(String)): com/dmdirc/actions/ConditionTree$OPERATION.AND
    //#input(ConditionTree parseString(String)): com/dmdirc/actions/ConditionTree$OPERATION.NOOP
    //#input(ConditionTree parseString(String)): com/dmdirc/actions/ConditionTree$OPERATION.NOT
    //#input(ConditionTree parseString(String)): com/dmdirc/actions/ConditionTree$OPERATION.OR
    //#input(ConditionTree parseString(String)): com/dmdirc/actions/ConditionTree$OPERATION.VAR
    //#input(ConditionTree parseString(String)): string
    //#output(ConditionTree parseString(String)): new ConditionTree(parseStack#3) num objects
    //#output(ConditionTree parseString(String)): new ConditionTree(parseStack#3).__Tag
    //#output(ConditionTree parseString(String)): new ConditionTree(parseStack#3).argument
    //#output(ConditionTree parseString(String)): new ConditionTree(parseStack#3).leftArg
    //#output(ConditionTree parseString(String)): new ConditionTree(parseStack#3).op
    //#output(ConditionTree parseString(String)): new ConditionTree(parseStack#3).rightArg
    //#output(ConditionTree parseString(String)): new ConditionTree(readTerm#1) num objects
    //#output(ConditionTree parseString(String)): new ConditionTree(readTerm#1).__Tag
    //#output(ConditionTree parseString(String)): new ConditionTree(readTerm#1).argument
    //#output(ConditionTree parseString(String)): new ConditionTree(readTerm#1).leftArg
    //#output(ConditionTree parseString(String)): new ConditionTree(readTerm#1).op
    //#output(ConditionTree parseString(String)): new ConditionTree(readTerm#1).rightArg
    //#output(ConditionTree parseString(String)): return_value
    //#new obj(ConditionTree parseString(String)): new ConditionTree(parseStack#3)
    //#new obj(ConditionTree parseString(String)): new ConditionTree(readTerm#1)
    //#pre[1] (ConditionTree parseString(String)): string != null
    //#post(ConditionTree parseString(String)): init'ed(return_value)
    //#post(ConditionTree parseString(String)): new ConditionTree(parseStack#3) num objects <= 1
    //#post(ConditionTree parseString(String)): new ConditionTree(parseStack#3).__Tag == com/dmdirc/actions/ConditionTree
    //#post(ConditionTree parseString(String)): new ConditionTree(parseStack#3).argument == -1
    //#post(ConditionTree parseString(String)): new ConditionTree(parseStack#3).leftArg == null
    //#post(ConditionTree parseString(String)): new ConditionTree(parseStack#3).op == &com.dmdirc.actions.ConditionTree$OPERATION__static_init.new ConditionTree$OPERATION(ConditionTree$OPERATION__static_init#5)
    //#post(ConditionTree parseString(String)): new ConditionTree(parseStack#3).rightArg == null
    //#post(ConditionTree parseString(String)): init'ed(new ConditionTree(readTerm#1) num objects)
    //#post(ConditionTree parseString(String)): new ConditionTree(readTerm#1).__Tag not init'ed, if init'ed
    //#post(ConditionTree parseString(String)): new ConditionTree(readTerm#1).argument == 0, if init'ed
    //#post(ConditionTree parseString(String)): new ConditionTree(readTerm#1).leftArg == null
    //#post(ConditionTree parseString(String)): new ConditionTree(readTerm#1).op == null
    //#post(ConditionTree parseString(String)): new ConditionTree(readTerm#1).rightArg == null
    //#unanalyzed(ConditionTree parseString(String)): Effects-of-calling:java.util.Deque:pollFirst
    //#unanalyzed(ConditionTree parseString(String)): Effects-of-calling:java.lang.Character:instanceof
    //#unanalyzed(ConditionTree parseString(String)): Effects-of-calling:java.lang.Character:charValue
    //#unanalyzed(ConditionTree parseString(String)): Effects-of-calling:java.util.Deque:isEmpty
    //#unanalyzed(ConditionTree parseString(String)): Effects-of-calling:readTerm
    //#unanalyzed(ConditionTree parseString(String)): Effects-of-calling:java.util.ArrayDeque
    //#unanalyzed(ConditionTree parseString(String)): Effects-of-calling:java.util.Deque:pollLast
    //#unanalyzed(ConditionTree parseString(String)): Effects-of-calling:java.util.Deque:addFirst
    //#unanalyzed(ConditionTree parseString(String)): Effects-of-calling:parseStack
    //#unanalyzed(ConditionTree parseString(String)): Effects-of-calling:java.util.Deque:poll
    //#unanalyzed(ConditionTree parseString(String)): Effects-of-calling:java.util.Deque:add
    //#unanalyzed(ConditionTree parseString(String)): Effects-of-calling:java.util.Deque:size
    //#test_vector(ConditionTree parseString(String)): java.lang.String:charAt(...)@193: {32}, {48..57}, {9}, {10}, {13}, {0..8, 11,12, 14..31, 33..47, 58..65_535}
    //#test_vector(ConditionTree parseString(String)): java.lang.String:charAt(...)@198: {0..47, 58..65_535}, {48..57}

        for (int i = 0; i < string.length(); i++) {
            final char m = string.charAt(i);

            if (isInt(m)) {
                final StringBuilder temp = new StringBuilder(String.valueOf(m));

                while (i + 1 < string.length() && isInt(string.charAt(i + 1))) {
                    temp.append(string.charAt(i + 1));
                    i++;
                }

                try {
                    stack.add(new ConditionTree(Integer.parseInt(temp.toString())));
                } catch (NumberFormatException ex) {
                    return null;
                }
            } else if (m != ' ' && m != '\t' && m != '\n' && m != '\r') {
                stack.add(m);
            }
        }

        return parseStack(stack);
    //#ConditionTree.java:213: end of method: ConditionTree com.dmdirc.actions.ConditionTree.parseString(String)
    }

    /**
     * Parses the specified stack of elements, and returns a corresponding
     * ConditionTree.
     *
     * @param stack The stack to be read.
     * @return The corresponding condition tree, or null if there was an error
     * while parsing the data.
     */
    private static ConditionTree parseStack(final Deque<Object> stack) {
        final Deque<Object> myStack = new ArrayDeque<Object>();
    //#ConditionTree.java:225: method: ConditionTree com.dmdirc.actions.ConditionTree.parseStack(Deque)
    //#input(ConditionTree parseStack(Deque)): __Descendant_Table[com/dmdirc/actions/ConditionTree]
    //#input(ConditionTree parseStack(Deque)): __Descendant_Table[others]
    //#input(ConditionTree parseStack(Deque)): com/dmdirc/actions/ConditionTree$OPERATION.AND
    //#input(ConditionTree parseStack(Deque)): com/dmdirc/actions/ConditionTree$OPERATION.NOOP
    //#input(ConditionTree parseStack(Deque)): com/dmdirc/actions/ConditionTree$OPERATION.NOT
    //#input(ConditionTree parseStack(Deque)): com/dmdirc/actions/ConditionTree$OPERATION.OR
    //#input(ConditionTree parseStack(Deque)): stack
    //#output(ConditionTree parseStack(Deque)): new ConditionTree(parseStack#3) num objects
    //#output(ConditionTree parseStack(Deque)): new ConditionTree(parseStack#3).__Tag
    //#output(ConditionTree parseStack(Deque)): new ConditionTree(parseStack#3).argument
    //#output(ConditionTree parseStack(Deque)): new ConditionTree(parseStack#3).leftArg
    //#output(ConditionTree parseStack(Deque)): new ConditionTree(parseStack#3).op
    //#output(ConditionTree parseStack(Deque)): new ConditionTree(parseStack#3).rightArg
    //#output(ConditionTree parseStack(Deque)): new ConditionTree(readTerm#1) num objects
    //#output(ConditionTree parseStack(Deque)): new ConditionTree(readTerm#1).__Tag
    //#output(ConditionTree parseStack(Deque)): new ConditionTree(readTerm#1).argument
    //#output(ConditionTree parseStack(Deque)): new ConditionTree(readTerm#1).leftArg
    //#output(ConditionTree parseStack(Deque)): new ConditionTree(readTerm#1).op
    //#output(ConditionTree parseStack(Deque)): new ConditionTree(readTerm#1).rightArg
    //#output(ConditionTree parseStack(Deque)): return_value
    //#new obj(ConditionTree parseStack(Deque)): new ConditionTree(parseStack#3)
    //#new obj(ConditionTree parseStack(Deque)): new ConditionTree(readTerm#1)
    //#pre[1] (ConditionTree parseStack(Deque)): stack != null
    //#post(ConditionTree parseStack(Deque)): init'ed(return_value)
    //#post(ConditionTree parseStack(Deque)): new ConditionTree(parseStack#3) num objects <= 1
    //#post(ConditionTree parseStack(Deque)): new ConditionTree(parseStack#3).__Tag == com/dmdirc/actions/ConditionTree
    //#post(ConditionTree parseStack(Deque)): new ConditionTree(parseStack#3).argument == -1
    //#post(ConditionTree parseStack(Deque)): new ConditionTree(parseStack#3).leftArg == null
    //#post(ConditionTree parseStack(Deque)): new ConditionTree(parseStack#3).op == &com.dmdirc.actions.ConditionTree$OPERATION__static_init.new ConditionTree$OPERATION(ConditionTree$OPERATION__static_init#5)
    //#post(ConditionTree parseStack(Deque)): new ConditionTree(parseStack#3).rightArg == null
    //#post(ConditionTree parseStack(Deque)): init'ed(new ConditionTree(readTerm#1) num objects)
    //#post(ConditionTree parseStack(Deque)): not_init'ed(new ConditionTree(readTerm#1).__Tag)
    //#post(ConditionTree parseStack(Deque)): not_init'ed(new ConditionTree(readTerm#1).argument)
    //#post(ConditionTree parseStack(Deque)): not_init'ed(new ConditionTree(readTerm#1).leftArg)
    //#post(ConditionTree parseStack(Deque)): not_init'ed(new ConditionTree(readTerm#1).op)
    //#post(ConditionTree parseStack(Deque)): not_init'ed(new ConditionTree(readTerm#1).rightArg)
    //#unanalyzed(ConditionTree parseStack(Deque)): Effects-of-calling:java.util.Deque:pollFirst
    //#unanalyzed(ConditionTree parseStack(Deque)): Effects-of-calling:java.lang.Character:instanceof
    //#unanalyzed(ConditionTree parseStack(Deque)): Effects-of-calling:java.lang.Character:charValue
    //#unanalyzed(ConditionTree parseStack(Deque)): Effects-of-calling:java.util.Deque:isEmpty
    //#unanalyzed(ConditionTree parseStack(Deque)): Effects-of-calling:readTerm
    //#unanalyzed(ConditionTree parseStack(Deque)): Effects-of-calling:java.util.ArrayDeque
    //#unanalyzed(ConditionTree parseStack(Deque)): Effects-of-calling:java.util.Deque:pollLast
    //#unanalyzed(ConditionTree parseStack(Deque)): Effects-of-calling:java.util.Deque:addFirst
    //#unanalyzed(ConditionTree parseStack(Deque)): Effects-of-calling:parseStack
    //#unanalyzed(ConditionTree parseStack(Deque)): Effects-of-calling:java.util.Deque:poll
    //#unanalyzed(ConditionTree parseStack(Deque)): Effects-of-calling:java.util.Deque:add
    //#unanalyzed(ConditionTree parseStack(Deque)): Effects-of-calling:java.util.Deque:size
    //#test_vector(ConditionTree parseStack(Deque)): java.lang.Character:charValue(...)@230: {0..40, 42..65_535}, {41}
    //#test_vector(ConditionTree parseStack(Deque)): java.lang.Character:charValue(...)@271: {0..37, 39..65_535}, {38}
    //#test_vector(ConditionTree parseStack(Deque)): java.lang.Character:charValue(...)@273: {0..123, 125..65_535}, {124}
    //#test_vector(ConditionTree parseStack(Deque)): java.util.Deque:isEmpty(...)@227: {1}, {0}
    //#test_vector(ConditionTree parseStack(Deque)): java.util.Deque:isEmpty(...)@243: {1}, {0}
    //#test_vector(ConditionTree parseStack(Deque)): java.util.Deque:isEmpty(...)@257: {0}, {1}
    //#test_vector(ConditionTree parseStack(Deque)): java.util.Deque:isEmpty(...)@263: {0}, {1}
    //#test_vector(ConditionTree parseStack(Deque)): java.util.Deque:size(...)@244: {-2_147_483_648..0, 2..4_294_967_295}, {1}

        while (!stack.isEmpty()) {
            final Object object = stack.poll();

            if (object instanceof Character && ((Character) object) == ')') {
                final ConditionTree bracket = readBracket(myStack);

                if (bracket == null) {
                    return null;
                } else {
                    myStack.add(bracket);
                }
            } else {
                myStack.add(object);
            }
        }

        while (!myStack.isEmpty()) {
            if (myStack.size() == 1) {
                final Object first = myStack.pollFirst();
                if (first instanceof ConditionTree) {
                    return (ConditionTree) first;
                } else {
                    return null;
                }
            }

            final ConditionTree first = readTerm(myStack);

            if (first == null) {
                return null;
            } else if (myStack.isEmpty()) {
                return first;
            }

            final Object second = myStack.pollFirst();

            if (myStack.isEmpty()) {
                return null;
            } else {
                final ConditionTree third = readTerm(myStack);

                if (third != null && second instanceof Character) {
                    OPERATION op;

                    if ((Character) second == '&') {
                        op = OPERATION.AND;
                    } else if ((Character) second == '|') {
                        op = OPERATION.OR;
                    } else {
                        return null;
                    }

                    myStack.addFirst(new ConditionTree(op, first, third));
                } else {
                    return null;
                }
            }
        }

        return new ConditionTree();
    //#ConditionTree.java:286: end of method: ConditionTree com.dmdirc.actions.ConditionTree.parseStack(Deque)
    }

    /**
     * Reads and returns a single term from the specified stack.
     *
     * @param stack The stack to be read
     * @return The ConditionTree representing the last element on the stack,
     * or null if it was not possible to create one.
     */
    private static ConditionTree readTerm(final Deque<Object> stack) {
        final Object first = stack.pollFirst();
    //#ConditionTree.java:297: method: ConditionTree com.dmdirc.actions.ConditionTree.readTerm(Deque)
    //#input(ConditionTree readTerm(Deque)): __Descendant_Table[com/dmdirc/actions/ConditionTree]
    //#input(ConditionTree readTerm(Deque)): __Descendant_Table[others]
    //#input(ConditionTree readTerm(Deque)): com/dmdirc/actions/ConditionTree$OPERATION.NOT
    //#input(ConditionTree readTerm(Deque)): stack
    //#output(ConditionTree readTerm(Deque)): new ConditionTree(readTerm#1) num objects
    //#output(ConditionTree readTerm(Deque)): new ConditionTree(readTerm#1).__Tag
    //#output(ConditionTree readTerm(Deque)): new ConditionTree(readTerm#1).argument
    //#output(ConditionTree readTerm(Deque)): new ConditionTree(readTerm#1).leftArg
    //#output(ConditionTree readTerm(Deque)): new ConditionTree(readTerm#1).op
    //#output(ConditionTree readTerm(Deque)): new ConditionTree(readTerm#1).rightArg
    //#output(ConditionTree readTerm(Deque)): new ConditionTree(readTerm#1*) num objects
    //#output(ConditionTree readTerm(Deque)): new ConditionTree(readTerm#1*).__Tag
    //#output(ConditionTree readTerm(Deque)): new ConditionTree(readTerm#1*).argument
    //#output(ConditionTree readTerm(Deque)): new ConditionTree(readTerm#1*).leftArg
    //#output(ConditionTree readTerm(Deque)): new ConditionTree(readTerm#1*).op
    //#output(ConditionTree readTerm(Deque)): new ConditionTree(readTerm#1*).rightArg
    //#output(ConditionTree readTerm(Deque)): return_value
    //#new obj(ConditionTree readTerm(Deque)): new ConditionTree(readTerm#1)
    //#new obj(ConditionTree readTerm(Deque)): new ConditionTree(readTerm#1*)
    //#pre[1] (ConditionTree readTerm(Deque)): stack != null
    //#post(ConditionTree readTerm(Deque)): init'ed(return_value)
    //#post(ConditionTree readTerm(Deque)): new ConditionTree(readTerm#1) num objects <= 1
    //#post(ConditionTree readTerm(Deque)): new ConditionTree(readTerm#1).__Tag == com/dmdirc/actions/ConditionTree
    //#post(ConditionTree readTerm(Deque)): new ConditionTree(readTerm#1).argument == -1
    //#post(ConditionTree readTerm(Deque)): init'ed(new ConditionTree(readTerm#1).leftArg)
    //#post(ConditionTree readTerm(Deque)): new ConditionTree(readTerm#1).op == &com.dmdirc.actions.ConditionTree$OPERATION__static_init.new ConditionTree$OPERATION(ConditionTree$OPERATION__static_init#4)
    //#post(ConditionTree readTerm(Deque)): new ConditionTree(readTerm#1).rightArg == null
    //#post(ConditionTree readTerm(Deque)): new ConditionTree(readTerm#1*) num objects <= 1
    //#post(ConditionTree readTerm(Deque)): not_init'ed(new ConditionTree(readTerm#1*).__Tag)
    //#post(ConditionTree readTerm(Deque)): not_init'ed(new ConditionTree(readTerm#1*).argument)
    //#post(ConditionTree readTerm(Deque)): not_init'ed(new ConditionTree(readTerm#1*).leftArg)
    //#post(ConditionTree readTerm(Deque)): not_init'ed(new ConditionTree(readTerm#1*).op)
    //#post(ConditionTree readTerm(Deque)): not_init'ed(new ConditionTree(readTerm#1*).rightArg)
    //#unanalyzed(ConditionTree readTerm(Deque)): Effects-of-calling:java.util.Deque:pollFirst
    //#unanalyzed(ConditionTree readTerm(Deque)): Effects-of-calling:java.lang.Character:instanceof
    //#unanalyzed(ConditionTree readTerm(Deque)): Effects-of-calling:java.lang.Character:charValue
    //#unanalyzed(ConditionTree readTerm(Deque)): Effects-of-calling:java.util.Deque:isEmpty
    //#unanalyzed(ConditionTree readTerm(Deque)): Effects-of-calling:readTerm
    //#test_vector(ConditionTree readTerm(Deque)): java.lang.Character:charValue(...)@299: {0..32, 34..65_535}, {33}
    //#test_vector(ConditionTree readTerm(Deque)): java.util.Deque:isEmpty(...)@300: {0}, {1}

        if (first instanceof Character && (Character) first == '!') {
            if (stack.isEmpty()) {
                return null;
            }

            return new ConditionTree(OPERATION.NOT, readTerm(stack));
        } else {
            if (!(first instanceof ConditionTree)) {
                return null;
            }

            return (ConditionTree) first;
    //#ConditionTree.java:310: end of method: ConditionTree com.dmdirc.actions.ConditionTree.readTerm(Deque)
        }
    }

    /**
     * Pops elements off of the end of the specified stack until an opening
     * bracket is reached, and then returns the parsed content of the bracket.
     *
     * @param stack The stack to be read for the bracket
     * @return The parsed contents of the bracket, or null if the brackets were
     * mismatched.
     */
    private static ConditionTree readBracket(final Deque<Object> stack) {
        final Deque<Object> tempStack = new ArrayDeque<Object>();
    //#ConditionTree.java:323: method: ConditionTree com.dmdirc.actions.ConditionTree.readBracket(Deque)
    //#input(ConditionTree readBracket(Deque)): __Descendant_Table[com/dmdirc/actions/ConditionTree]
    //#input(ConditionTree readBracket(Deque)): __Descendant_Table[others]
    //#input(ConditionTree readBracket(Deque)): com/dmdirc/actions/ConditionTree$OPERATION.AND
    //#input(ConditionTree readBracket(Deque)): com/dmdirc/actions/ConditionTree$OPERATION.NOOP
    //#input(ConditionTree readBracket(Deque)): com/dmdirc/actions/ConditionTree$OPERATION.NOT
    //#input(ConditionTree readBracket(Deque)): com/dmdirc/actions/ConditionTree$OPERATION.OR
    //#input(ConditionTree readBracket(Deque)): stack
    //#output(ConditionTree readBracket(Deque)): new ConditionTree(parseStack#3) num objects
    //#output(ConditionTree readBracket(Deque)): new ConditionTree(parseStack#3).__Tag
    //#output(ConditionTree readBracket(Deque)): new ConditionTree(parseStack#3).argument
    //#output(ConditionTree readBracket(Deque)): new ConditionTree(parseStack#3).leftArg
    //#output(ConditionTree readBracket(Deque)): new ConditionTree(parseStack#3).op
    //#output(ConditionTree readBracket(Deque)): new ConditionTree(parseStack#3).rightArg
    //#output(ConditionTree readBracket(Deque)): new ConditionTree(readTerm#1) num objects
    //#output(ConditionTree readBracket(Deque)): new ConditionTree(readTerm#1).__Tag
    //#output(ConditionTree readBracket(Deque)): new ConditionTree(readTerm#1).argument
    //#output(ConditionTree readBracket(Deque)): new ConditionTree(readTerm#1).leftArg
    //#output(ConditionTree readBracket(Deque)): new ConditionTree(readTerm#1).op
    //#output(ConditionTree readBracket(Deque)): new ConditionTree(readTerm#1).rightArg
    //#output(ConditionTree readBracket(Deque)): return_value
    //#new obj(ConditionTree readBracket(Deque)): new ConditionTree(parseStack#3)
    //#new obj(ConditionTree readBracket(Deque)): new ConditionTree(readTerm#1)
    //#pre[1] (ConditionTree readBracket(Deque)): (soft) stack != null
    //#post(ConditionTree readBracket(Deque)): init'ed(return_value)
    //#post(ConditionTree readBracket(Deque)): new ConditionTree(parseStack#3) num objects <= 1
    //#post(ConditionTree readBracket(Deque)): new ConditionTree(parseStack#3).__Tag == com/dmdirc/actions/ConditionTree
    //#post(ConditionTree readBracket(Deque)): new ConditionTree(parseStack#3).argument == -1
    //#post(ConditionTree readBracket(Deque)): new ConditionTree(parseStack#3).leftArg == null
    //#post(ConditionTree readBracket(Deque)): new ConditionTree(parseStack#3).op == &com.dmdirc.actions.ConditionTree$OPERATION__static_init.new ConditionTree$OPERATION(ConditionTree$OPERATION__static_init#5)
    //#post(ConditionTree readBracket(Deque)): new ConditionTree(parseStack#3).rightArg == null
    //#post(ConditionTree readBracket(Deque)): init'ed(new ConditionTree(readTerm#1) num objects)
    //#post(ConditionTree readBracket(Deque)): new ConditionTree(readTerm#1).__Tag not init'ed, if init'ed
    //#post(ConditionTree readBracket(Deque)): new ConditionTree(readTerm#1).argument == 0, if init'ed
    //#post(ConditionTree readBracket(Deque)): new ConditionTree(readTerm#1).leftArg == null
    //#post(ConditionTree readBracket(Deque)): new ConditionTree(readTerm#1).op == null
    //#post(ConditionTree readBracket(Deque)): new ConditionTree(readTerm#1).rightArg == null
    //#unanalyzed(ConditionTree readBracket(Deque)): Effects-of-calling:java.util.Deque:pollFirst
    //#unanalyzed(ConditionTree readBracket(Deque)): Effects-of-calling:java.lang.Character:instanceof
    //#unanalyzed(ConditionTree readBracket(Deque)): Effects-of-calling:java.lang.Character:charValue
    //#unanalyzed(ConditionTree readBracket(Deque)): Effects-of-calling:java.util.Deque:isEmpty
    //#unanalyzed(ConditionTree readBracket(Deque)): Effects-of-calling:readTerm
    //#unanalyzed(ConditionTree readBracket(Deque)): Effects-of-calling:java.util.ArrayDeque
    //#unanalyzed(ConditionTree readBracket(Deque)): Effects-of-calling:java.util.Deque:pollLast
    //#unanalyzed(ConditionTree readBracket(Deque)): Effects-of-calling:java.util.Deque:addFirst
    //#unanalyzed(ConditionTree readBracket(Deque)): Effects-of-calling:parseStack
    //#unanalyzed(ConditionTree readBracket(Deque)): Effects-of-calling:java.util.Deque:poll
    //#unanalyzed(ConditionTree readBracket(Deque)): Effects-of-calling:java.util.Deque:add
    //#unanalyzed(ConditionTree readBracket(Deque)): Effects-of-calling:java.util.Deque:size
    //#test_vector(ConditionTree readBracket(Deque)): java.lang.Character:charValue(...)@329: {0..39, 41..65_535}, {40}
    //#test_vector(ConditionTree readBracket(Deque)): java.util.Deque:isEmpty(...)@326: {1}, {0}
        boolean found = false;

        while (!found && !stack.isEmpty()) {
            final Object object = stack.pollLast();

            if (object instanceof Character && ((Character) object) == '(') {
                found = true;
            } else {
                tempStack.addFirst(object);
            }
        }

        if (found) {
            return parseStack(tempStack);
        } else {
            return null;
    //#ConditionTree.java:339: end of method: ConditionTree com.dmdirc.actions.ConditionTree.readBracket(Deque)
        }
    }

    /**
     * Determines if the specified character represents a single digit.
     *
     * @param target The character to be tested
     * @return True if the character is a digit, false otherwise
     */
    private static boolean isInt(final char target) {
        return target >= '0' && target <= '9';
    //#ConditionTree.java:350: method: bool com.dmdirc.actions.ConditionTree.isInt(char)
    //#input(bool isInt(char)): target
    //#output(bool isInt(char)): return_value
    //#post(bool isInt(char)): init'ed(return_value)
    //#ConditionTree.java:350: end of method: bool com.dmdirc.actions.ConditionTree.isInt(char)
    }

    /**
     * Creates a condition tree by disjoining the specified number of arguments
     * together.
     *
     * @param numArgs The number of arguments to be disjoined
     * @return The corresponding condition tree
     */
    public static ConditionTree createDisjunction(final int numArgs) {
        final StringBuilder builder = new StringBuilder();
    //#ConditionTree.java:361: method: ConditionTree com.dmdirc.actions.ConditionTree.createDisjunction(int)
    //#input(ConditionTree createDisjunction(int)): __Descendant_Table[com/dmdirc/actions/ConditionTree]
    //#input(ConditionTree createDisjunction(int)): __Descendant_Table[others]
    //#input(ConditionTree createDisjunction(int)): com/dmdirc/actions/ConditionTree$OPERATION.AND
    //#input(ConditionTree createDisjunction(int)): com/dmdirc/actions/ConditionTree$OPERATION.NOOP
    //#input(ConditionTree createDisjunction(int)): com/dmdirc/actions/ConditionTree$OPERATION.NOT
    //#input(ConditionTree createDisjunction(int)): com/dmdirc/actions/ConditionTree$OPERATION.OR
    //#input(ConditionTree createDisjunction(int)): com/dmdirc/actions/ConditionTree$OPERATION.VAR
    //#input(ConditionTree createDisjunction(int)): numArgs
    //#output(ConditionTree createDisjunction(int)): new ConditionTree(parseStack#3) num objects
    //#output(ConditionTree createDisjunction(int)): new ConditionTree(parseStack#3).__Tag
    //#output(ConditionTree createDisjunction(int)): new ConditionTree(parseStack#3).argument
    //#output(ConditionTree createDisjunction(int)): new ConditionTree(parseStack#3).leftArg
    //#output(ConditionTree createDisjunction(int)): new ConditionTree(parseStack#3).op
    //#output(ConditionTree createDisjunction(int)): new ConditionTree(parseStack#3).rightArg
    //#output(ConditionTree createDisjunction(int)): new ConditionTree(readTerm#1) num objects
    //#output(ConditionTree createDisjunction(int)): new ConditionTree(readTerm#1).__Tag
    //#output(ConditionTree createDisjunction(int)): new ConditionTree(readTerm#1).argument
    //#output(ConditionTree createDisjunction(int)): new ConditionTree(readTerm#1).leftArg
    //#output(ConditionTree createDisjunction(int)): new ConditionTree(readTerm#1).op
    //#output(ConditionTree createDisjunction(int)): new ConditionTree(readTerm#1).rightArg
    //#output(ConditionTree createDisjunction(int)): return_value
    //#new obj(ConditionTree createDisjunction(int)): new ConditionTree(parseStack#3)
    //#new obj(ConditionTree createDisjunction(int)): new ConditionTree(readTerm#1)
    //#post(ConditionTree createDisjunction(int)): init'ed(return_value)
    //#post(ConditionTree createDisjunction(int)): new ConditionTree(parseStack#3) num objects <= 1
    //#post(ConditionTree createDisjunction(int)): new ConditionTree(parseStack#3).__Tag == com/dmdirc/actions/ConditionTree
    //#post(ConditionTree createDisjunction(int)): new ConditionTree(parseStack#3).argument == -1
    //#post(ConditionTree createDisjunction(int)): new ConditionTree(parseStack#3).leftArg == null
    //#post(ConditionTree createDisjunction(int)): new ConditionTree(parseStack#3).op == &com.dmdirc.actions.ConditionTree$OPERATION__static_init.new ConditionTree$OPERATION(ConditionTree$OPERATION__static_init#5)
    //#post(ConditionTree createDisjunction(int)): new ConditionTree(parseStack#3).rightArg == null
    //#post(ConditionTree createDisjunction(int)): init'ed(new ConditionTree(readTerm#1) num objects)
    //#post(ConditionTree createDisjunction(int)): new ConditionTree(readTerm#1).__Tag not init'ed, if init'ed
    //#post(ConditionTree createDisjunction(int)): new ConditionTree(readTerm#1).argument == 0, if init'ed
    //#post(ConditionTree createDisjunction(int)): new ConditionTree(readTerm#1).leftArg == null
    //#post(ConditionTree createDisjunction(int)): new ConditionTree(readTerm#1).op == null
    //#post(ConditionTree createDisjunction(int)): new ConditionTree(readTerm#1).rightArg == null
    //#unanalyzed(ConditionTree createDisjunction(int)): Effects-of-calling:java.lang.StringBuilder:toString
    //#unanalyzed(ConditionTree createDisjunction(int)): Effects-of-calling:java.util.Deque:pollFirst
    //#unanalyzed(ConditionTree createDisjunction(int)): Effects-of-calling:java.lang.Character:instanceof
    //#unanalyzed(ConditionTree createDisjunction(int)): Effects-of-calling:java.lang.Character:charValue
    //#unanalyzed(ConditionTree createDisjunction(int)): Effects-of-calling:java.util.Deque:isEmpty
    //#unanalyzed(ConditionTree createDisjunction(int)): Effects-of-calling:readTerm
    //#unanalyzed(ConditionTree createDisjunction(int)): Effects-of-calling:java.util.ArrayDeque
    //#unanalyzed(ConditionTree createDisjunction(int)): Effects-of-calling:java.util.Deque:pollLast
    //#unanalyzed(ConditionTree createDisjunction(int)): Effects-of-calling:java.util.Deque:addFirst
    //#unanalyzed(ConditionTree createDisjunction(int)): Effects-of-calling:parseStack
    //#unanalyzed(ConditionTree createDisjunction(int)): Effects-of-calling:java.util.Deque:poll
    //#unanalyzed(ConditionTree createDisjunction(int)): Effects-of-calling:java.util.Deque:add
    //#unanalyzed(ConditionTree createDisjunction(int)): Effects-of-calling:java.util.Deque:size
    //#unanalyzed(ConditionTree createDisjunction(int)): Effects-of-calling:java.lang.String:length
    //#unanalyzed(ConditionTree createDisjunction(int)): Effects-of-calling:java.lang.String:charAt
    //#unanalyzed(ConditionTree createDisjunction(int)): Effects-of-calling:java.lang.String:valueOf
    //#unanalyzed(ConditionTree createDisjunction(int)): Effects-of-calling:java.lang.StringBuilder
    //#unanalyzed(ConditionTree createDisjunction(int)): Effects-of-calling:java.lang.StringBuilder:append
    //#unanalyzed(ConditionTree createDisjunction(int)): Effects-of-calling:java.lang.Integer:parseInt
    //#unanalyzed(ConditionTree createDisjunction(int)): Effects-of-calling:java.lang.Throwable:__curr_excep_obj
    //#unanalyzed(ConditionTree createDisjunction(int)): Effects-of-calling:java.lang.Character:valueOf
    //#test_vector(ConditionTree createDisjunction(int)): java.lang.StringBuilder:length(...)@364: {0}, {-2_147_483_648..-1, 1..4_294_967_295}

        for (int i = 0; i < numArgs; i++) {
            if (builder.length() != 0) {
                builder.append('|');
            }

            builder.append(i);
        }

        return parseString(builder.toString());
    //#ConditionTree.java:371: end of method: ConditionTree com.dmdirc.actions.ConditionTree.createDisjunction(int)
    }

    /**
     * Creates a condition tree by conjoining the specified number of arguments
     * together.
     *
     * @param numArgs The number of arguments to be conjoined
     * @return The corresponding condition tree
     */
    public static ConditionTree createConjunction(final int numArgs) {
        final StringBuilder builder = new StringBuilder();
    //#ConditionTree.java:382: method: ConditionTree com.dmdirc.actions.ConditionTree.createConjunction(int)
    //#input(ConditionTree createConjunction(int)): __Descendant_Table[com/dmdirc/actions/ConditionTree]
    //#input(ConditionTree createConjunction(int)): __Descendant_Table[others]
    //#input(ConditionTree createConjunction(int)): com/dmdirc/actions/ConditionTree$OPERATION.AND
    //#input(ConditionTree createConjunction(int)): com/dmdirc/actions/ConditionTree$OPERATION.NOOP
    //#input(ConditionTree createConjunction(int)): com/dmdirc/actions/ConditionTree$OPERATION.NOT
    //#input(ConditionTree createConjunction(int)): com/dmdirc/actions/ConditionTree$OPERATION.OR
    //#input(ConditionTree createConjunction(int)): com/dmdirc/actions/ConditionTree$OPERATION.VAR
    //#input(ConditionTree createConjunction(int)): numArgs
    //#output(ConditionTree createConjunction(int)): new ConditionTree(parseStack#3) num objects
    //#output(ConditionTree createConjunction(int)): new ConditionTree(parseStack#3).__Tag
    //#output(ConditionTree createConjunction(int)): new ConditionTree(parseStack#3).argument
    //#output(ConditionTree createConjunction(int)): new ConditionTree(parseStack#3).leftArg
    //#output(ConditionTree createConjunction(int)): new ConditionTree(parseStack#3).op
    //#output(ConditionTree createConjunction(int)): new ConditionTree(parseStack#3).rightArg
    //#output(ConditionTree createConjunction(int)): new ConditionTree(readTerm#1) num objects
    //#output(ConditionTree createConjunction(int)): new ConditionTree(readTerm#1).__Tag
    //#output(ConditionTree createConjunction(int)): new ConditionTree(readTerm#1).argument
    //#output(ConditionTree createConjunction(int)): new ConditionTree(readTerm#1).leftArg
    //#output(ConditionTree createConjunction(int)): new ConditionTree(readTerm#1).op
    //#output(ConditionTree createConjunction(int)): new ConditionTree(readTerm#1).rightArg
    //#output(ConditionTree createConjunction(int)): return_value
    //#new obj(ConditionTree createConjunction(int)): new ConditionTree(parseStack#3)
    //#new obj(ConditionTree createConjunction(int)): new ConditionTree(readTerm#1)
    //#post(ConditionTree createConjunction(int)): init'ed(return_value)
    //#post(ConditionTree createConjunction(int)): new ConditionTree(parseStack#3) num objects <= 1
    //#post(ConditionTree createConjunction(int)): new ConditionTree(parseStack#3).__Tag == com/dmdirc/actions/ConditionTree
    //#post(ConditionTree createConjunction(int)): new ConditionTree(parseStack#3).argument == -1
    //#post(ConditionTree createConjunction(int)): new ConditionTree(parseStack#3).leftArg == null
    //#post(ConditionTree createConjunction(int)): new ConditionTree(parseStack#3).op == &com.dmdirc.actions.ConditionTree$OPERATION__static_init.new ConditionTree$OPERATION(ConditionTree$OPERATION__static_init#5)
    //#post(ConditionTree createConjunction(int)): new ConditionTree(parseStack#3).rightArg == null
    //#post(ConditionTree createConjunction(int)): init'ed(new ConditionTree(readTerm#1) num objects)
    //#post(ConditionTree createConjunction(int)): new ConditionTree(readTerm#1).__Tag not init'ed, if init'ed
    //#post(ConditionTree createConjunction(int)): new ConditionTree(readTerm#1).argument == 0, if init'ed
    //#post(ConditionTree createConjunction(int)): new ConditionTree(readTerm#1).leftArg == null
    //#post(ConditionTree createConjunction(int)): new ConditionTree(readTerm#1).op == null
    //#post(ConditionTree createConjunction(int)): new ConditionTree(readTerm#1).rightArg == null
    //#unanalyzed(ConditionTree createConjunction(int)): Effects-of-calling:java.lang.StringBuilder:toString
    //#unanalyzed(ConditionTree createConjunction(int)): Effects-of-calling:java.util.Deque:pollFirst
    //#unanalyzed(ConditionTree createConjunction(int)): Effects-of-calling:java.lang.Character:instanceof
    //#unanalyzed(ConditionTree createConjunction(int)): Effects-of-calling:java.lang.Character:charValue
    //#unanalyzed(ConditionTree createConjunction(int)): Effects-of-calling:java.util.Deque:isEmpty
    //#unanalyzed(ConditionTree createConjunction(int)): Effects-of-calling:readTerm
    //#unanalyzed(ConditionTree createConjunction(int)): Effects-of-calling:java.util.ArrayDeque
    //#unanalyzed(ConditionTree createConjunction(int)): Effects-of-calling:java.util.Deque:pollLast
    //#unanalyzed(ConditionTree createConjunction(int)): Effects-of-calling:java.util.Deque:addFirst
    //#unanalyzed(ConditionTree createConjunction(int)): Effects-of-calling:parseStack
    //#unanalyzed(ConditionTree createConjunction(int)): Effects-of-calling:java.util.Deque:poll
    //#unanalyzed(ConditionTree createConjunction(int)): Effects-of-calling:java.util.Deque:add
    //#unanalyzed(ConditionTree createConjunction(int)): Effects-of-calling:java.util.Deque:size
    //#unanalyzed(ConditionTree createConjunction(int)): Effects-of-calling:java.lang.String:length
    //#unanalyzed(ConditionTree createConjunction(int)): Effects-of-calling:java.lang.String:charAt
    //#unanalyzed(ConditionTree createConjunction(int)): Effects-of-calling:java.lang.String:valueOf
    //#unanalyzed(ConditionTree createConjunction(int)): Effects-of-calling:java.lang.StringBuilder
    //#unanalyzed(ConditionTree createConjunction(int)): Effects-of-calling:java.lang.StringBuilder:append
    //#unanalyzed(ConditionTree createConjunction(int)): Effects-of-calling:java.lang.Integer:parseInt
    //#unanalyzed(ConditionTree createConjunction(int)): Effects-of-calling:java.lang.Throwable:__curr_excep_obj
    //#unanalyzed(ConditionTree createConjunction(int)): Effects-of-calling:java.lang.Character:valueOf
    //#test_vector(ConditionTree createConjunction(int)): java.lang.StringBuilder:length(...)@385: {0}, {-2_147_483_648..-1, 1..4_294_967_295}

        for (int i = 0; i < numArgs; i++) {
            if (builder.length() != 0) {
                builder.append('&');
            }

            builder.append(i);
        }

        return parseString(builder.toString());
    //#ConditionTree.java:392: end of method: ConditionTree com.dmdirc.actions.ConditionTree.createConjunction(int)
    }

}    //#ConditionTree.java:: end of class: com.dmdirc.actions.ConditionTree$OPERATION
    //#ConditionTree.java:: end of class: com.dmdirc.actions.ConditionTree$1
    //#output(com.dmdirc.actions.ConditionTree__static_init): __Descendant_Table[com/dmdirc/actions/ConditionTree]
    //#output(com.dmdirc.actions.ConditionTree__static_init): __Dispatch_Table.equals(Ljava/lang/Object;)Z
    //#output(com.dmdirc.actions.ConditionTree__static_init): __Dispatch_Table.evaluate([Z)Z
    //#output(com.dmdirc.actions.ConditionTree__static_init): __Dispatch_Table.getMaximumArgument()I
    //#output(com.dmdirc.actions.ConditionTree__static_init): __Dispatch_Table.hashCode()I
    //#output(com.dmdirc.actions.ConditionTree__static_init): __Dispatch_Table.toString()Ljava/lang/String;
    //#post(com.dmdirc.actions.ConditionTree__static_init): __Descendant_Table[com/dmdirc/actions/ConditionTree] == &__Dispatch_Table
    //#post(com.dmdirc.actions.ConditionTree__static_init): __Dispatch_Table.equals(Ljava/lang/Object;)Z == &equals
    //#post(com.dmdirc.actions.ConditionTree__static_init): __Dispatch_Table.evaluate([Z)Z == &evaluate
    //#post(com.dmdirc.actions.ConditionTree__static_init): __Dispatch_Table.getMaximumArgument()I == &getMaximumArgument
    //#post(com.dmdirc.actions.ConditionTree__static_init): __Dispatch_Table.hashCode()I == &hashCode
    //#post(com.dmdirc.actions.ConditionTree__static_init): __Dispatch_Table.toString()Ljava/lang/String; == &toString
    //#ConditionTree.java:: end of method: com.dmdirc.actions.ConditionTree.com.dmdirc.actions.ConditionTree__static_init
    //#ConditionTree.java:: end of class: com.dmdirc.actions.ConditionTree
