/*******************************************************************************
 * Copyright (c) 2001, 2004 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.wst.xsd.ui.internal.util;

import org.eclipse.wst.sse.core.internal.format.IStructuredFormatProcessor;
import org.eclipse.wst.xml.core.document.IDOMModel;
import org.eclipse.wst.xml.core.document.IDOMNode;
import org.eclipse.wst.xml.core.internal.provisional.format.FormatProcessorXML;
import org.eclipse.xsd.util.XSDConstants;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;

public class XSDDOMHelper
{
  public static final int LENGTH_FACET        =  1;
  public static final int MIN_LENGTH_FACET    =  2;
  public static final int MAX_LENGTH_FACET    =  3;
  public static final int PATTERN_FACET       =  4;
  public static final int ENUM_FACET          =  5;
  public static final int WHITE_SPACE_FACET   =  6;

  public static final int MAX_INCLUSIVE_FACET =  7;
  public static final int MAX_EXCLUSIVE_FACET =  8;
  public static final int MIN_INCLUSIVE_FACET =  9;
  public static final int MIN_EXCLUSIVE_FACET =  10;

  public static final int TOTAL_DIGITS_FACET     = 11;
  public static final int FRACTION_DIGITS_FACET  = 12;

  public static final int N_FACETS            = 13;

  public static String[][] dataType =
  {
    //
    // Table format:
    // Type
    //  Length, MinLength, MaxLength, Pattern, Enumeration,whiteSpace
    //  MaxInclusive, MaxExclusive, MinInclusive, MinExclusive, TotalDigits, FractionDigits
    //

    // 0
    { "anySimpleType",
        "Y", "Y", "Y", "Y", "Y", "Y",
        "Y", "Y", "Y", "Y", "Y", "Y",
    },

    // 1
    { "anyType",
        "Y", "Y", "Y", "Y", "Y", "Y",
        "Y", "Y", "Y", "Y", "Y", "Y",
    },


    // 2
    { "anyURI",
        "Y", "Y", "Y", "Y", "Y", "Y",
        "N", "N", "N", "N", "N", "N",
    },

    // 3
    { "base64Binary",
        "Y", "Y", "Y", "Y", "Y", "Y",
        "N", "N", "N", "N", "N", "N",
    },

    // 4
    { "boolean",
        "N", "N", "N", "Y", "N", "Y",
        "N", "N", "N", "N", "N", "N",
    },

    // 5
    { "byte",
        "N", "N", "N", "Y", "Y", "Y",
        "Y", "Y", "Y", "Y", "Y", "Y",
    },

    // 6
    { "date",
        "N", "N", "N", "Y", "Y", "Y",
        "Y", "Y", "Y", "Y", "N", "N",
    },

    // 7
    { "dateTime",
        "N", "N", "N", "Y", "Y", "Y",
        "Y", "Y", "Y", "Y", "N", "N",
    },

    // 8
    { "decimal",
        "N", "N", "N", "Y", "Y", "Y",
        "Y", "Y", "Y", "Y", "Y", "Y",
    },


    // 9
    { "double",
        "N", "N", "N", "Y", "Y", "Y",
        "Y", "Y", "Y", "Y", "N", "N",
    },

    // 10
    { "duration",
        "N", "N", "N", "Y", "Y", "Y",
        "Y", "Y", "Y", "Y", "N", "N",
    },

    // 11
    { "ENTITY",
        "Y", "Y", "Y", "Y", "Y", "Y",
        "N", "N", "N", "N", "N", "N",
    },

    // 12
    { "ENTITIES",
        "Y", "Y", "Y", "N", "Y", "Y",
        "N", "N", "N", "N", "N", "N",
    },

    // 13
    { "float",
        "N", "N", "N", "Y", "Y", "Y",
        "Y", "Y", "Y", "Y", "N", "N",
    },

    // 14
    { "gDay",
        "N", "N", "N", "Y", "Y", "Y",
        "Y", "Y", "Y", "Y", "N", "N",
    },

    // 15
    { "gMonth",
        "N", "N", "N", "Y", "Y", "Y",
        "Y", "Y", "Y", "Y", "N", "N",
    },

    // 16
    { "gMonthDay",
        "N", "N", "N", "Y", "Y", "Y",
        "Y", "Y", "Y", "Y", "N", "N",
    },

    // 17
    { "gYear",
        "N", "N", "N", "Y", "Y", "Y",
        "Y", "Y", "Y", "Y", "N", "N",
    },

    // 18
    { "gYearMonth",
        "N", "N", "N", "Y", "Y", "Y",
        "Y", "Y", "Y", "Y", "N", "N",
    },

    // 19
    { "hexBinary",
        "Y", "Y", "Y", "Y", "Y", "Y",
        "N", "N", "N", "N", "N", "N",
    },

    // 20
    { "ID",
        "Y", "Y", "Y", "Y", "Y", "Y",
        "N", "N", "N", "N", "N", "N",
    },

    // 21
    { "IDREF",
        "Y", "Y", "Y", "Y", "Y", "Y",
        "N", "N", "N", "N", "N", "N",
    },

    // 22
    { "IDREFS",
        "Y", "Y", "Y", "N", "Y", "Y",
        "N", "N", "N", "N", "N", "N",
    },

    // 23
    { "int",
        "N", "N", "N", "Y", "Y", "Y",
        "Y", "Y", "Y", "Y", "Y", "Y",
    },

    // 24
    { "integer",
        "N", "N", "N", "Y", "Y", "Y",
        "Y", "Y", "Y", "Y", "Y", "Y",
    },

    // 25
    { "language",
        "Y", "Y", "Y", "Y", "Y", "Y",
        "N", "N", "N", "N", "N", "N",
    },

    // 26
    { "long",
        "N", "N", "N", "Y", "Y", "Y",
        "Y", "Y", "Y", "Y", "Y", "Y",
    },

    // 27
    { "Name",
        "Y", "Y", "Y", "Y", "Y", "Y",
        "N", "N", "N", "N", "N", "N",
    },


    // 28
    { "NCName",
        "Y", "Y", "Y", "Y", "Y", "Y",
        "N", "N", "N", "N", "N", "N",
    },

    // 29
    { "negativeInteger",
        "N", "N", "N", "Y", "Y", "Y",
        "Y", "Y", "Y", "Y", "Y", "Y",
    },

    // 30
    { "NMTOKEN",
        "Y", "Y", "Y", "Y", "Y", "Y",
        "N", "N", "N", "N", "N", "N",
    },

    // 31
    { "NMTOKENS",
        "Y", "Y", "Y", "N", "Y", "Y",
        "N", "N", "N", "N", "N", "N",
    },

    // 32
    { "nonNegativeInteger",
        "N", "N", "N", "Y", "Y", "Y",
        "Y", "Y", "Y", "Y", "Y", "Y",
    },

    // 33
    { "nonPositiveInteger",
        "N", "N", "N", "Y", "Y", "Y",
        "Y", "Y", "Y", "Y", "Y", "Y",
    },

    // 34
    { "normalizedString",
        "Y", "Y", "Y", "Y", "Y", "Y",
        "N", "N", "N", "N", "N", "N",

    },

    // 35
    { "NOTATION",
        "Y", "Y", "Y", "Y", "Y", "Y",
        "N", "N", "N", "N", "N", "N",

    },

    // 36
    { "positiveInteger",
        "N", "N", "N", "Y", "Y", "Y",
        "Y", "Y", "Y", "Y", "Y", "Y",
    },

    // 37
    { "QName",
        "N", "N", "N", "Y", "Y", "Y",
        "N", "N", "N", "N", "N", "N",
    },

    // 38
    { "short",
        "N", "N", "N", "Y", "Y", "Y",
        "Y", "Y", "Y", "Y", "Y", "Y",
    },

    // 39
    { "string",
        "Y", "Y", "Y", "Y", "Y", "Y",
        "N", "N", "N", "N", "N", "N",
    },

    // 40
    { "time",
        "N", "N", "N", "Y", "Y", "Y",
        "Y", "Y", "Y", "Y", "N", "N",
    },

    // 41
    { "token",
        "Y", "Y", "Y", "Y", "Y", "Y",
        "N", "N", "N", "N", "N", "N",
    },

    // 42
    { "unsignedByte",
        "N", "N", "N", "Y", "Y", "Y",
        "Y", "Y", "Y", "Y", "Y", "Y",
    },

    // 43
    { "unsignedInt",
        "N", "N", "N", "Y", "Y", "Y",
        "Y", "Y", "Y", "Y", "Y", "Y",
    },

    // 44
    { "unsignedLong",
        "N", "N", "N", "Y", "Y", "Y",
        "Y", "Y", "Y", "Y", "Y", "Y",
    },

    // 45
    { "unsignedShort",
        "N", "N", "N", "Y", "Y", "Y",
        "Y", "Y", "Y", "Y", "Y", "Y",
    },

  };

  public static String XMLSchemaURI = "http://www.w3.org/2001/XMLSchema";

  /**
   * Constructor for XSDDOMHelper.
   */
  public XSDDOMHelper()
  {
    super();
  }

  public Node getChildNode(Element parent, String childName)
  {
/*    NodeList nodeList = parent.getElementsByTagNameNS(XMLSchemaURI, childName);
    if (nodeList.getLength() > 0)
      return nodeList.item(0);
    return null;
*/
    NodeList list = null;
    if (parent != null)
    {
      list = parent.getChildNodes();
    }
   
    String name = null;
    if (list != null)
    {
      // Performance issue perhaps?
      for (int i = 0; i < list.getLength(); i++)
      {
        if (list.item(i) instanceof Element)
        {
          if (list.item(i).getLocalName().equals(childName))
          {
            return list.item(i);
          }
        }
      }
    }
    return null;
  }

  public static String SIMPLE_TYPE = "Simple";
  public static String USER_SIMPLE_TYPE = "simpleType";
  public static String USER_COMPLEX_TYPE = "complexType";
/*
  public void setElementType(Element element, String type)
  {
    Document doc = element.getOwnerDocument();
    if (type.equals(SIMPLE_TYPE))
    {
      removeChild(element, USER_SIMPLE_TYPE);
      removeChild(element, USER_COMPLEX_TYPE);
      element.setAttribute("type","xsd:string");
      return;
    }
    else if (type.equals(USER_SIMPLE_TYPE))
    {
      removeChild(element, USER_COMPLEX_TYPE);
    }
    else
    {
      removeChild(element, USER_SIMPLE_TYPE);
    }
    element.removeAttribute("type");
    element.appendChild(doc.createElement("xsd:"+type));
  }

  public String getElementType(Element element)
  {
    String tagName = element.getLocalName();

    if (tagName.equals(XSDConstants.ELEMENT_ELEMENT_TAG) ||
        tagName.equals(XSDConstants.ATTRIBUTE_ELEMENT_TAG))
    {
      if (element.hasAttribute("type"))
      {
        return SIMPLE_TYPE;
      }
      NodeList nodes = element.getElementsByTagNameNS(XMLSchemaURI, USER_SIMPLE_TYPE);
      if (nodes.getLength() > 0)
      {
        return USER_SIMPLE_TYPE;
      }
      nodes = element.getElementsByTagNameNS(XMLSchemaURI, USER_COMPLEX_TYPE);
      if (nodes.getLength() > 0)
      {
        return USER_COMPLEX_TYPE;
      }
    }
    return "";
  }
*/
  public void removeDerivedByElement(Element element)
  {
    removeChild(element, XSDConstants.RESTRICTION_ELEMENT_TAG);
    removeChild(element, XSDConstants.EXTENSION_ELEMENT_TAG);
  }

  public String getBaseType(Element element) // for SimpleContent and ComplexContent
  {
    Node restrictionChild = getChildNode(element, "restriction");
    Node extensionChild = getChildNode(element, "extension");
    String baseType = "";
    if (restrictionChild != null)
    {
      if (restrictionChild instanceof Element)
      {
        baseType = ((Element)restrictionChild).getAttribute("base");
//        String prefix = element.getPrefix();
//        if (prefix != null && prefix.length() > 0)
//        {
//          baseType = baseType.substring(baseType.indexOf(prefix) + prefix.length() + 1);
//        }
      }
    }
    else if (extensionChild != null) // should be one or the other
    {
      if (extensionChild instanceof Element)
      {
        baseType = ((Element)extensionChild).getAttribute("base");
//        String prefix = element.getPrefix();
//        if (prefix != null && prefix.length() > 0)
//        {
//          baseType = baseType.substring(baseType.indexOf(prefix) + prefix.length() + 1);
//        }
      }
    }
    return baseType;
  }

  public void setDerivedByBaseType(Element element, String derivedByType, String type)
  {
    Document doc = element.getOwnerDocument();

    Element derivedByElement = getDerivedByElement(element);
    if (derivedByElement != null)
    {
      derivedByElement.setAttribute("base", type);
    }
    else  // there really should be one already...base is required.
    {
      Element newElement = doc.createElement(derivedByType);
      newElement.setAttribute("base", type);
      element.appendChild(newElement);
    }
  }

  public void changeDerivedByType(Element element, String derivedByType, String type)
  {
    Document doc = element.getOwnerDocument();

    String prefix = element.getPrefix();
    prefix = prefix == null ? "" : prefix + ":";

    Element derivedByElement = getDerivedByElement(element);
    
    if (derivedByElement.getLocalName().equals(derivedByType))
    {
    	return; // it's already the derived by type
    }
    Element newNode;
  	if (derivedByType.equals("restriction"))
  	{
    	newNode = doc.createElementNS(XSDDOMHelper.XMLSchemaURI, prefix + XSDConstants.RESTRICTION_ELEMENT_TAG);
    }
    else
    {
    	newNode = doc.createElementNS(XSDDOMHelper.XMLSchemaURI, prefix + XSDConstants.EXTENSION_ELEMENT_TAG);
    }

    if (derivedByElement != null)
    {
      if (derivedByElement.hasChildNodes())
      {        
        NodeList nodes = derivedByElement.getChildNodes();
        // use clones so we don't have a refresh problem
        for (int i = 0; i < nodes.getLength(); i++)
        {
          Node node = nodes.item(i);       
          newNode.appendChild(node.cloneNode(true));
        }
      }
      newNode.setAttribute("base", type);
      element.replaceChild(newNode, derivedByElement);

    }
  }

  public void setSimpleContentType(Element element, String type)
  {
    String contentTypeName = element.getLocalName();

    if (contentTypeName.equals(XSDConstants.UNION_ELEMENT_TAG))
    {
      element.setAttribute(XSDConstants.MEMBERTYPES_ATTRIBUTE, type);
    }
    else if (contentTypeName.equals(XSDConstants.LIST_ELEMENT_TAG))
    {
      element.setAttribute(XSDConstants.ITEMTYPE_ATTRIBUTE, type);
    }
    else if (contentTypeName.equals(XSDConstants.RESTRICTION_ELEMENT_TAG))
    {
      element.setAttribute(XSDConstants.BASE_ATTRIBUTE, type);
    }
  }

  public void removeSimpleTypeContent(Element element)
  {
    String contentTypeName = element.getLocalName();
    if (contentTypeName.equals(XSDConstants.UNION_ELEMENT_TAG))
    {
      element.removeAttribute(XSDConstants.MEMBERTYPES_ATTRIBUTE);
    }
    else if (contentTypeName.equals(XSDConstants.LIST_ELEMENT_TAG))
    {
      element.removeAttribute(XSDConstants.ITEMTYPE_ATTRIBUTE);
    }
    else if (contentTypeName.equals(XSDConstants.RESTRICTION_ELEMENT_TAG))
    {
      element.removeAttribute(XSDConstants.BASE_ATTRIBUTE);
    }
  }

  public String getDerivedByName(Element element)
  {
    Node restrictionChild = getChildNode(element, "restriction");
    Node extensionChild = getChildNode(element, "extension");
    if (restrictionChild != null)
    {
      return "restriction";
    }
    if (extensionChild != null)
    {
      return "extension";
    }
    return "";
  }

  /**
   * Get the derived by node given the complexContent or simpleContent node
   */
  public Element getDerivedByElement(Element element)
  {
    Node restrictionChild = getChildNode(element, "restriction");
    Node extensionChild = getChildNode(element, "extension");
    if (restrictionChild != null)
    {
      if (restrictionChild instanceof Element)
      {
        return (Element)restrictionChild;
      }
    }
    
    if (extensionChild != null)
    {
      if (extensionChild instanceof Element)
      {
        return (Element)extensionChild;
      }
    }
    return null;
  }

  /**
   * Get the derived by node given the ComplexType node
   * Returns the first one, if say, the INVALID schema has more than one
   */
  public Element getDerivedByElementFromComplexType(Element element)
  {
    NodeList nl = element.getChildNodes();
    int childNumber = 0;
    int j = 0;
    for (j = 0; j < nl.getLength(); j++)
    {
      Node aNode = nl.item(j);
      if (inputEquals(aNode, XSDConstants.COMPLEXCONTENT_ELEMENT_TAG, false))
      {
        break; 
      }
      else if (inputEquals(aNode, XSDConstants.SIMPLECONTENT_ELEMENT_TAG, false))
      {
        break;
      }
    }
    Element derivedByNode = getDerivedByElement((Element)nl.item(j));
    return derivedByNode;
  }

  /**
   * Get the content model given the ComplexType node
   * Returns the first one, if say, the INVALID schema has more than one
   */
  public Element getContentModelFromParent(Element element)
  {
    NodeList nl = element.getChildNodes();
    int childNumber = 0;
    int j = 0;
    boolean modelExists = false;
    int length = nl.getLength();
    for (j = 0; j < length; j++)
    {
      Node aNode = nl.item(j);
      if (inputEquals(aNode, XSDConstants.COMPLEXCONTENT_ELEMENT_TAG, false))
      {
        modelExists = true;
        break; 
      }
      else if (inputEquals(aNode, XSDConstants.SIMPLECONTENT_ELEMENT_TAG, false))
      {
        modelExists = true;
        break;
      }
      else if (inputEquals(aNode, XSDConstants.SEQUENCE_ELEMENT_TAG, false))
      {
        modelExists = true;
        break;
      }
      else if (inputEquals(aNode, XSDConstants.CHOICE_ELEMENT_TAG, false))
      {
        modelExists = true;
        break;
      }
      else if (inputEquals(aNode, XSDConstants.ALL_ELEMENT_TAG, false))
      {
        modelExists = true;
        break;
      }
    }
    if (!modelExists)
    {
      return null;
    }

    Element derivedByNode = (Element)nl.item(j);
    return derivedByNode;
  }

  /**
   * 
   */
  public void changeContentModel(Element complexTypeElement, String contentModel, Element sequenceChoiceOrAllElement)
  {
    Document doc = complexTypeElement.getOwnerDocument();

    String prefix = complexTypeElement.getPrefix();
    prefix = prefix == null ? "" : prefix + ":";
    
    Element contentModelElement = getContentModelFromParent(complexTypeElement);

    if (contentModelElement.getLocalName().equals(contentModel))
    {
      return; // it's already the content model 
    }
    Element newNode;
    newNode = doc.createElementNS(XSDDOMHelper.XMLSchemaURI, prefix + contentModel);

    if (contentModelElement.hasChildNodes())
    {        
      NodeList nodes = contentModelElement.getChildNodes();
      // use clones so we don't have a refresh problem
      for (int i = 0; i < nodes.getLength(); i++)
      {
        Node node = nodes.item(i);
        if (node instanceof Element)
        {
          if (node.getLocalName().equals(XSDConstants.ANNOTATION_ELEMENT_TAG))
          {
            if (!(XSDDOMHelper.inputEquals(contentModelElement, XSDConstants.SEQUENCE_ELEMENT_TAG, false) ||
                XSDDOMHelper.inputEquals(contentModelElement, XSDConstants.CHOICE_ELEMENT_TAG, false) ||
                XSDDOMHelper.inputEquals(contentModelElement, XSDConstants.ALL_ELEMENT_TAG, false)))
            {
              newNode.appendChild(node.cloneNode(true));
            }
          }
          else if (node.getLocalName().equals(XSDConstants.RESTRICTION_ELEMENT_TAG) ||
                    node.getLocalName().equals(XSDConstants.EXTENSION_ELEMENT_TAG))
          {
            newNode.appendChild(node.cloneNode(true));
            if (sequenceChoiceOrAllElement != null)
            {
              node.appendChild(sequenceChoiceOrAllElement);
            }
          }
          else
          {
            removeNodeAndWhitespace(node);
          }
        }
        else
        {
          newNode.appendChild(node.cloneNode(true)); 
        }
      }
    }
    complexTypeElement.replaceChild(newNode, contentModelElement);
  }

  public Element cloneElement(Element parent, Element sourceNode)
  {
    Document doc = parent.getOwnerDocument();
    String prefix = parent.getPrefix();
    prefix = prefix == null ? "" : prefix + ":";
    
    Element newNode = doc.createElementNS(XSDDOMHelper.XMLSchemaURI, prefix + sourceNode.getLocalName());

    if (sourceNode.hasChildNodes())
    {        
      NodeList nodes = sourceNode.getChildNodes();
      // use clones so we don't have a refresh problem
      for (int i = 0; i < nodes.getLength(); i++)
      {
        Node node = nodes.item(i);
        newNode.appendChild(node.cloneNode(true));
      }
    }
    return newNode;
//    parent.replaceChild(newNode, sourceNode);
  }

  public boolean hasElementChildren(Element parentNode)
  {
    boolean hasChildrenElements = false;
    if (parentNode != null && parentNode.hasChildNodes())
    {
      NodeList nodes = parentNode.getChildNodes();
      for (int i = 0; i < nodes.getLength(); i++)
      {
        if (nodes.item(i) instanceof Element)
        {
          hasChildrenElements = true;
          break;
        }
      }
    }
    return hasChildrenElements;
  }

  public void removeChild(Element node, String childName)
  {
    Node child = getChildNode(node,childName);
    if (child != null)
    {
      node.removeChild(child);
    }
  }

  public static boolean isFacet(Object obj)
  {
    if (XSDDOMHelper.inputEquals(obj, XSDConstants.LENGTH_ELEMENT_TAG, false) ||
        XSDDOMHelper.inputEquals(obj, XSDConstants.MINLENGTH_ELEMENT_TAG, false) ||
        XSDDOMHelper.inputEquals(obj, XSDConstants.MAXLENGTH_ELEMENT_TAG, false) ||
        XSDDOMHelper.inputEquals(obj, XSDConstants.WHITESPACE_ELEMENT_TAG, false) ||
        XSDDOMHelper.inputEquals(obj, XSDConstants.MAXINCLUSIVE_ELEMENT_TAG, false) ||
        XSDDOMHelper.inputEquals(obj, XSDConstants.MAXEXCLUSIVE_ELEMENT_TAG, false) ||
        XSDDOMHelper.inputEquals(obj, XSDConstants.MININCLUSIVE_ELEMENT_TAG, false) ||
        XSDDOMHelper.inputEquals(obj, XSDConstants.MINEXCLUSIVE_ELEMENT_TAG, false) ||
        XSDDOMHelper.inputEquals(obj, XSDConstants.TOTALDIGITS_ELEMENT_TAG, false) ||
        XSDDOMHelper.inputEquals(obj, XSDConstants.FRACTIONDIGITS_ELEMENT_TAG, false))
    {
      return true;
    }
    return false;
  }

  public static void removeNodeAndWhitespace(Node node)
  {
    Node parentNode = node.getParentNode();
    
    Node nextElement = getNextElementNode(node);
    Node previousElement = getPreviousElementNode(node);

    Node nextSibling = node.getNextSibling();
    if (nextSibling instanceof Text)
    {
      parentNode.removeChild(nextSibling);
    }
    Node previousSibling = node.getPreviousSibling();

		parentNode.removeChild(node);

    if (nextElement != null)
    {
			formatChild(nextElement);
    }

		if (previousElement != null)
		{
			formatChild(previousElement);
		}
  }

	public static void formatChild(Node child)
	{
    if (child instanceof IDOMNode)
    {
      IDOMModel model = ((IDOMNode)child).getModel();
      try
      {
        // tell the model that we are about to make a big model change
        model.aboutToChangeModel();
        
	      IStructuredFormatProcessor formatProcessor = new FormatProcessorXML();
		    formatProcessor.formatNode(child);
      }
      finally
      {
        // tell the model that we are done with the big model change
        model.changedModel(); 
      }
    }
  }
  
  public static Node getLastElementNode(Node parent)
  {
    Node lastChild = parent.getLastChild();
    
    while (!(lastChild instanceof Element) && lastChild != null)
    {
      lastChild = lastChild.getPreviousSibling();
    }
    return lastChild;
  }

  public static Node getNextElementNode(Node node)
  {
    Node next = node.getNextSibling();
    
    while (!(next instanceof Element) && next != null)
    {
      next = next.getNextSibling();
    }
    if (next instanceof Text)
    {
    	return null;
    }
    return next;
  }

	public static Node getPreviousElementNode(Node node)
	{
		Node previous = node.getPreviousSibling();
    
		while (!(previous instanceof Element) && previous != null)
		{
			previous = previous.getPreviousSibling();
		}
    if (previous instanceof Text)
    {
      return null;
    }
    return previous;
	}

  public static void moveNode(Node referenceNode, Node nodeToMove, boolean isBefore)
  {
    // this assumes that the referenceNode and node to move have the same parent
    Node parent = referenceNode.getParentNode();

    // Get reference nodes next and previous text strings
    String referenceNodeNextString = "";
    String referenceNodePreviousString = "";
    if (referenceNode != null)
    {
      Node referenceNodeNextSibling = referenceNode.getNextSibling();
      Node referenceNodePreviousSibling = referenceNode.getPreviousSibling();
      if (referenceNodeNextSibling instanceof Text)
      {
        referenceNodeNextString = ((Text)referenceNodeNextSibling).getData();
      }
      if (referenceNodePreviousSibling instanceof Text)
      {
        referenceNodePreviousString = ((Text)referenceNodePreviousSibling).getData();
      }
    }
    // Get the dragged node's next and previous text strings
    Node nodeToMoveNextSibling = nodeToMove.getNextSibling();
    Node nodeToMovePreviousSibling = nodeToMove.getPreviousSibling();
    Node nodeToMoveNextText = null;
    String nodeToMoveNextString = "";
    String nodeToMovePreviousString = "";
    if (nodeToMoveNextSibling instanceof Text)
    {
      nodeToMoveNextText = (Text)nodeToMoveNextSibling;
      nodeToMoveNextString = ((Text)nodeToMoveNextSibling).getData();
    }
    if (nodeToMovePreviousSibling instanceof Text)
    {
      nodeToMovePreviousString = ((Text)nodeToMovePreviousSibling).getData();
    }

    // Get the last element's next and previous text strings
    Node lastElement = getLastElementNode(parent);
    Node lastElementNextSibling = lastElement.getNextSibling();
    Node lastElementPreviousSibling = lastElement.getPreviousSibling();
    String lastElementNextString = "";
    String lastElementPreviousString = "";		
    if (lastElementNextSibling instanceof Text)
    {
      lastElementNextString = ((Text)lastElementNextSibling).getData();
    }
    if (lastElementPreviousSibling instanceof Text)
    {
      lastElementPreviousString = ((Text)lastElementPreviousSibling).getData();
    }

    boolean isLastElement = false; // whether the last element is dragged/moved
    if (lastElement == nodeToMove)
    {
      isLastElement = true;
    }
		
    // defect 221056 this test is required or else the node will
    // be removed from the tree and the insert will fail
    if (referenceNode != nodeToMove)
    {
      parent.removeChild(nodeToMove);
      if (referenceNode != null)
      {
        if (!isBefore)
        {
          referenceNode = getNextElementNode(referenceNode);
//        referenceNode = referenceNode.getNextSibling();
        }
      }

      if (referenceNode != null)
      {
        insertBefore(nodeToMove, referenceNode);
      }
      else
      {
        parent.appendChild(nodeToMove);
      }

      Node newLastElement = getLastElementNode(parent);
      if (referenceNode != null)
      {
        if (referenceNode != newLastElement) 
        {
          if (!isLastElement)
          {
            setTextData(referenceNode, nodeToMoveNextString, nodeToMovePreviousString);
          }
        }
        setTextData(nodeToMove, referenceNodeNextString, referenceNodePreviousString);
      }
      // Remove the empty space left by the dragged node
      if (nodeToMoveNextText != null)
      {
    	  parent.removeChild(nodeToMoveNextText);
      }
      // special case for the last element
      if ((newLastElement == nodeToMove) || isLastElement)
      {
        setTextData(newLastElement, lastElementNextString, lastElementPreviousString);
      }
    }
  }

  public static void setTextData(Node target, String nextText, String previousText)
  {
    Node parent = target.getParentNode();
    Node nextSibling = target.getNextSibling();
    Node previousSibling = target.getPreviousSibling();
    if (nextSibling instanceof Text)
    {
      ((Text)nextSibling).setData(nextText);	
    }
    if (nextSibling == null || nextSibling instanceof Element)
    {
      Text textNode = parent.getOwnerDocument().createTextNode("");
      textNode.setData(nextText);
      if (nextSibling != null)
      {
        parent.insertBefore(textNode, nextSibling);
      }
      else
      {
        parent.insertBefore(textNode, getNextElementNode(target));
      }
    }				

    if (previousSibling instanceof Text)
    {
      ((Text)previousSibling).setData(previousText);
    }
    if (previousSibling == null || previousSibling instanceof Element)
    {
      Text textNode = parent.getOwnerDocument().createTextNode("");
      textNode.setData(previousText);
      parent.insertBefore(textNode, target);
    }				
  }

  public static void insertBefore(Node nodeToInsert, Node referenceNode)
  {
    // this assumes that the referenceNode and node to move have the same parent
    Node parent = referenceNode.getParentNode();

    Node previousSibling = referenceNode.getPreviousSibling();
    parent.insertBefore(nodeToInsert, referenceNode);
  }

  public static boolean inputEquals(Object input, String tagname, boolean isRef)
  {
    if (input instanceof Element)
    {
      Element element = (Element) input;
      if (element.getLocalName().equals(tagname))
      {
        boolean refPresent = element.hasAttribute("ref");

        return refPresent == isRef;
      }
    }
    return false;
  }

  public static void updateElementToNotAnonymous(Element element)
  {
    if (element != null)
    {
      NodeList children = element.getChildNodes();
      if (children != null)
      {
        for (int i = 0; i < children.getLength(); i++)
        {
          Node node = (Node)children.item(i);
          if (node instanceof Element)
          {
            if (node.getLocalName().equals(XSDConstants.SIMPLETYPE_ELEMENT_TAG) ||
                node.getLocalName().equals(XSDConstants.COMPLEXTYPE_ELEMENT_TAG))
            {
              XSDDOMHelper.removeNodeAndWhitespace(node);
              i=0;
            }
          }
        }
      }
    }
  }
  
  public static boolean isAttributeRef(Element ct, String attrName, String ns)
  {
    NodeList list = ct.getChildNodes();
    int length = list.getLength();
    for (int i = 0; i < length; i++)
    {
      if (list.item(i) instanceof Element)
      {
        Element aChild = (Element)list.item(i);
        if (aChild.getLocalName().equals(XSDConstants.ATTRIBUTE_ELEMENT_TAG))
        {
          if (aChild.hasAttribute(XSDConstants.REF_ATTRIBUTE))
          {
            String refValue = aChild.getAttribute(XSDConstants.REF_ATTRIBUTE);
            if (refValue.equals(attrName))
            {
              return true;
            }
          }
        }
      }
      
    }
    
    return false;
  }
}
