//
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.0.5-b02-fcs 
// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
// Any modifications to this file will be lost upon recompilation of the source schema. 
// Generated on: 2011.02.27 at 07:28:19 PM CST 
//

package org.eclipse.ptp.rm.jaxb.core.data;

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

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;

/**
 * <p>
 * Java class for anonymous complex type.
 * 
 * <p>
 * The following schema fragment specifies the expected content contained within
 * this class.
 * 
 * <pre>
 * &lt;complexType>
 *   &lt;complexContent>
 *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
 *       &lt;sequence>
 *         &lt;element ref="{}arglist"/>
 *         &lt;element ref="{}parser-ref" maxOccurs="2" minOccurs="0"/>
 *         &lt;element ref="{}environment-variables" minOccurs="0"/>
 *       &lt;/sequence>
 *       &lt;attribute name="directory" type="{http://www.w3.org/2001/XMLSchema}string" />
 *       &lt;attribute name="displayStderr" type="{http://www.w3.org/2001/XMLSchema}boolean" default="false" />
 *       &lt;attribute name="displayStdout" type="{http://www.w3.org/2001/XMLSchema}boolean" default="false" />
 *       &lt;attribute name="name" type="{http://www.w3.org/2001/XMLSchema}string" />
 *       &lt;attribute name="redirectStderr" type="{http://www.w3.org/2001/XMLSchema}boolean" default="false" />
 *       &lt;attribute name="replaceEnvironment" type="{http://www.w3.org/2001/XMLSchema}boolean" default="false" />
 *     &lt;/restriction>
 *   &lt;/complexContent>
 * &lt;/complexType>
 * </pre>
 * 
 * 
 */
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = { "arglist", "parserRef", "environmentVariables" })
@XmlRootElement(name = "command")
public class Command {

	@XmlElement(required = true)
	protected Arglist arglist;
	@XmlElement(name = "parser-ref")
	protected List<String> parserRef;
	@XmlElement(name = "environment-variables")
	protected EnvironmentVariables environmentVariables;
	@XmlAttribute
	protected String directory;
	@XmlAttribute
	protected Boolean displayStderr;
	@XmlAttribute
	protected Boolean displayStdout;
	@XmlAttribute
	protected String name;
	@XmlAttribute
	protected Boolean redirectStderr;
	@XmlAttribute
	protected Boolean replaceEnvironment;

	/**
	 * Gets the value of the arglist property.
	 * 
	 * @return possible object is {@link Arglist }
	 * 
	 */
	public Arglist getArglist() {
		return arglist;
	}

	/**
	 * Gets the value of the directory property.
	 * 
	 * @return possible object is {@link String }
	 * 
	 */
	public String getDirectory() {
		return directory;
	}

	/**
	 * Gets the value of the environmentVariables property.
	 * 
	 * @return possible object is {@link EnvironmentVariables }
	 * 
	 */
	public EnvironmentVariables getEnvironmentVariables() {
		return environmentVariables;
	}

	/**
	 * Gets the value of the name property.
	 * 
	 * @return possible object is {@link String }
	 * 
	 */
	public String getName() {
		return name;
	}

	/**
	 * Gets the value of the parserRef property.
	 * 
	 * <p>
	 * This accessor method returns a reference to the live list, not a
	 * snapshot. Therefore any modification you make to the returned list will
	 * be present inside the JAXB object. This is why there is not a
	 * <CODE>set</CODE> method for the parserRef property.
	 * 
	 * <p>
	 * For example, to add a new item, do as follows:
	 * 
	 * <pre>
	 * getParserRef().add(newItem);
	 * </pre>
	 * 
	 * 
	 * <p>
	 * Objects of the following type(s) are allowed in the list {@link String }
	 * 
	 * 
	 */
	public List<String> getParserRef() {
		if (parserRef == null) {
			parserRef = new ArrayList<String>();
		}
		return this.parserRef;
	}

	/**
	 * Gets the value of the displayStderr property.
	 * 
	 * @return possible object is {@link Boolean }
	 * 
	 */
	public boolean isDisplayStderr() {
		if (displayStderr == null) {
			return false;
		} else {
			return displayStderr;
		}
	}

	/**
	 * Gets the value of the displayStdout property.
	 * 
	 * @return possible object is {@link Boolean }
	 * 
	 */
	public boolean isDisplayStdout() {
		if (displayStdout == null) {
			return false;
		} else {
			return displayStdout;
		}
	}

	/**
	 * Gets the value of the redirectStderr property.
	 * 
	 * @return possible object is {@link Boolean }
	 * 
	 */
	public boolean isRedirectStderr() {
		if (redirectStderr == null) {
			return false;
		} else {
			return redirectStderr;
		}
	}

	/**
	 * Gets the value of the replaceEnvironment property.
	 * 
	 * @return possible object is {@link Boolean }
	 * 
	 */
	public boolean isReplaceEnvironment() {
		if (replaceEnvironment == null) {
			return false;
		} else {
			return replaceEnvironment;
		}
	}

	/**
	 * Sets the value of the arglist property.
	 * 
	 * @param value
	 *            allowed object is {@link Arglist }
	 * 
	 */
	public void setArglist(Arglist value) {
		this.arglist = value;
	}

	/**
	 * Sets the value of the directory property.
	 * 
	 * @param value
	 *            allowed object is {@link String }
	 * 
	 */
	public void setDirectory(String value) {
		this.directory = value;
	}

	/**
	 * Sets the value of the displayStderr property.
	 * 
	 * @param value
	 *            allowed object is {@link Boolean }
	 * 
	 */
	public void setDisplayStderr(Boolean value) {
		this.displayStderr = value;
	}

	/**
	 * Sets the value of the displayStdout property.
	 * 
	 * @param value
	 *            allowed object is {@link Boolean }
	 * 
	 */
	public void setDisplayStdout(Boolean value) {
		this.displayStdout = value;
	}

	/**
	 * Sets the value of the environmentVariables property.
	 * 
	 * @param value
	 *            allowed object is {@link EnvironmentVariables }
	 * 
	 */
	public void setEnvironmentVariables(EnvironmentVariables value) {
		this.environmentVariables = value;
	}

	/**
	 * Sets the value of the name property.
	 * 
	 * @param value
	 *            allowed object is {@link String }
	 * 
	 */
	public void setName(String value) {
		this.name = value;
	}

	/**
	 * Sets the value of the redirectStderr property.
	 * 
	 * @param value
	 *            allowed object is {@link Boolean }
	 * 
	 */
	public void setRedirectStderr(Boolean value) {
		this.redirectStderr = value;
	}

	/**
	 * Sets the value of the replaceEnvironment property.
	 * 
	 * @param value
	 *            allowed object is {@link Boolean }
	 * 
	 */
	public void setReplaceEnvironment(Boolean value) {
		this.replaceEnvironment = value;
	}

}
