/**
  * Create IDOMPosition based on Indexed 'position' in model. If node at position is text, use
  * position to calculate DOMPosition offset, otherwize, simply create position pointed to
  * container's children list's edge.
  *
  * @param model
  * @param position
  * @param adjust
  * @return the dom position
  */
 public IDOMPosition createDomposition1(IDOMModel model, int position, boolean adjust) {
   try {
     // get the container
     Object object = getPosNode(model, position);
     if (object == null && position > 0) {
       // The end of file?
       object = getPosNode(model, position - 1);
     }
     Node container = null;
     if (object == null) {
       // empty file?
       return new DOMPosition(model.getDocument(), 0);
     }
     container = (Node) object;
     Object oppNode = getPosNode(model, position - 1);
     if (oppNode != null
         && !EditModelQuery.isChild((Node) oppNode, container)
         && //
         !EditModelQuery.isInline(container)
         && EditModelQuery.isInline((Node) oppNode)) {
       container = (Node) oppNode;
     }
     int location = EditHelper.getInstance().getLocation(container, position, false);
     IDOMPosition result = null;
     switch (location) {
       case 1:
       case 2:
         result = new DOMRefPosition(container, false);
         break;
       case 4:
       case 5:
         result = new DOMRefPosition(container, true);
         break;
       case 3:
         if (EditModelQuery.isText(container)) {
           result =
               new DOMPosition(container, position - EditModelQuery.getNodeStartIndex(container));
         } else {
           result = new DOMPosition(container, container.getChildNodes().getLength());
         }
     }
     return result;
   } catch (Exception e) {
     // "Error in position creation"
     _log.error("Error.EditModelQuery.0" + e); // $NON-NLS-1$
     return null;
   }
 }
 /**
  * @param node
  * @return if has tranparent node only
  */
 public static boolean hasTransparentNodeOnly(Node node) {
   NodeList children = node.getChildNodes();
   for (int i = 0, n = children.getLength(); i < n; i++) {
     if (!EditModelQuery.isTransparentText(children.item(i))) {
       return false;
     }
   }
   return true;
 }
 /**
  * Determine whether the position is at node's edge. When the offset is at edge, it is in the
  * leftmost or rightmost offset of node's region.
  *
  * @param position
  * @param forward
  * @return true if at edge
  */
 boolean atEdge(IDOMPosition position, boolean forward) {
   Node node = position.getContainerNode();
   int offset = position.getOffset();
   if (forward) {
     if (EditModelQuery.isText(node)) {
       return offset == node.getNodeValue().length();
     }
     return offset == node.getChildNodes().getLength();
   }
   return offset == 0;
 }
 /**
  * @param node
  * @param names
  * @param ignoreCase
  * @return true if node has ancestors in the name list TODO: bad practice
  */
 public static boolean hasAncestor(Node node, String names[], boolean ignoreCase) {
   Assert.isTrue(names != null);
   while (node != null && !EditModelQuery.isDocument(node)) {
     if (isElement(node))
       if (containItem(names, node, ignoreCase)) {
         return true;
       }
     node = node.getParentNode();
   }
   return false;
 }
 /**
  * To see if 'node' has ancestor that has name as 'name'
  *
  * @param node
  * @param name
  * @param ignoreCase
  * @return true if node has the named ancestor
  */
 public static boolean hasAncestor(Node node, String name, boolean ignoreCase) {
   Assert.isTrue(name != null);
   while (node != null && !EditModelQuery.isDocument(node)) {
     if (node.getNodeName() != null)
       if ((ignoreCase && name.equalsIgnoreCase(node.getNodeName()))
           || //
           (!ignoreCase && name.equals(node.getNodeName()))) {
         return true;
       }
     node = node.getParentNode();
   }
   return false;
 }
 /**
  * @param fModel
  * @param textSelection
  * @return the design range
  */
 static DesignRange convertToDesignRange(IStructuredModel fModel, TextSelection textSelection) {
   int start = textSelection.getOffset();
   int end = textSelection.getLength() + start;
   IDOMPosition startDomPos =
       EditModelQuery.getInstance().createDomposition((IDOMModel) fModel, start, false);
   IDOMPosition endDomPos =
       EditModelQuery.getInstance().createDomposition((IDOMModel) fModel, end, false);
   if (startDomPos == null) {
     startDomPos = endDomPos;
   } else if (endDomPos == null) {
     endDomPos = startDomPos;
   }
   if (startDomPos != null) {
     DesignPosition startPos = null, endPos = null;
     startPos = DOMPositionHelper.toDesignPosition(startDomPos);
     endPos = DOMPositionHelper.toDesignPosition(endDomPos);
     if (startPos != null) {
       return new DesignRange(startPos, endPos);
     }
   }
   return null;
 }
 /**
  * To see if 'node' has direct ancestors that has names listed in 'name[]'
  *
  * @param node
  * @param top
  * @param ignoreCase
  * @return the list of ancestors
  */
 public static List getAncestors(Node node, String top, boolean ignoreCase) {
   List result = new ArrayList();
   Assert.isTrue(node != null);
   while (node != null && !EditModelQuery.isDocument(node)) {
     result.add(node);
     String name = node.getLocalName();
     if (ignoreCase && top.equalsIgnoreCase(name)
         || //
         (!ignoreCase && top.equals(name))) {
       break;
     }
     node = node.getParentNode();
   }
   return result;
 }