/* This file was generated by SableCC (http://www.sablecc.org/). */

package com.google.clearsilver.jsilver.syntax.node;

import java.util.*;
import com.google.clearsilver.jsilver.syntax.analysis.*;

@SuppressWarnings("nls")
public final class AMultipleCommand extends PCommand
{
    private final LinkedList<PCommand> _command_ = new LinkedList<PCommand>();

    public AMultipleCommand()
    {
        // Constructor
    }

    public AMultipleCommand(
        @SuppressWarnings("hiding") List<PCommand> _command_)
    {
        // Constructor
        setCommand(_command_);

    }

    @Override
    public Object clone()
    {
        return new AMultipleCommand(
            cloneList(this._command_));
    }

    public void apply(Switch sw)
    {
        ((Analysis) sw).caseAMultipleCommand(this);
    }

    public LinkedList<PCommand> getCommand()
    {
        return this._command_;
    }

    public void setCommand(List<PCommand> list)
    {
        this._command_.clear();
        this._command_.addAll(list);
        for(PCommand e : list)
        {
            if(e.parent() != null)
            {
                e.parent().removeChild(e);
            }

            e.parent(this);
        }
    }

    @Override
    public String toString()
    {
        return ""
            + toString(this._command_);
    }

    @Override
    void removeChild(@SuppressWarnings("unused") Node child)
    {
        // Remove child
        if(this._command_.remove(child))
        {
            return;
        }

        throw new RuntimeException("Not a child.");
    }

    @Override
    void replaceChild(@SuppressWarnings("unused") Node oldChild, @SuppressWarnings("unused") Node newChild)
    {
        // Replace child
        for(ListIterator<PCommand> i = this._command_.listIterator(); i.hasNext();)
        {
            if(i.next() == oldChild)
            {
                if(newChild != null)
                {
                    i.set((PCommand) newChild);
                    newChild.parent(this);
                    oldChild.parent(null);
                    return;
                }

                i.remove();
                oldChild.parent(null);
                return;
            }
        }

        throw new RuntimeException("Not a child.");
    }
}
