/*
 * Copyright 2008 Google Inc.
 * 
 * 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
 * 
 * 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.
 */
package com.google.gwt.uibinder.rebind;

import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.core.ext.typeinfo.JClassType;
import com.google.gwt.core.ext.typeinfo.JType;
import com.google.gwt.core.ext.typeinfo.TypeOracle;
import com.google.gwt.core.ext.typeinfo.TypeOracleException;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.resources.client.ImageResource;
import com.google.gwt.uibinder.attributeparsers.AttributeParser;
import com.google.gwt.uibinder.attributeparsers.AttributeParsers;

import org.w3c.dom.Attr;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * A wrapper for {@link Element} that limits the way parsers can interact with
 * the XML document, and provides some convenience methods.
 * <p>
 * The main function of this wrapper is to ensure that parsers can only read
 * elements and attributes by 'consuming' them, which removes the given value.
 * This allows for a natural hierarchy among parsers -- more specific parsers
 * will run first, and if they consume a value, less-specific parsers will not
 * see it.
 */
public class XMLElement {
  /**
   * Callback interface used by {@link #consumeInnerHtml(Interpreter)} and
   * {@link #consumeChildElements(Interpreter)}.
   */
  public interface Interpreter<T> {
    /**
     * Given an XMLElement, return its filtered value.
     * 
     * @throws UnableToCompleteException on error
     */
    T interpretElement(XMLElement elem) throws UnableToCompleteException;
  }

  /**
   * Extends {@link Interpreter} with a method to be called after all elements
   * have been processed.
   */
  public interface PostProcessingInterpreter<T> extends Interpreter<T> {
    String postProcess(String consumedText) throws UnableToCompleteException;
  }

  private static class NoBrainInterpeter<T> implements Interpreter<T> {
    private final T rtn;

    public NoBrainInterpeter(T rtn) {
      this.rtn = rtn;
    }

    public T interpretElement(XMLElement elem) {
      return rtn;
    }
  }

  /**
   * Represents the source location where the XMLElement was declared.
   */
  public static class Location {
    private final String systemId;
    private final int lineNumber;

    public Location(String systemId, int lineNumber) {
      this.systemId = systemId;
      this.lineNumber = lineNumber;
    }

    public int getLineNumber() {
      return lineNumber;
    }

    public String getSystemId() {
      return systemId;
    }

    /**
     * For debugging use only.
     */
    @Override
    public String toString() {
      return systemId + ":" + lineNumber;
    }
  }

  static final String LOCATION_KEY = "gwtLocation";

  private static final Set<String> NO_END_TAG = new HashSet<String>();

  private static final String[] EMPTY = new String[]{};

  private static void clearChildren(Element elem) {
    // TODO(rjrjr) I'm nearly positive that anywhere this is called
    // we should instead be calling assertNoBody
    Node child;
    while ((child = elem.getFirstChild()) != null) {
      elem.removeChild(child);
    }
  }

  private final Element elem;
  private final AttributeParsers attributeParsers;
  // for legacy templates
  @SuppressWarnings("deprecation")
  private final com.google.gwt.uibinder.attributeparsers.BundleAttributeParsers bundleParsers;
  private final TypeOracle oracle;

  private final MortalLogger logger;
  private final String debugString;

  private final DesignTimeUtils designTime;

  private final XMLElementProvider provider;

  private JType booleanType;
  private JType imageResourceType;
  private JType doubleType;
  private JType intType;
  private JType stringType;

  {
    // from com/google/gxp/compiler/schema/html.xml
    NO_END_TAG.add("area");
    NO_END_TAG.add("base");
    NO_END_TAG.add("basefont");
    NO_END_TAG.add("br");
    NO_END_TAG.add("col");
    NO_END_TAG.add("frame");
    NO_END_TAG.add("hr");
    NO_END_TAG.add("img");
    NO_END_TAG.add("input");
    NO_END_TAG.add("isindex");
    NO_END_TAG.add("link");
    NO_END_TAG.add("meta");
    NO_END_TAG.add("param");
    NO_END_TAG.add("wbr");
  }

  // bundleParsers for legacy templates
  @SuppressWarnings("deprecation")
  XMLElement(
      Element elem,
      AttributeParsers attributeParsers,
      com.google.gwt.uibinder.attributeparsers.BundleAttributeParsers bundleParsers,
      TypeOracle oracle, MortalLogger logger, DesignTimeUtils designTime,
      XMLElementProvider provider) {
    this.elem = elem;
    this.attributeParsers = attributeParsers;
    this.bundleParsers = bundleParsers;
    this.oracle = oracle;
    this.logger = logger;
    this.designTime = designTime;
    this.provider = provider;

    this.debugString = getOpeningTag();
  }

  /**
   * Ensure that the receiver has no attributes left.
   * 
   * @throws UnableToCompleteException if it does
   */
  public void assertNoAttributes() throws UnableToCompleteException {
    int numAtts = getAttributeCount();
    if (numAtts == 0) {
      return;
    }

    StringBuilder b = new StringBuilder();
    for (int i = 0; i < numAtts; i++) {
      if (i > 0) {
        b.append(", ");
      }
      b.append('"').append(getAttribute(i).getName()).append('"');
    }
    logger.die(this, "Unexpected attributes: %s", b);
  }

  /**
   * Require that the receiver's body is empty of text and has no child nodes.
   * 
   * @throws UnableToCompleteException if it isn't
   */
  public void assertNoBody() throws UnableToCompleteException {
    consumeChildElements(new Interpreter<Boolean>() {
      public Boolean interpretElement(XMLElement elem)
          throws UnableToCompleteException {
        logger.die(elem, "Found unexpected child element");
        return false; // unreachable
      }
    });
    assertNoText();
  }

  /**
   * Require that the receiver's body is empty of text.
   * 
   * @throws UnableToCompleteException if it isn't
   */
  public void assertNoText() throws UnableToCompleteException {
    NoBrainInterpeter<String> nullInterpreter = new NoBrainInterpeter<String>(
        null);
    String s = consumeInnerTextEscapedAsHtmlStringLiteral(nullInterpreter);
    if (!"".equals(s)) {
      logger.die(this, "Unexpected text in element: \"%s\"", s);
    }
  }

  /**
   * Consumes the given attribute as a literal or field reference. The type
   * parameter is required to determine how the value is parsed and validated.
   * 
   * @param name the attribute's full name (including prefix)
   * @param type the type this attribute is expected to provide
   * @return the attribute's value as a Java expression, or null if it is not
   *         set
   * @throws UnableToCompleteException on parse failure
   */
  public String consumeAttribute(String name, JType type)
      throws UnableToCompleteException {
    return consumeAttributeWithDefault(name, null, type);
  }

  /**
   * Consumes the given attribute as a literal or field reference. The type
   * parameter is required to determine how the value is parsed and validated.
   * 
   * @param name the attribute's full name (including prefix)
   * @param defaultValue the value to @return if the attribute was unset
   * @param type the type this attribute is expected to provide
   * @return the attribute's value as a Java expression, or the given default if
   *         it was unset
   * @throws UnableToCompleteException on parse failure
   */
  public String consumeAttributeWithDefault(String name, String defaultValue,
      JType type) throws UnableToCompleteException {
    return consumeAttributeWithDefault(name, defaultValue, new JType[]{type});
  }

  /**
   * Like {@link #consumeAttributeWithDefault(String, String, JType)}, but
   * accommodates more complex type signatures.
   */
  public String consumeAttributeWithDefault(String name, String defaultValue,
      JType[] types) throws UnableToCompleteException {
    /*
     * TODO(rjrjr) The only reason we need the attribute here is for getParser,
     * and getParser only needs it for horrible old BundleAttributeParsers. When
     * that dies, this gets much simpler.
     */
    XMLAttribute attribute = getAttribute(name);
    if (attribute == null) {
      if (defaultValue != null) {
        designTime.putAttribute(this, name + ".default", defaultValue);
      }
      return defaultValue;
    }
    String rawValue = attribute.consumeRawValue();
    AttributeParser parser = getParser(attribute, types);
    if (parser == null) {
      logger.die(this, "No such attribute %s", name);
    }

    try {
      String value = parser.parse(rawValue);
      designTime.putAttribute(this, name, value);
      return value;
    } catch (UnableToCompleteException e) {
      logger.die(this, "Cannot parse attribute %s", name);
      throw e;
    }
  }

  /**
   * Convenience method for parsing the named attribute as a boolean value or
   * reference.
   * 
   * @return an expression that will evaluate to a boolean value in the
   *         generated code, or null if there is no such attribute
   * 
   * @throws UnableToCompleteException on unparseable value
   */
  public String consumeBooleanAttribute(String name)
      throws UnableToCompleteException {
    return consumeAttribute(name, getBooleanType());
  }

  /**
   * Convenience method for parsing the named attribute as a boolean value or
   * reference.
   * 
   * @param defaultValue value to return if attribute was not set
   * @return an expression that will evaluate to a boolean value in the
   *         generated code, or defaultValue if there is no such attribute
   * 
   * @throws UnableToCompleteException on unparseable value
   */
  public String consumeBooleanAttribute(String name, boolean defaultValue)
      throws UnableToCompleteException {
    return consumeAttributeWithDefault(name, Boolean.toString(defaultValue),
        getBooleanType());
  }

  /**
   * Consumes the named attribute as a boolean expression. This will not accept
   * {field.reference} expressions. Useful for values that must be resolved at
   * compile time, such as generated annotation values.
   * 
   * @return {@link Boolean#TRUE}, {@link Boolean#FALSE}, or null if no such
   *         attribute
   * 
   * @throws UnableToCompleteException on unparseable value
   */
  public Boolean consumeBooleanConstantAttribute(String name)
      throws UnableToCompleteException {
    String value = consumeRawAttribute(name);
    if (value == null) {
      return null;
    }
    if (value.equals("true") || value.equals("false")) {
      return Boolean.valueOf(value);
    }
    logger.die(this, "%s must be \"true\" or \"false\"", name);
    return null; // unreachable
  }

  /**
   * Consumes and returns all child elements.
   * 
   * @throws UnableToCompleteException if extra text nodes are found
   */
  public Iterable<XMLElement> consumeChildElements()
      throws UnableToCompleteException {
    Iterable<XMLElement> rtn = consumeChildElementsNoEmptyCheck();
    assertNoText();
    return rtn;
  }

  /**
   * Consumes and returns all child elements selected by the interpreter. Note
   * that text nodes are not elements, and so are not presented for
   * interpretation, and are not consumed.
   * 
   * @param interpreter Should return true for any child that should be consumed
   *          and returned by the consumeChildElements call
   * @throws UnableToCompleteException
   */
  public Collection<XMLElement> consumeChildElements(
      Interpreter<Boolean> interpreter) throws UnableToCompleteException {
    List<XMLElement> elements = new ArrayList<XMLElement>();
    List<Node> doomed = new ArrayList<Node>();

    NodeList childNodes = elem.getChildNodes();
    for (int i = 0; i < childNodes.getLength(); ++i) {
      Node childNode = childNodes.item(i);
      if (childNode.getNodeType() == Node.ELEMENT_NODE) {
        XMLElement childElement = provider.get((Element) childNode);
        if (interpreter.interpretElement(childElement)) {
          elements.add(childElement);
          doomed.add(childNode);
        }
      }
    }

    for (Node n : doomed) {
      elem.removeChild(n);
    }
    return elements;
  }

  /**
   * Convenience method for parsing the named attribute as an ImageResource
   * value or reference.
   * 
   * @return an expression that will evaluate to an ImageResource value in the
   *         generated code, or null if there is no such attribute
   * @throws UnableToCompleteException on unparseable value
   */
  public String consumeImageResourceAttribute(String name)
      throws UnableToCompleteException {
    return consumeAttribute(name, getImageResourceType());
  }

  /**
   * Consumes all child elements, and returns an HTML interpretation of them.
   * Trailing and leading whitespace is trimmed.
   * <p>
   * Each element encountered will be passed to the given Interpreter for
   * possible replacement. Escaping is performed to allow the returned text to
   * serve as a Java string literal used as input to a setInnerHTML call.
   * <p>
   * This call requires an interpreter to make sense of any special children.
   * The odds are you want to use
   * {@link com.google.gwt.uibinder.elementparsers.templates.parsers.HtmlInterpreter}
   * for an HTML value, or
   * {@link com.google.gwt.uibinder.elementparsers.templates.parsers.TextInterpreter}
   * for text.
   * 
   * @param interpreter Called for each element, expected to return a string
   *          replacement for it, or null if it should be left as is
   */
  public String consumeInnerHtml(Interpreter<String> interpreter)
      throws UnableToCompleteException {
    if (interpreter == null) {
      throw new NullPointerException("interpreter must not be null");
    }
    StringBuffer buf = new StringBuffer();
    GetInnerHtmlVisitor.getEscapedInnerHtml(elem, buf, interpreter, provider);

    clearChildren(elem);
    return buf.toString().trim();
  }

  /**
   * Refines {@link #consumeInnerHtml(Interpreter)} to handle
   * PostProcessingInterpreter.
   */
  public String consumeInnerHtml(PostProcessingInterpreter<String> interpreter)
      throws UnableToCompleteException {
    String html = consumeInnerHtml((Interpreter<String>) interpreter);
    return interpreter.postProcess(html);
  }

  /**
   * Refines {@link #consumeInnerTextEscapedAsHtmlStringLiteral(Interpreter)} to
   * handle PostProcessingInterpreter.
   */
  public String consumeInnerText(PostProcessingInterpreter<String> interpreter)
      throws UnableToCompleteException {
    String text = consumeInnerTextEscapedAsHtmlStringLiteral(interpreter);
    return interpreter.postProcess(text);
  }

  /**
   * Consumes all child text nodes, and asserts that this element held only
   * text. Trailing and leading whitespace is trimmed, and escaped for use as a
   * string literal. Notice that HTML entities in the text are also escaped--is
   * this a source of errors?
   * <p>
   * This call requires an interpreter to make sense of any special children.
   * The odds are you want to use
   * {@link com.google.gwt.uibinder.elementparsers.templates.parsers.TextInterpreter}
   * 
   * @throws UnableToCompleteException If any elements present are not consumed
   *           by the interpreter
   */
  public String consumeInnerTextEscapedAsHtmlStringLiteral(
      Interpreter<String> interpreter) throws UnableToCompleteException {
    if (interpreter == null) {
      throw new NullPointerException("interpreter must not be null");
    }
    StringBuffer buf = new StringBuffer();

    GetEscapedInnerTextVisitor.getEscapedInnerText(elem, buf, interpreter,
        provider);

    // Make sure there are no children left but empty husks
    for (XMLElement child : consumeChildElementsNoEmptyCheck()) {
      if (child.hasChildNodes() || child.getAttributeCount() > 0) {
        logger.die(this, "Illegal child %s in a text-only context. "
                   + "Perhaps you are trying to use unescaped HTML "
                   + "where text is required, as in a HasText widget?", child);
      }
    }

    clearChildren(elem);
    return buf.toString().trim();
  }

  /**
   * Convenience method for parsing the named attribute as a CSS length value.
   * 
   * @return a (double, Unit) pair literal, an expression that will evaluate to
   *         such a pair in the generated code, or null if there is no such
   *         attribute
   * 
   * @throws UnableToCompleteException on unparseable value
   */
  public String consumeLengthAttribute(String name)
      throws UnableToCompleteException {
    return consumeAttributeWithDefault(name, null, new JType[]{
        getDoubleType(), getUnitType()});
  }

  /**
   * Consumes all attributes, and returns a string representing the entire
   * opening tag. E.g., "<div able='baker'>"
   */
  public String consumeOpeningTag() {
    String rtn = getOpeningTag();

    for (int i = getAttributeCount() - 1; i >= 0; i--) {
      getAttribute(i).consumeRawValue();
    }
    return rtn;
  }

  /**
   * Consumes the named attribute and parses it to an unparsed, unescaped array
   * of Strings. The strings in the attribute may be comma or space separated
   * (or a mix of both).
   * 
   * @return array of String, empty if the attribute was not set.
   */
  public String[] consumeRawArrayAttribute(String name) {
    String raw = consumeRawAttribute(name, null);
    if (raw == null) {
      return EMPTY;
    }

    return raw.split("[,\\s]+");
  }

  /**
   * Consumes the given attribute and returns its trimmed value, or null if it
   * was unset. The returned string is not escaped.
   * 
   * @param name the attribute's full name (including prefix)
   * @return the attribute's value, or ""
   */
  public String consumeRawAttribute(String name) {
    if (!elem.hasAttribute(name)) {
      return null;
    }
    String value = elem.getAttribute(name);
    elem.removeAttribute(name);
    return value.trim();
  }

  /**
   * Consumes the given attribute and returns its trimmed value, or the given
   * default value if it was unset. The returned string is not escaped.
   * 
   * @param name the attribute's full name (including prefix)
   * @param defaultValue the value to return if the attribute was unset
   * @return the attribute's value, or defaultValue
   */
  public String consumeRawAttribute(String name, String defaultValue) {
    String value = consumeRawAttribute(name);
    if (value == null) {
      return defaultValue;
    }
    return value;
  }

  /**
   * Consumes the given required attribute as a literal or field reference. The
   * types parameters are required to determine how the value is parsed and
   * validated.
   * 
   * @param name the attribute's full name (including prefix)
   * @param types the type(s) this attribute is expected to provide
   * @return the attribute's value as a Java expression
   * @throws UnableToCompleteException on parse failure, or if the attribute is
   *           empty or unspecified
   */
  public String consumeRequiredAttribute(String name, JType... types)
      throws UnableToCompleteException {
    /*
     * TODO(rjrjr) We have to get the attribute to get the parser, and we must
     * get the attribute before we consume the value. This nasty subtlety is all
     * down to BundleParsers, which we'll hopefully kill off soon.
     */
    XMLAttribute attribute = getAttribute(name);
    if (attribute == null) {
      failRequired(name);
    }
    AttributeParser parser = getParser(attribute, types);
    String rawValue = consumeRequiredRawAttribute(name);

    try {
      String value = parser.parse(rawValue);
      designTime.putAttribute(this, name, value);
      return value;
    } catch (UnableToCompleteException e) {
      logger.die(this, "Cannot parse attribute \"%s\"", name);
      throw e;
    }
  }

  /**
   * Convenience method for parsing the named required attribute as a double
   * value or reference.
   * 
   * @return a double literal, an expression that will evaluate to a double
   *         value in the generated code
   * 
   * @throws UnableToCompleteException on unparseable value, or if the attribute
   *           is empty or unspecified
   */
  public String consumeRequiredDoubleAttribute(String name)
      throws UnableToCompleteException {
    return consumeRequiredAttribute(name, getDoubleType());
  }

  /**
   * Convenience method for parsing the named required attribute as a integer
   * value or reference.
   * 
   * @return a integer literal, an expression that will evaluate to a integer
   *         value in the generated code
   * 
   * @throws UnableToCompleteException on unparseable value, or if the attribute
   *           is empty or unspecified
   */
  public String consumeRequiredIntAttribute(String name)
      throws UnableToCompleteException {
    return consumeRequiredAttribute(name, getIntType());
  }

  /**
   * Consumes the named attribute, or dies if it is missing.
   */
  public String consumeRequiredRawAttribute(String name)
      throws UnableToCompleteException {
    String value = consumeRawAttribute(name);
    if (value == null) {
      failRequired(name);
    }
    return value;
  }

  /**
   * Consumes a single child element, ignoring any text nodes and throwing an
   * exception if no child is found, or more than one child element is found.
   * 
   * @throws UnableToCompleteException on no children, or too many
   */
  public XMLElement consumeSingleChildElement()
      throws UnableToCompleteException {
    XMLElement ret = null;
    for (XMLElement child : consumeChildElements()) {
      if (ret != null) {
        logger.die(this,
            "Element may only contain a single child element, but "
                + "found %s and %s.", ret, child);
      }

      ret = child;
    }

    if (ret == null) {
      logger.die(this, "Element must have a single child element");
    }

    return ret;
  }

  /**
   * Consumes the named attribute and parses it to an array of String
   * expressions. The strings in the attribute may be comma or space separated
   * (or a mix of both).
   * 
   * @return array of String expressions, empty if the attribute was not set.
   * @throws UnableToCompleteException on unparseable value
   */
  public String[] consumeStringArrayAttribute(String name)
      throws UnableToCompleteException {
    AttributeParser parser = attributeParsers.get(getStringType());

    String[] strings = consumeRawArrayAttribute(name);
    for (int i = 0; i < strings.length; i++) {
      try {
        strings[i] = parser.parse(strings[i]);
      } catch (UnableToCompleteException e) {
        logger.die(this, "Cannot parse attribute " + name);
        throw e;
      }
    }
    designTime.putAttribute(this, name, strings);
    return strings;
  }

  /**
   * Convenience method for parsing the named attribute as a String value or
   * reference.
   * 
   * @return an expression that will evaluate to a String value in the generated
   *         code, or null if there is no such attribute
   * @throws UnableToCompleteException on unparseable value
   */
  public String consumeStringAttribute(String name)
      throws UnableToCompleteException {
    return consumeAttribute(name, getStringType());
  }

  /**
   * Convenience method for parsing the named attribute as a String value or
   * reference.
   * 
   * @return an expression that will evaluate to a String value in the generated
   *         code, or the given defaultValue if there is no such attribute
   * @throws UnableToCompleteException on unparseable value
   */
  public String consumeStringAttribute(String name, String defaultValue)
      throws UnableToCompleteException {
    return consumeAttributeWithDefault(name, defaultValue, getStringType());
  }

  /**
   * Returns the unprocessed, unescaped, raw inner text of the receiver. Dies if
   * the receiver has non-text children.
   * <p>
   * You probably want to use
   * {@link #consumeInnerTextEscapedAsHtmlStringLiteral} instead.
   * 
   * @return the text
   * @throws UnableToCompleteException if it held anything other than text nodes
   */
  public String consumeUnescapedInnerText() throws UnableToCompleteException {
    final NodeList children = elem.getChildNodes();
    if (children.getLength() < 1) {
      return "";
    }
    if (children.getLength() > 1
        || Node.TEXT_NODE != children.item(0).getNodeType()) {
      logger.die(this, "Element must contain only text");
    }
    Text t = (Text) children.item(0);
    return t.getTextContent();
  }

  /**
   * Get the attribute at the given index. If you are consuming attributes,
   * remember to traverse them in reverse.
   */
  public XMLAttribute getAttribute(int i) {
    return new XMLAttribute(XMLElement.this,
        (Attr) elem.getAttributes().item(i));
  }

  /**
   * Get the attribute with the given name.
   * 
   * @return the attribute, or null if there is none of that name
   */
  public XMLAttribute getAttribute(String name) {
    Attr attr = elem.getAttributeNode(name);
    if (attr == null) {
      return null;
    }
    return new XMLAttribute(this, attr);
  }

  /**
   * @return The number of attributes this element has
   */
  public int getAttributeCount() {
    return elem.getAttributes().getLength();
  }

  public String getClosingTag() {
    if (NO_END_TAG.contains(elem.getTagName())) {
      return "";
    }
    return String.format("</%s>", elem.getTagName());
  }

  /**
   * @return the design time path of this element, in form of indexes from root,
   *         such as "0/0/1/0".
   */
  public String getDesignTimePath() {
    return designTime.getPath(elem);
  }

  /**
   * Gets this element's local name (sans namespace prefix).
   */
  public String getLocalName() {
    return elem.getLocalName();
  }

  public Location getLocation() {
    return (Location) elem.getUserData(LOCATION_KEY);
  }

  /**
   * Gets this element's namespace URI.
   */
  public String getNamespaceUri() {
    return elem.getNamespaceURI();
  }

  public String getNamespaceUriForAttribute(String fieldName) {
    Attr attr = elem.getAttributeNode(fieldName);
    return attr.getNamespaceURI();
  }

  /**
   * @return the parent element, or null if parent is null or a node type other
   *         than Element
   */
  public XMLElement getParent() {
    Node parent = elem.getParentNode();
    if (parent == null || Node.ELEMENT_NODE != parent.getNodeType()) {
      return null;
    }
    return provider.get((Element) parent);
  }

  public String getPrefix() {
    return elem.getPrefix();
  }

  /**
   * Determines whether the element has a given attribute.
   */
  public boolean hasAttribute(String name) {
    return elem.hasAttribute(name);
  }

  public boolean hasChildNodes() {
    return elem.hasChildNodes();
  }

  public String lookupPrefix(String prefix) {
    return elem.lookupPrefix(prefix);
  }

  public void setAttribute(String name, String value) {
    elem.setAttribute(name, value);
  }

  @Override
  public String toString() {
    return debugString;
  }

  private Iterable<XMLElement> consumeChildElementsNoEmptyCheck() {
    try {
      Iterable<XMLElement> rtn = consumeChildElements(new NoBrainInterpeter<Boolean>(
          true));
      return rtn;
    } catch (UnableToCompleteException e) {
      throw new RuntimeException("Impossible exception", e);
    }
  }

  private void failRequired(String name) throws UnableToCompleteException {
    logger.die(this, "Missing required attribute \"%s\"", name);
  }

  private JType getBooleanType() {
    if (booleanType == null) {
      try {
        booleanType = oracle.parse("boolean");
      } catch (TypeOracleException e) {
        throw new RuntimeException(e);
      }
    }
    return booleanType;
  }

  private JType getDoubleType() {
    if (doubleType == null) {
      try {
        doubleType = oracle.parse("double");
      } catch (TypeOracleException e) {
        throw new RuntimeException(e);
      }
    }
    return doubleType;
  }

  private JType getImageResourceType() {
    if (imageResourceType == null) {
      imageResourceType = oracle.findType(ImageResource.class.getCanonicalName());
    }
    return imageResourceType;
  }

  private JType getIntType() {
    if (intType == null) {
      try {
        intType = oracle.parse("int");
      } catch (TypeOracleException e) {
        throw new RuntimeException(e);
      }
    }
    return intType;
  }

  private String getOpeningTag() {
    StringBuilder b = new StringBuilder().append("<").append(elem.getTagName());

    NamedNodeMap attrs = elem.getAttributes();
    for (int i = 0; i < attrs.getLength(); i++) {
      Attr attr = (Attr) attrs.item(i);
      b.append(String.format(" %s='%s'", attr.getName(),
          UiBinderWriter.escapeAttributeText(attr.getValue())));
    }
    b.append(">");
    return b.toString();
  }

  @SuppressWarnings("deprecation")
  private AttributeParser getParser(XMLAttribute xmlAttribute, JType... types)
      throws UnableToCompleteException {
    AttributeParser rtn = bundleParsers.get(xmlAttribute);
    if (rtn == null) {
      rtn = attributeParsers.get(types);
    }

    return rtn;
  }

  private JType getStringType() {
    if (stringType == null) {
      stringType = oracle.findType(String.class.getCanonicalName());
    }
    return stringType;
  }

  private JClassType getUnitType() {
    return oracle.findType(Unit.class.getCanonicalName()).isEnum();
  }
}
