/************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
 *
 * Copyright 2008, 2010 Oracle and/or its affiliates. All rights reserved.
 *
 * Use is subject to license terms.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy
 * of the License at http://www.apache.org/licenses/LICENSE-2.0. You can also
 * obtain a copy of the License at http://odftoolkit.org/docs/license.txt
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 ************************************************************************/

/*
 * This file is automatically generated.
 * Don't edit manually.
 */
package org.odftoolkit.odfdom.dom.element.style;

import org.odftoolkit.odfdom.pkg.OdfElement;
import org.odftoolkit.odfdom.pkg.ElementVisitor;
import org.odftoolkit.odfdom.pkg.OdfFileDom;
import org.odftoolkit.odfdom.pkg.OdfName;
import org.odftoolkit.odfdom.dom.OdfDocumentNamespace;
import org.odftoolkit.odfdom.dom.DefaultElementVisitor;
import org.odftoolkit.odfdom.dom.element.svg.SvgDefinitionSrcElement;
import org.odftoolkit.odfdom.dom.element.svg.SvgFontFaceSrcElement;
import org.odftoolkit.odfdom.dom.attribute.style.StyleFontAdornmentsAttribute;
import org.odftoolkit.odfdom.dom.attribute.style.StyleFontCharsetAttribute;
import org.odftoolkit.odfdom.dom.attribute.style.StyleFontFamilyGenericAttribute;
import org.odftoolkit.odfdom.dom.attribute.style.StyleFontPitchAttribute;
import org.odftoolkit.odfdom.dom.attribute.style.StyleNameAttribute;
import org.odftoolkit.odfdom.dom.attribute.svg.SvgAccentHeightAttribute;
import org.odftoolkit.odfdom.dom.attribute.svg.SvgAlphabeticAttribute;
import org.odftoolkit.odfdom.dom.attribute.svg.SvgAscentAttribute;
import org.odftoolkit.odfdom.dom.attribute.svg.SvgBboxAttribute;
import org.odftoolkit.odfdom.dom.attribute.svg.SvgCapHeightAttribute;
import org.odftoolkit.odfdom.dom.attribute.svg.SvgDescentAttribute;
import org.odftoolkit.odfdom.dom.attribute.svg.SvgFontFamilyAttribute;
import org.odftoolkit.odfdom.dom.attribute.svg.SvgFontSizeAttribute;
import org.odftoolkit.odfdom.dom.attribute.svg.SvgFontStretchAttribute;
import org.odftoolkit.odfdom.dom.attribute.svg.SvgFontStyleAttribute;
import org.odftoolkit.odfdom.dom.attribute.svg.SvgFontVariantAttribute;
import org.odftoolkit.odfdom.dom.attribute.svg.SvgFontWeightAttribute;
import org.odftoolkit.odfdom.dom.attribute.svg.SvgHangingAttribute;
import org.odftoolkit.odfdom.dom.attribute.svg.SvgIdeographicAttribute;
import org.odftoolkit.odfdom.dom.attribute.svg.SvgMathematicalAttribute;
import org.odftoolkit.odfdom.dom.attribute.svg.SvgOverlinePositionAttribute;
import org.odftoolkit.odfdom.dom.attribute.svg.SvgOverlineThicknessAttribute;
import org.odftoolkit.odfdom.dom.attribute.svg.SvgPanose1Attribute;
import org.odftoolkit.odfdom.dom.attribute.svg.SvgSlopeAttribute;
import org.odftoolkit.odfdom.dom.attribute.svg.SvgStemhAttribute;
import org.odftoolkit.odfdom.dom.attribute.svg.SvgStemvAttribute;
import org.odftoolkit.odfdom.dom.attribute.svg.SvgStrikethroughPositionAttribute;
import org.odftoolkit.odfdom.dom.attribute.svg.SvgStrikethroughThicknessAttribute;
import org.odftoolkit.odfdom.dom.attribute.svg.SvgUnderlinePositionAttribute;
import org.odftoolkit.odfdom.dom.attribute.svg.SvgUnderlineThicknessAttribute;
import org.odftoolkit.odfdom.dom.attribute.svg.SvgUnicodeRangeAttribute;
import org.odftoolkit.odfdom.dom.attribute.svg.SvgUnitsPerEmAttribute;
import org.odftoolkit.odfdom.dom.attribute.svg.SvgVAlphabeticAttribute;
import org.odftoolkit.odfdom.dom.attribute.svg.SvgVHangingAttribute;
import org.odftoolkit.odfdom.dom.attribute.svg.SvgVIdeographicAttribute;
import org.odftoolkit.odfdom.dom.attribute.svg.SvgVMathematicalAttribute;
import org.odftoolkit.odfdom.dom.attribute.svg.SvgWidthsAttribute;
import org.odftoolkit.odfdom.dom.attribute.svg.SvgXHeightAttribute;

/**
 * DOM implementation of OpenDocument element  {@odf.element style:font-face}.
 *
 */
public class StyleFontFaceElement extends OdfElement {

	public static final OdfName ELEMENT_NAME = OdfName.newName(OdfDocumentNamespace.STYLE, "font-face");

	/**
	 * Create the instance of <code>StyleFontFaceElement</code>
	 *
	 * @param  ownerDoc     The type is <code>OdfFileDom</code>
	 */
	public StyleFontFaceElement(OdfFileDom ownerDoc) {
		super(ownerDoc, ELEMENT_NAME);
	}

	/**
	 * Get the element name
	 *
	 * @return  return   <code>OdfName</code> the name of element {@odf.element style:font-face}.
	 */
	public OdfName getOdfName() {
		return ELEMENT_NAME;
	}

	/**
	 * Receives the value of the ODFDOM attribute representation <code>StyleFontAdornmentsAttribute</code> , See {@odf.attribute style:font-adornments}
	 *
	 * @return - the <code>String</code> , the value or <code>null</code>, if the attribute is not set and no default value defined.
	 */
	public String getStyleFontAdornmentsAttribute() {
		StyleFontAdornmentsAttribute attr = (StyleFontAdornmentsAttribute) getOdfAttribute(OdfDocumentNamespace.STYLE, "font-adornments");
		if (attr != null) {
			return String.valueOf(attr.getValue());
		}
		return null;
	}

	/**
	 * Sets the value of ODFDOM attribute representation <code>StyleFontAdornmentsAttribute</code> , See {@odf.attribute style:font-adornments}
	 *
	 * @param styleFontAdornmentsValue   The type is <code>String</code>
	 */
	public void setStyleFontAdornmentsAttribute(String styleFontAdornmentsValue) {
		StyleFontAdornmentsAttribute attr = new StyleFontAdornmentsAttribute((OdfFileDom) this.ownerDocument);
		setOdfAttribute(attr);
		attr.setValue(styleFontAdornmentsValue);
	}

	/**
	 * Receives the value of the ODFDOM attribute representation <code>StyleFontCharsetAttribute</code> , See {@odf.attribute style:font-charset}
	 *
	 * @return - the <code>String</code> , the value or <code>null</code>, if the attribute is not set and no default value defined.
	 */
	public String getStyleFontCharsetAttribute() {
		StyleFontCharsetAttribute attr = (StyleFontCharsetAttribute) getOdfAttribute(OdfDocumentNamespace.STYLE, "font-charset");
		if (attr != null) {
			return String.valueOf(attr.getValue());
		}
		return null;
	}

	/**
	 * Sets the value of ODFDOM attribute representation <code>StyleFontCharsetAttribute</code> , See {@odf.attribute style:font-charset}
	 *
	 * @param styleFontCharsetValue   The type is <code>String</code>
	 */
	public void setStyleFontCharsetAttribute(String styleFontCharsetValue) {
		StyleFontCharsetAttribute attr = new StyleFontCharsetAttribute((OdfFileDom) this.ownerDocument);
		setOdfAttribute(attr);
		attr.setValue(styleFontCharsetValue);
	}

	/**
	 * Receives the value of the ODFDOM attribute representation <code>StyleFontFamilyGenericAttribute</code> , See {@odf.attribute style:font-family-generic}
	 *
	 * @return - the <code>String</code> , the value or <code>null</code>, if the attribute is not set and no default value defined.
	 */
	public String getStyleFontFamilyGenericAttribute() {
		StyleFontFamilyGenericAttribute attr = (StyleFontFamilyGenericAttribute) getOdfAttribute(OdfDocumentNamespace.STYLE, "font-family-generic");
		if (attr != null) {
			return String.valueOf(attr.getValue());
		}
		return null;
	}

	/**
	 * Sets the value of ODFDOM attribute representation <code>StyleFontFamilyGenericAttribute</code> , See {@odf.attribute style:font-family-generic}
	 *
	 * @param styleFontFamilyGenericValue   The type is <code>String</code>
	 */
	public void setStyleFontFamilyGenericAttribute(String styleFontFamilyGenericValue) {
		StyleFontFamilyGenericAttribute attr = new StyleFontFamilyGenericAttribute((OdfFileDom) this.ownerDocument);
		setOdfAttribute(attr);
		attr.setValue(styleFontFamilyGenericValue);
	}

	/**
	 * Receives the value of the ODFDOM attribute representation <code>StyleFontPitchAttribute</code> , See {@odf.attribute style:font-pitch}
	 *
	 * @return - the <code>String</code> , the value or <code>null</code>, if the attribute is not set and no default value defined.
	 */
	public String getStyleFontPitchAttribute() {
		StyleFontPitchAttribute attr = (StyleFontPitchAttribute) getOdfAttribute(OdfDocumentNamespace.STYLE, "font-pitch");
		if (attr != null) {
			return String.valueOf(attr.getValue());
		}
		return null;
	}

	/**
	 * Sets the value of ODFDOM attribute representation <code>StyleFontPitchAttribute</code> , See {@odf.attribute style:font-pitch}
	 *
	 * @param styleFontPitchValue   The type is <code>String</code>
	 */
	public void setStyleFontPitchAttribute(String styleFontPitchValue) {
		StyleFontPitchAttribute attr = new StyleFontPitchAttribute((OdfFileDom) this.ownerDocument);
		setOdfAttribute(attr);
		attr.setValue(styleFontPitchValue);
	}

	/**
	 * Receives the value of the ODFDOM attribute representation <code>StyleNameAttribute</code> , See {@odf.attribute style:name}
	 *
	 * Attribute is mandatory.
	 *
	 * @return - the <code>String</code> , the value or <code>null</code>, if the attribute is not set and no default value defined.
	 */
	public String getStyleNameAttribute() {
		StyleNameAttribute attr = (StyleNameAttribute) getOdfAttribute(OdfDocumentNamespace.STYLE, "name");
		if (attr != null) {
			return String.valueOf(attr.getValue());
		}
		return null;
	}

	/**
	 * Sets the value of ODFDOM attribute representation <code>StyleNameAttribute</code> , See {@odf.attribute style:name}
	 *
	 * @param styleNameValue   The type is <code>String</code>
	 */
	public void setStyleNameAttribute(String styleNameValue) {
		StyleNameAttribute attr = new StyleNameAttribute((OdfFileDom) this.ownerDocument);
		setOdfAttribute(attr);
		attr.setValue(styleNameValue);
	}

	/**
	 * Receives the value of the ODFDOM attribute representation <code>SvgAccentHeightAttribute</code> , See {@odf.attribute svg:accent-height}
	 *
	 * @return - the <code>Integer</code> , the value or <code>null</code>, if the attribute is not set and no default value defined.
	 */
	public Integer getSvgAccentHeightAttribute() {
		SvgAccentHeightAttribute attr = (SvgAccentHeightAttribute) getOdfAttribute(OdfDocumentNamespace.SVG, "accent-height");
		if (attr != null) {
			return Integer.valueOf(attr.intValue());
		}
		return null;
	}

	/**
	 * Sets the value of ODFDOM attribute representation <code>SvgAccentHeightAttribute</code> , See {@odf.attribute svg:accent-height}
	 *
	 * @param svgAccentHeightValue   The type is <code>Integer</code>
	 */
	public void setSvgAccentHeightAttribute(Integer svgAccentHeightValue) {
		SvgAccentHeightAttribute attr = new SvgAccentHeightAttribute((OdfFileDom) this.ownerDocument);
		setOdfAttribute(attr);
		attr.setIntValue(svgAccentHeightValue.intValue());
	}

	/**
	 * Receives the value of the ODFDOM attribute representation <code>SvgAlphabeticAttribute</code> , See {@odf.attribute svg:alphabetic}
	 *
	 * @return - the <code>Integer</code> , the value or <code>null</code>, if the attribute is not set and no default value defined.
	 */
	public Integer getSvgAlphabeticAttribute() {
		SvgAlphabeticAttribute attr = (SvgAlphabeticAttribute) getOdfAttribute(OdfDocumentNamespace.SVG, "alphabetic");
		if (attr != null) {
			return Integer.valueOf(attr.intValue());
		}
		return null;
	}

	/**
	 * Sets the value of ODFDOM attribute representation <code>SvgAlphabeticAttribute</code> , See {@odf.attribute svg:alphabetic}
	 *
	 * @param svgAlphabeticValue   The type is <code>Integer</code>
	 */
	public void setSvgAlphabeticAttribute(Integer svgAlphabeticValue) {
		SvgAlphabeticAttribute attr = new SvgAlphabeticAttribute((OdfFileDom) this.ownerDocument);
		setOdfAttribute(attr);
		attr.setIntValue(svgAlphabeticValue.intValue());
	}

	/**
	 * Receives the value of the ODFDOM attribute representation <code>SvgAscentAttribute</code> , See {@odf.attribute svg:ascent}
	 *
	 * @return - the <code>Integer</code> , the value or <code>null</code>, if the attribute is not set and no default value defined.
	 */
	public Integer getSvgAscentAttribute() {
		SvgAscentAttribute attr = (SvgAscentAttribute) getOdfAttribute(OdfDocumentNamespace.SVG, "ascent");
		if (attr != null) {
			return Integer.valueOf(attr.intValue());
		}
		return null;
	}

	/**
	 * Sets the value of ODFDOM attribute representation <code>SvgAscentAttribute</code> , See {@odf.attribute svg:ascent}
	 *
	 * @param svgAscentValue   The type is <code>Integer</code>
	 */
	public void setSvgAscentAttribute(Integer svgAscentValue) {
		SvgAscentAttribute attr = new SvgAscentAttribute((OdfFileDom) this.ownerDocument);
		setOdfAttribute(attr);
		attr.setIntValue(svgAscentValue.intValue());
	}

	/**
	 * Receives the value of the ODFDOM attribute representation <code>SvgBboxAttribute</code> , See {@odf.attribute svg:bbox}
	 *
	 * @return - the <code>String</code> , the value or <code>null</code>, if the attribute is not set and no default value defined.
	 */
	public String getSvgBboxAttribute() {
		SvgBboxAttribute attr = (SvgBboxAttribute) getOdfAttribute(OdfDocumentNamespace.SVG, "bbox");
		if (attr != null) {
			return String.valueOf(attr.getValue());
		}
		return null;
	}

	/**
	 * Sets the value of ODFDOM attribute representation <code>SvgBboxAttribute</code> , See {@odf.attribute svg:bbox}
	 *
	 * @param svgBboxValue   The type is <code>String</code>
	 */
	public void setSvgBboxAttribute(String svgBboxValue) {
		SvgBboxAttribute attr = new SvgBboxAttribute((OdfFileDom) this.ownerDocument);
		setOdfAttribute(attr);
		attr.setValue(svgBboxValue);
	}

	/**
	 * Receives the value of the ODFDOM attribute representation <code>SvgCapHeightAttribute</code> , See {@odf.attribute svg:cap-height}
	 *
	 * @return - the <code>Integer</code> , the value or <code>null</code>, if the attribute is not set and no default value defined.
	 */
	public Integer getSvgCapHeightAttribute() {
		SvgCapHeightAttribute attr = (SvgCapHeightAttribute) getOdfAttribute(OdfDocumentNamespace.SVG, "cap-height");
		if (attr != null) {
			return Integer.valueOf(attr.intValue());
		}
		return null;
	}

	/**
	 * Sets the value of ODFDOM attribute representation <code>SvgCapHeightAttribute</code> , See {@odf.attribute svg:cap-height}
	 *
	 * @param svgCapHeightValue   The type is <code>Integer</code>
	 */
	public void setSvgCapHeightAttribute(Integer svgCapHeightValue) {
		SvgCapHeightAttribute attr = new SvgCapHeightAttribute((OdfFileDom) this.ownerDocument);
		setOdfAttribute(attr);
		attr.setIntValue(svgCapHeightValue.intValue());
	}

	/**
	 * Receives the value of the ODFDOM attribute representation <code>SvgDescentAttribute</code> , See {@odf.attribute svg:descent}
	 *
	 * @return - the <code>Integer</code> , the value or <code>null</code>, if the attribute is not set and no default value defined.
	 */
	public Integer getSvgDescentAttribute() {
		SvgDescentAttribute attr = (SvgDescentAttribute) getOdfAttribute(OdfDocumentNamespace.SVG, "descent");
		if (attr != null) {
			return Integer.valueOf(attr.intValue());
		}
		return null;
	}

	/**
	 * Sets the value of ODFDOM attribute representation <code>SvgDescentAttribute</code> , See {@odf.attribute svg:descent}
	 *
	 * @param svgDescentValue   The type is <code>Integer</code>
	 */
	public void setSvgDescentAttribute(Integer svgDescentValue) {
		SvgDescentAttribute attr = new SvgDescentAttribute((OdfFileDom) this.ownerDocument);
		setOdfAttribute(attr);
		attr.setIntValue(svgDescentValue.intValue());
	}

	/**
	 * Receives the value of the ODFDOM attribute representation <code>SvgFontFamilyAttribute</code> , See {@odf.attribute svg:font-family}
	 *
	 * @return - the <code>String</code> , the value or <code>null</code>, if the attribute is not set and no default value defined.
	 */
	public String getSvgFontFamilyAttribute() {
		SvgFontFamilyAttribute attr = (SvgFontFamilyAttribute) getOdfAttribute(OdfDocumentNamespace.SVG, "font-family");
		if (attr != null) {
			return String.valueOf(attr.getValue());
		}
		return null;
	}

	/**
	 * Sets the value of ODFDOM attribute representation <code>SvgFontFamilyAttribute</code> , See {@odf.attribute svg:font-family}
	 *
	 * @param svgFontFamilyValue   The type is <code>String</code>
	 */
	public void setSvgFontFamilyAttribute(String svgFontFamilyValue) {
		SvgFontFamilyAttribute attr = new SvgFontFamilyAttribute((OdfFileDom) this.ownerDocument);
		setOdfAttribute(attr);
		attr.setValue(svgFontFamilyValue);
	}

	/**
	 * Receives the value of the ODFDOM attribute representation <code>SvgFontSizeAttribute</code> , See {@odf.attribute svg:font-size}
	 *
	 * @return - the <code>String</code> , the value or <code>null</code>, if the attribute is not set and no default value defined.
	 */
	public String getSvgFontSizeAttribute() {
		SvgFontSizeAttribute attr = (SvgFontSizeAttribute) getOdfAttribute(OdfDocumentNamespace.SVG, "font-size");
		if (attr != null) {
			return String.valueOf(attr.getValue());
		}
		return null;
	}

	/**
	 * Sets the value of ODFDOM attribute representation <code>SvgFontSizeAttribute</code> , See {@odf.attribute svg:font-size}
	 *
	 * @param svgFontSizeValue   The type is <code>String</code>
	 */
	public void setSvgFontSizeAttribute(String svgFontSizeValue) {
		SvgFontSizeAttribute attr = new SvgFontSizeAttribute((OdfFileDom) this.ownerDocument);
		setOdfAttribute(attr);
		attr.setValue(svgFontSizeValue);
	}

	/**
	 * Receives the value of the ODFDOM attribute representation <code>SvgFontStretchAttribute</code> , See {@odf.attribute svg:font-stretch}
	 *
	 * @return - the <code>String</code> , the value or <code>null</code>, if the attribute is not set and no default value defined.
	 */
	public String getSvgFontStretchAttribute() {
		SvgFontStretchAttribute attr = (SvgFontStretchAttribute) getOdfAttribute(OdfDocumentNamespace.SVG, "font-stretch");
		if (attr != null) {
			return String.valueOf(attr.getValue());
		}
		return null;
	}

	/**
	 * Sets the value of ODFDOM attribute representation <code>SvgFontStretchAttribute</code> , See {@odf.attribute svg:font-stretch}
	 *
	 * @param svgFontStretchValue   The type is <code>String</code>
	 */
	public void setSvgFontStretchAttribute(String svgFontStretchValue) {
		SvgFontStretchAttribute attr = new SvgFontStretchAttribute((OdfFileDom) this.ownerDocument);
		setOdfAttribute(attr);
		attr.setValue(svgFontStretchValue);
	}

	/**
	 * Receives the value of the ODFDOM attribute representation <code>SvgFontStyleAttribute</code> , See {@odf.attribute svg:font-style}
	 *
	 * @return - the <code>String</code> , the value or <code>null</code>, if the attribute is not set and no default value defined.
	 */
	public String getSvgFontStyleAttribute() {
		SvgFontStyleAttribute attr = (SvgFontStyleAttribute) getOdfAttribute(OdfDocumentNamespace.SVG, "font-style");
		if (attr != null) {
			return String.valueOf(attr.getValue());
		}
		return null;
	}

	/**
	 * Sets the value of ODFDOM attribute representation <code>SvgFontStyleAttribute</code> , See {@odf.attribute svg:font-style}
	 *
	 * @param svgFontStyleValue   The type is <code>String</code>
	 */
	public void setSvgFontStyleAttribute(String svgFontStyleValue) {
		SvgFontStyleAttribute attr = new SvgFontStyleAttribute((OdfFileDom) this.ownerDocument);
		setOdfAttribute(attr);
		attr.setValue(svgFontStyleValue);
	}

	/**
	 * Receives the value of the ODFDOM attribute representation <code>SvgFontVariantAttribute</code> , See {@odf.attribute svg:font-variant}
	 *
	 * @return - the <code>String</code> , the value or <code>null</code>, if the attribute is not set and no default value defined.
	 */
	public String getSvgFontVariantAttribute() {
		SvgFontVariantAttribute attr = (SvgFontVariantAttribute) getOdfAttribute(OdfDocumentNamespace.SVG, "font-variant");
		if (attr != null) {
			return String.valueOf(attr.getValue());
		}
		return null;
	}

	/**
	 * Sets the value of ODFDOM attribute representation <code>SvgFontVariantAttribute</code> , See {@odf.attribute svg:font-variant}
	 *
	 * @param svgFontVariantValue   The type is <code>String</code>
	 */
	public void setSvgFontVariantAttribute(String svgFontVariantValue) {
		SvgFontVariantAttribute attr = new SvgFontVariantAttribute((OdfFileDom) this.ownerDocument);
		setOdfAttribute(attr);
		attr.setValue(svgFontVariantValue);
	}

	/**
	 * Receives the value of the ODFDOM attribute representation <code>SvgFontWeightAttribute</code> , See {@odf.attribute svg:font-weight}
	 *
	 * @return - the <code>String</code> , the value or <code>null</code>, if the attribute is not set and no default value defined.
	 */
	public String getSvgFontWeightAttribute() {
		SvgFontWeightAttribute attr = (SvgFontWeightAttribute) getOdfAttribute(OdfDocumentNamespace.SVG, "font-weight");
		if (attr != null) {
			return String.valueOf(attr.getValue());
		}
		return null;
	}

	/**
	 * Sets the value of ODFDOM attribute representation <code>SvgFontWeightAttribute</code> , See {@odf.attribute svg:font-weight}
	 *
	 * @param svgFontWeightValue   The type is <code>String</code>
	 */
	public void setSvgFontWeightAttribute(String svgFontWeightValue) {
		SvgFontWeightAttribute attr = new SvgFontWeightAttribute((OdfFileDom) this.ownerDocument);
		setOdfAttribute(attr);
		attr.setValue(svgFontWeightValue);
	}

	/**
	 * Receives the value of the ODFDOM attribute representation <code>SvgHangingAttribute</code> , See {@odf.attribute svg:hanging}
	 *
	 * @return - the <code>Integer</code> , the value or <code>null</code>, if the attribute is not set and no default value defined.
	 */
	public Integer getSvgHangingAttribute() {
		SvgHangingAttribute attr = (SvgHangingAttribute) getOdfAttribute(OdfDocumentNamespace.SVG, "hanging");
		if (attr != null) {
			return Integer.valueOf(attr.intValue());
		}
		return null;
	}

	/**
	 * Sets the value of ODFDOM attribute representation <code>SvgHangingAttribute</code> , See {@odf.attribute svg:hanging}
	 *
	 * @param svgHangingValue   The type is <code>Integer</code>
	 */
	public void setSvgHangingAttribute(Integer svgHangingValue) {
		SvgHangingAttribute attr = new SvgHangingAttribute((OdfFileDom) this.ownerDocument);
		setOdfAttribute(attr);
		attr.setIntValue(svgHangingValue.intValue());
	}

	/**
	 * Receives the value of the ODFDOM attribute representation <code>SvgIdeographicAttribute</code> , See {@odf.attribute svg:ideographic}
	 *
	 * @return - the <code>Integer</code> , the value or <code>null</code>, if the attribute is not set and no default value defined.
	 */
	public Integer getSvgIdeographicAttribute() {
		SvgIdeographicAttribute attr = (SvgIdeographicAttribute) getOdfAttribute(OdfDocumentNamespace.SVG, "ideographic");
		if (attr != null) {
			return Integer.valueOf(attr.intValue());
		}
		return null;
	}

	/**
	 * Sets the value of ODFDOM attribute representation <code>SvgIdeographicAttribute</code> , See {@odf.attribute svg:ideographic}
	 *
	 * @param svgIdeographicValue   The type is <code>Integer</code>
	 */
	public void setSvgIdeographicAttribute(Integer svgIdeographicValue) {
		SvgIdeographicAttribute attr = new SvgIdeographicAttribute((OdfFileDom) this.ownerDocument);
		setOdfAttribute(attr);
		attr.setIntValue(svgIdeographicValue.intValue());
	}

	/**
	 * Receives the value of the ODFDOM attribute representation <code>SvgMathematicalAttribute</code> , See {@odf.attribute svg:mathematical}
	 *
	 * @return - the <code>Integer</code> , the value or <code>null</code>, if the attribute is not set and no default value defined.
	 */
	public Integer getSvgMathematicalAttribute() {
		SvgMathematicalAttribute attr = (SvgMathematicalAttribute) getOdfAttribute(OdfDocumentNamespace.SVG, "mathematical");
		if (attr != null) {
			return Integer.valueOf(attr.intValue());
		}
		return null;
	}

	/**
	 * Sets the value of ODFDOM attribute representation <code>SvgMathematicalAttribute</code> , See {@odf.attribute svg:mathematical}
	 *
	 * @param svgMathematicalValue   The type is <code>Integer</code>
	 */
	public void setSvgMathematicalAttribute(Integer svgMathematicalValue) {
		SvgMathematicalAttribute attr = new SvgMathematicalAttribute((OdfFileDom) this.ownerDocument);
		setOdfAttribute(attr);
		attr.setIntValue(svgMathematicalValue.intValue());
	}

	/**
	 * Receives the value of the ODFDOM attribute representation <code>SvgOverlinePositionAttribute</code> , See {@odf.attribute svg:overline-position}
	 *
	 * @return - the <code>Integer</code> , the value or <code>null</code>, if the attribute is not set and no default value defined.
	 */
	public Integer getSvgOverlinePositionAttribute() {
		SvgOverlinePositionAttribute attr = (SvgOverlinePositionAttribute) getOdfAttribute(OdfDocumentNamespace.SVG, "overline-position");
		if (attr != null) {
			return Integer.valueOf(attr.intValue());
		}
		return null;
	}

	/**
	 * Sets the value of ODFDOM attribute representation <code>SvgOverlinePositionAttribute</code> , See {@odf.attribute svg:overline-position}
	 *
	 * @param svgOverlinePositionValue   The type is <code>Integer</code>
	 */
	public void setSvgOverlinePositionAttribute(Integer svgOverlinePositionValue) {
		SvgOverlinePositionAttribute attr = new SvgOverlinePositionAttribute((OdfFileDom) this.ownerDocument);
		setOdfAttribute(attr);
		attr.setIntValue(svgOverlinePositionValue.intValue());
	}

	/**
	 * Receives the value of the ODFDOM attribute representation <code>SvgOverlineThicknessAttribute</code> , See {@odf.attribute svg:overline-thickness}
	 *
	 * @return - the <code>Integer</code> , the value or <code>null</code>, if the attribute is not set and no default value defined.
	 */
	public Integer getSvgOverlineThicknessAttribute() {
		SvgOverlineThicknessAttribute attr = (SvgOverlineThicknessAttribute) getOdfAttribute(OdfDocumentNamespace.SVG, "overline-thickness");
		if (attr != null) {
			return Integer.valueOf(attr.intValue());
		}
		return null;
	}

	/**
	 * Sets the value of ODFDOM attribute representation <code>SvgOverlineThicknessAttribute</code> , See {@odf.attribute svg:overline-thickness}
	 *
	 * @param svgOverlineThicknessValue   The type is <code>Integer</code>
	 */
	public void setSvgOverlineThicknessAttribute(Integer svgOverlineThicknessValue) {
		SvgOverlineThicknessAttribute attr = new SvgOverlineThicknessAttribute((OdfFileDom) this.ownerDocument);
		setOdfAttribute(attr);
		attr.setIntValue(svgOverlineThicknessValue.intValue());
	}

	/**
	 * Receives the value of the ODFDOM attribute representation <code>SvgPanose1Attribute</code> , See {@odf.attribute svg:panose-1}
	 *
	 * @return - the <code>String</code> , the value or <code>null</code>, if the attribute is not set and no default value defined.
	 */
	public String getSvgPanose1Attribute() {
		SvgPanose1Attribute attr = (SvgPanose1Attribute) getOdfAttribute(OdfDocumentNamespace.SVG, "panose-1");
		if (attr != null) {
			return String.valueOf(attr.getValue());
		}
		return null;
	}

	/**
	 * Sets the value of ODFDOM attribute representation <code>SvgPanose1Attribute</code> , See {@odf.attribute svg:panose-1}
	 *
	 * @param svgPanose1Value   The type is <code>String</code>
	 */
	public void setSvgPanose1Attribute(String svgPanose1Value) {
		SvgPanose1Attribute attr = new SvgPanose1Attribute((OdfFileDom) this.ownerDocument);
		setOdfAttribute(attr);
		attr.setValue(svgPanose1Value);
	}

	/**
	 * Receives the value of the ODFDOM attribute representation <code>SvgSlopeAttribute</code> , See {@odf.attribute svg:slope}
	 *
	 * @return - the <code>Integer</code> , the value or <code>null</code>, if the attribute is not set and no default value defined.
	 */
	public Integer getSvgSlopeAttribute() {
		SvgSlopeAttribute attr = (SvgSlopeAttribute) getOdfAttribute(OdfDocumentNamespace.SVG, "slope");
		if (attr != null) {
			return Integer.valueOf(attr.intValue());
		}
		return null;
	}

	/**
	 * Sets the value of ODFDOM attribute representation <code>SvgSlopeAttribute</code> , See {@odf.attribute svg:slope}
	 *
	 * @param svgSlopeValue   The type is <code>Integer</code>
	 */
	public void setSvgSlopeAttribute(Integer svgSlopeValue) {
		SvgSlopeAttribute attr = new SvgSlopeAttribute((OdfFileDom) this.ownerDocument);
		setOdfAttribute(attr);
		attr.setIntValue(svgSlopeValue.intValue());
	}

	/**
	 * Receives the value of the ODFDOM attribute representation <code>SvgStemhAttribute</code> , See {@odf.attribute svg:stemh}
	 *
	 * @return - the <code>Integer</code> , the value or <code>null</code>, if the attribute is not set and no default value defined.
	 */
	public Integer getSvgStemhAttribute() {
		SvgStemhAttribute attr = (SvgStemhAttribute) getOdfAttribute(OdfDocumentNamespace.SVG, "stemh");
		if (attr != null) {
			return Integer.valueOf(attr.intValue());
		}
		return null;
	}

	/**
	 * Sets the value of ODFDOM attribute representation <code>SvgStemhAttribute</code> , See {@odf.attribute svg:stemh}
	 *
	 * @param svgStemhValue   The type is <code>Integer</code>
	 */
	public void setSvgStemhAttribute(Integer svgStemhValue) {
		SvgStemhAttribute attr = new SvgStemhAttribute((OdfFileDom) this.ownerDocument);
		setOdfAttribute(attr);
		attr.setIntValue(svgStemhValue.intValue());
	}

	/**
	 * Receives the value of the ODFDOM attribute representation <code>SvgStemvAttribute</code> , See {@odf.attribute svg:stemv}
	 *
	 * @return - the <code>Integer</code> , the value or <code>null</code>, if the attribute is not set and no default value defined.
	 */
	public Integer getSvgStemvAttribute() {
		SvgStemvAttribute attr = (SvgStemvAttribute) getOdfAttribute(OdfDocumentNamespace.SVG, "stemv");
		if (attr != null) {
			return Integer.valueOf(attr.intValue());
		}
		return null;
	}

	/**
	 * Sets the value of ODFDOM attribute representation <code>SvgStemvAttribute</code> , See {@odf.attribute svg:stemv}
	 *
	 * @param svgStemvValue   The type is <code>Integer</code>
	 */
	public void setSvgStemvAttribute(Integer svgStemvValue) {
		SvgStemvAttribute attr = new SvgStemvAttribute((OdfFileDom) this.ownerDocument);
		setOdfAttribute(attr);
		attr.setIntValue(svgStemvValue.intValue());
	}

	/**
	 * Receives the value of the ODFDOM attribute representation <code>SvgStrikethroughPositionAttribute</code> , See {@odf.attribute svg:strikethrough-position}
	 *
	 * @return - the <code>Integer</code> , the value or <code>null</code>, if the attribute is not set and no default value defined.
	 */
	public Integer getSvgStrikethroughPositionAttribute() {
		SvgStrikethroughPositionAttribute attr = (SvgStrikethroughPositionAttribute) getOdfAttribute(OdfDocumentNamespace.SVG, "strikethrough-position");
		if (attr != null) {
			return Integer.valueOf(attr.intValue());
		}
		return null;
	}

	/**
	 * Sets the value of ODFDOM attribute representation <code>SvgStrikethroughPositionAttribute</code> , See {@odf.attribute svg:strikethrough-position}
	 *
	 * @param svgStrikethroughPositionValue   The type is <code>Integer</code>
	 */
	public void setSvgStrikethroughPositionAttribute(Integer svgStrikethroughPositionValue) {
		SvgStrikethroughPositionAttribute attr = new SvgStrikethroughPositionAttribute((OdfFileDom) this.ownerDocument);
		setOdfAttribute(attr);
		attr.setIntValue(svgStrikethroughPositionValue.intValue());
	}

	/**
	 * Receives the value of the ODFDOM attribute representation <code>SvgStrikethroughThicknessAttribute</code> , See {@odf.attribute svg:strikethrough-thickness}
	 *
	 * @return - the <code>Integer</code> , the value or <code>null</code>, if the attribute is not set and no default value defined.
	 */
	public Integer getSvgStrikethroughThicknessAttribute() {
		SvgStrikethroughThicknessAttribute attr = (SvgStrikethroughThicknessAttribute) getOdfAttribute(OdfDocumentNamespace.SVG, "strikethrough-thickness");
		if (attr != null) {
			return Integer.valueOf(attr.intValue());
		}
		return null;
	}

	/**
	 * Sets the value of ODFDOM attribute representation <code>SvgStrikethroughThicknessAttribute</code> , See {@odf.attribute svg:strikethrough-thickness}
	 *
	 * @param svgStrikethroughThicknessValue   The type is <code>Integer</code>
	 */
	public void setSvgStrikethroughThicknessAttribute(Integer svgStrikethroughThicknessValue) {
		SvgStrikethroughThicknessAttribute attr = new SvgStrikethroughThicknessAttribute((OdfFileDom) this.ownerDocument);
		setOdfAttribute(attr);
		attr.setIntValue(svgStrikethroughThicknessValue.intValue());
	}

	/**
	 * Receives the value of the ODFDOM attribute representation <code>SvgUnderlinePositionAttribute</code> , See {@odf.attribute svg:underline-position}
	 *
	 * @return - the <code>Integer</code> , the value or <code>null</code>, if the attribute is not set and no default value defined.
	 */
	public Integer getSvgUnderlinePositionAttribute() {
		SvgUnderlinePositionAttribute attr = (SvgUnderlinePositionAttribute) getOdfAttribute(OdfDocumentNamespace.SVG, "underline-position");
		if (attr != null) {
			return Integer.valueOf(attr.intValue());
		}
		return null;
	}

	/**
	 * Sets the value of ODFDOM attribute representation <code>SvgUnderlinePositionAttribute</code> , See {@odf.attribute svg:underline-position}
	 *
	 * @param svgUnderlinePositionValue   The type is <code>Integer</code>
	 */
	public void setSvgUnderlinePositionAttribute(Integer svgUnderlinePositionValue) {
		SvgUnderlinePositionAttribute attr = new SvgUnderlinePositionAttribute((OdfFileDom) this.ownerDocument);
		setOdfAttribute(attr);
		attr.setIntValue(svgUnderlinePositionValue.intValue());
	}

	/**
	 * Receives the value of the ODFDOM attribute representation <code>SvgUnderlineThicknessAttribute</code> , See {@odf.attribute svg:underline-thickness}
	 *
	 * @return - the <code>Integer</code> , the value or <code>null</code>, if the attribute is not set and no default value defined.
	 */
	public Integer getSvgUnderlineThicknessAttribute() {
		SvgUnderlineThicknessAttribute attr = (SvgUnderlineThicknessAttribute) getOdfAttribute(OdfDocumentNamespace.SVG, "underline-thickness");
		if (attr != null) {
			return Integer.valueOf(attr.intValue());
		}
		return null;
	}

	/**
	 * Sets the value of ODFDOM attribute representation <code>SvgUnderlineThicknessAttribute</code> , See {@odf.attribute svg:underline-thickness}
	 *
	 * @param svgUnderlineThicknessValue   The type is <code>Integer</code>
	 */
	public void setSvgUnderlineThicknessAttribute(Integer svgUnderlineThicknessValue) {
		SvgUnderlineThicknessAttribute attr = new SvgUnderlineThicknessAttribute((OdfFileDom) this.ownerDocument);
		setOdfAttribute(attr);
		attr.setIntValue(svgUnderlineThicknessValue.intValue());
	}

	/**
	 * Receives the value of the ODFDOM attribute representation <code>SvgUnicodeRangeAttribute</code> , See {@odf.attribute svg:unicode-range}
	 *
	 * @return - the <code>String</code> , the value or <code>null</code>, if the attribute is not set and no default value defined.
	 */
	public String getSvgUnicodeRangeAttribute() {
		SvgUnicodeRangeAttribute attr = (SvgUnicodeRangeAttribute) getOdfAttribute(OdfDocumentNamespace.SVG, "unicode-range");
		if (attr != null) {
			return String.valueOf(attr.getValue());
		}
		return null;
	}

	/**
	 * Sets the value of ODFDOM attribute representation <code>SvgUnicodeRangeAttribute</code> , See {@odf.attribute svg:unicode-range}
	 *
	 * @param svgUnicodeRangeValue   The type is <code>String</code>
	 */
	public void setSvgUnicodeRangeAttribute(String svgUnicodeRangeValue) {
		SvgUnicodeRangeAttribute attr = new SvgUnicodeRangeAttribute((OdfFileDom) this.ownerDocument);
		setOdfAttribute(attr);
		attr.setValue(svgUnicodeRangeValue);
	}

	/**
	 * Receives the value of the ODFDOM attribute representation <code>SvgUnitsPerEmAttribute</code> , See {@odf.attribute svg:units-per-em}
	 *
	 * @return - the <code>Integer</code> , the value or <code>null</code>, if the attribute is not set and no default value defined.
	 */
	public Integer getSvgUnitsPerEmAttribute() {
		SvgUnitsPerEmAttribute attr = (SvgUnitsPerEmAttribute) getOdfAttribute(OdfDocumentNamespace.SVG, "units-per-em");
		if (attr != null) {
			return Integer.valueOf(attr.intValue());
		}
		return null;
	}

	/**
	 * Sets the value of ODFDOM attribute representation <code>SvgUnitsPerEmAttribute</code> , See {@odf.attribute svg:units-per-em}
	 *
	 * @param svgUnitsPerEmValue   The type is <code>Integer</code>
	 */
	public void setSvgUnitsPerEmAttribute(Integer svgUnitsPerEmValue) {
		SvgUnitsPerEmAttribute attr = new SvgUnitsPerEmAttribute((OdfFileDom) this.ownerDocument);
		setOdfAttribute(attr);
		attr.setIntValue(svgUnitsPerEmValue.intValue());
	}

	/**
	 * Receives the value of the ODFDOM attribute representation <code>SvgVAlphabeticAttribute</code> , See {@odf.attribute svg:v-alphabetic}
	 *
	 * @return - the <code>Integer</code> , the value or <code>null</code>, if the attribute is not set and no default value defined.
	 */
	public Integer getSvgVAlphabeticAttribute() {
		SvgVAlphabeticAttribute attr = (SvgVAlphabeticAttribute) getOdfAttribute(OdfDocumentNamespace.SVG, "v-alphabetic");
		if (attr != null) {
			return Integer.valueOf(attr.intValue());
		}
		return null;
	}

	/**
	 * Sets the value of ODFDOM attribute representation <code>SvgVAlphabeticAttribute</code> , See {@odf.attribute svg:v-alphabetic}
	 *
	 * @param svgVAlphabeticValue   The type is <code>Integer</code>
	 */
	public void setSvgVAlphabeticAttribute(Integer svgVAlphabeticValue) {
		SvgVAlphabeticAttribute attr = new SvgVAlphabeticAttribute((OdfFileDom) this.ownerDocument);
		setOdfAttribute(attr);
		attr.setIntValue(svgVAlphabeticValue.intValue());
	}

	/**
	 * Receives the value of the ODFDOM attribute representation <code>SvgVHangingAttribute</code> , See {@odf.attribute svg:v-hanging}
	 *
	 * @return - the <code>Integer</code> , the value or <code>null</code>, if the attribute is not set and no default value defined.
	 */
	public Integer getSvgVHangingAttribute() {
		SvgVHangingAttribute attr = (SvgVHangingAttribute) getOdfAttribute(OdfDocumentNamespace.SVG, "v-hanging");
		if (attr != null) {
			return Integer.valueOf(attr.intValue());
		}
		return null;
	}

	/**
	 * Sets the value of ODFDOM attribute representation <code>SvgVHangingAttribute</code> , See {@odf.attribute svg:v-hanging}
	 *
	 * @param svgVHangingValue   The type is <code>Integer</code>
	 */
	public void setSvgVHangingAttribute(Integer svgVHangingValue) {
		SvgVHangingAttribute attr = new SvgVHangingAttribute((OdfFileDom) this.ownerDocument);
		setOdfAttribute(attr);
		attr.setIntValue(svgVHangingValue.intValue());
	}

	/**
	 * Receives the value of the ODFDOM attribute representation <code>SvgVIdeographicAttribute</code> , See {@odf.attribute svg:v-ideographic}
	 *
	 * @return - the <code>Integer</code> , the value or <code>null</code>, if the attribute is not set and no default value defined.
	 */
	public Integer getSvgVIdeographicAttribute() {
		SvgVIdeographicAttribute attr = (SvgVIdeographicAttribute) getOdfAttribute(OdfDocumentNamespace.SVG, "v-ideographic");
		if (attr != null) {
			return Integer.valueOf(attr.intValue());
		}
		return null;
	}

	/**
	 * Sets the value of ODFDOM attribute representation <code>SvgVIdeographicAttribute</code> , See {@odf.attribute svg:v-ideographic}
	 *
	 * @param svgVIdeographicValue   The type is <code>Integer</code>
	 */
	public void setSvgVIdeographicAttribute(Integer svgVIdeographicValue) {
		SvgVIdeographicAttribute attr = new SvgVIdeographicAttribute((OdfFileDom) this.ownerDocument);
		setOdfAttribute(attr);
		attr.setIntValue(svgVIdeographicValue.intValue());
	}

	/**
	 * Receives the value of the ODFDOM attribute representation <code>SvgVMathematicalAttribute</code> , See {@odf.attribute svg:v-mathematical}
	 *
	 * @return - the <code>Integer</code> , the value or <code>null</code>, if the attribute is not set and no default value defined.
	 */
	public Integer getSvgVMathematicalAttribute() {
		SvgVMathematicalAttribute attr = (SvgVMathematicalAttribute) getOdfAttribute(OdfDocumentNamespace.SVG, "v-mathematical");
		if (attr != null) {
			return Integer.valueOf(attr.intValue());
		}
		return null;
	}

	/**
	 * Sets the value of ODFDOM attribute representation <code>SvgVMathematicalAttribute</code> , See {@odf.attribute svg:v-mathematical}
	 *
	 * @param svgVMathematicalValue   The type is <code>Integer</code>
	 */
	public void setSvgVMathematicalAttribute(Integer svgVMathematicalValue) {
		SvgVMathematicalAttribute attr = new SvgVMathematicalAttribute((OdfFileDom) this.ownerDocument);
		setOdfAttribute(attr);
		attr.setIntValue(svgVMathematicalValue.intValue());
	}

	/**
	 * Receives the value of the ODFDOM attribute representation <code>SvgWidthsAttribute</code> , See {@odf.attribute svg:widths}
	 *
	 * @return - the <code>String</code> , the value or <code>null</code>, if the attribute is not set and no default value defined.
	 */
	public String getSvgWidthsAttribute() {
		SvgWidthsAttribute attr = (SvgWidthsAttribute) getOdfAttribute(OdfDocumentNamespace.SVG, "widths");
		if (attr != null) {
			return String.valueOf(attr.getValue());
		}
		return null;
	}

	/**
	 * Sets the value of ODFDOM attribute representation <code>SvgWidthsAttribute</code> , See {@odf.attribute svg:widths}
	 *
	 * @param svgWidthsValue   The type is <code>String</code>
	 */
	public void setSvgWidthsAttribute(String svgWidthsValue) {
		SvgWidthsAttribute attr = new SvgWidthsAttribute((OdfFileDom) this.ownerDocument);
		setOdfAttribute(attr);
		attr.setValue(svgWidthsValue);
	}

	/**
	 * Receives the value of the ODFDOM attribute representation <code>SvgXHeightAttribute</code> , See {@odf.attribute svg:x-height}
	 *
	 * @return - the <code>Integer</code> , the value or <code>null</code>, if the attribute is not set and no default value defined.
	 */
	public Integer getSvgXHeightAttribute() {
		SvgXHeightAttribute attr = (SvgXHeightAttribute) getOdfAttribute(OdfDocumentNamespace.SVG, "x-height");
		if (attr != null) {
			return Integer.valueOf(attr.intValue());
		}
		return null;
	}

	/**
	 * Sets the value of ODFDOM attribute representation <code>SvgXHeightAttribute</code> , See {@odf.attribute svg:x-height}
	 *
	 * @param svgXHeightValue   The type is <code>Integer</code>
	 */
	public void setSvgXHeightAttribute(Integer svgXHeightValue) {
		SvgXHeightAttribute attr = new SvgXHeightAttribute((OdfFileDom) this.ownerDocument);
		setOdfAttribute(attr);
		attr.setIntValue(svgXHeightValue.intValue());
	}

	/**
	 * Create child element {@odf.element svg:definition-src}.
	 *
	 * @param xlinkHrefValue  the <code>String</code> value of <code>XlinkHrefAttribute</code>, see {@odf.attribute  xlink:href} at specification
	 * @param xlinkTypeValue  the <code>String</code> value of <code>XlinkTypeAttribute</code>, see {@odf.attribute  xlink:type} at specification
	 * @return the element {@odf.element svg:definition-src}
	 */
	 public SvgDefinitionSrcElement newSvgDefinitionSrcElement(String xlinkHrefValue, String xlinkTypeValue) {
		SvgDefinitionSrcElement svgDefinitionSrc = ((OdfFileDom) this.ownerDocument).newOdfElement(SvgDefinitionSrcElement.class);
		svgDefinitionSrc.setXlinkHrefAttribute(xlinkHrefValue);
		svgDefinitionSrc.setXlinkTypeAttribute(xlinkTypeValue);
		this.appendChild(svgDefinitionSrc);
		return svgDefinitionSrc;
	}

	/**
	 * Create child element {@odf.element svg:font-face-src}.
	 *
	 * @return the element {@odf.element svg:font-face-src}
	 */
	public SvgFontFaceSrcElement newSvgFontFaceSrcElement() {
		SvgFontFaceSrcElement svgFontFaceSrc = ((OdfFileDom) this.ownerDocument).newOdfElement(SvgFontFaceSrcElement.class);
		this.appendChild(svgFontFaceSrc);
		return svgFontFaceSrc;
	}

	@Override
	public void accept(ElementVisitor visitor) {
		if (visitor instanceof DefaultElementVisitor) {
			DefaultElementVisitor defaultVisitor = (DefaultElementVisitor) visitor;
			defaultVisitor.visit(this);
		} else {
			visitor.visit(this);
		}
	}
}
