/*******************************************************************************
 * 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.format.IStructuredFormatProcessor;
import org.eclipse.wst.xml.core.document.XMLModel;
import org.eclipse.wst.xml.core.document.XMLNode;
import org.eclipse.wst.xml.core.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 XMLNode)
    {
      XMLModel model = ((XMLNode)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;
  }
}
