    1   /*
    2    * $Header$
    3    * $Revision$
    4    * $Date$
    5    *
    6    * ====================================================================
    7    *
    8    * Copyright (C) 2005 bob mcwhirter & James Strachan.
    9    * All rights reserved.
    10   *
    11   * Redistribution and use in source and binary forms, with or without
    12   * modification, are permitted provided that the following conditions
    13   * are met:
    14   *
    15   * 1. Redistributions of source code must retain the above copyright
    16   *    notice, this list of conditions, and the following disclaimer.
    17   *
    18   * 2. Redistributions in binary form must reproduce the above copyright
    19   *    notice, this list of conditions, and the disclaimer that follows
    20   *    these conditions in the documentation and/or other materials
    21   *    provided with the distribution.
    22   *
    23   * 3. The name "Jaxen" must not be used to endorse or promote products
    24   *    derived from this software without prior written permission.  For
    25   *    written permission, please contact license@jaxen.org.
    26   *
    27   * 4. Products derived from this software may not be called "Jaxen", nor
    28   *    may "Jaxen" appear in their name, without prior written permission
    29   *    from the Jaxen Project Management (pm@jaxen.org).
    30   *
    31   * In addition, we request (but do not require) that you include in the
    32   * end-user documentation provided with the redistribution and/or in the
    33   * software itself an acknowledgement equivalent to the following:
    34   *     "This product includes software developed by the
    35   *      Jaxen Project (http://www.jaxen.org/)."
    36   * Alternatively, the acknowledgment may be graphical using the logos
    37   * available at http://www.jaxen.org/
    38   *
    39   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
    40   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
    41   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
    42   * DISCLAIMED.  IN NO EVENT SHALL THE Jaxen AUTHORS OR THE PROJECT
    43   * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    44   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    45   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
    46   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
    47   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
    48   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
    49   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
    50   * SUCH DAMAGE.
    51   *
    52   * ====================================================================
    53   * This software consists of voluntary contributions made by many
    54   * individuals on behalf of the Jaxen Project and was originally
    55   * created by bob mcwhirter <bob@werken.com> and
    56   * James Strachan <jstrachan@apache.org>.  For more information on the
    57   * Jaxen Project, please see <http://www.jaxen.org/>.
    58   *
    59   * $Id$
    60   */
    61
    62
    63  package org.jaxen;
    64
    65  import java.io.File;
    66  import java.io.IOException;
    67  import java.util.Iterator;
    68  import java.util.List;
    69
    70  import javax.xml.parsers.DocumentBuilder;
    71  import javax.xml.parsers.DocumentBuilderFactory;
    72  import javax.xml.parsers.ParserConfigurationException;
    73
    74  import org.jaxen.dom.DOMXPath;
    75  import org.jaxen.dom.NamespaceNode;
    76  import org.jaxen.pattern.Pattern;
    77  import org.jaxen.saxpath.helpers.XPathReaderFactory;
    78  import org.w3c.dom.Attr;
    79  import org.w3c.dom.Element;
    80  import org.w3c.dom.Node;
    81  import org.w3c.dom.Text;
    82  import org.xml.sax.SAXException;
    83
    84  import junit.framework.TestCase;
    85
    86  /***
    87   * <p>
    88   * Tests for org.jaxen.BaseXPath.
    89   * </p>
    90   *
    91   * @author Elliotte Rusty Harold
    92   * @version 1.1b7
    93   *
    94   */
    95  public class BaseXPathTest extends TestCase {
    96
    97      private org.w3c.dom.Document doc;
    98      private DocumentBuilder builder;
    99
    100     public BaseXPathTest(String name) {
    101         super(name);
    102     }
    103
    104     protected void setUp() throws ParserConfigurationException {
    105
    106         DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    107         factory.setNamespaceAware(true);
    108         doc = factory.newDocumentBuilder().newDocument();
    109         builder = factory.newDocumentBuilder();
    110
    111     }
    112
    113     public void testSelectSingleNodeForContext() throws JaxenException {
    114
    115         BaseXPath xpath = new BaseXPath("1 + 2");
    116
    117         String stringValue = xpath.stringValueOf(xpath);
    118         assertEquals("3", stringValue);
    119
    120         Number numberValue = xpath.numberValueOf(xpath);
    121         assertEquals(3, numberValue.doubleValue(), 0.00001);
    122
    123     }
    124
    125
    126     public void testParentOfSelection() throws JaxenException {
    127         /*
    128         html
    129             a
    130                 img
    131             a        <- return that node
    132                 img   <- select this node
    133         */
    134         XPath xpath = new DOMXPath("(/html/a/img[contains(@src,'gif')])[2]/..");
    135         org.w3c.dom.Element html = doc.createElementNS("", "html");
    136         org.w3c.dom.Element a1 = doc.createElementNS("", "a");
    137         org.w3c.dom.Element a2 = doc.createElementNS("", "a");
    138         org.w3c.dom.Element img1 = doc.createElementNS("", "img");
    139           org.w3c.dom.Attr img1_src = doc.createAttributeNS("", "src");
    140         img1_src.setValue("1.gif");
    141         org.w3c.dom.Element img2 = doc.createElementNS("", "img");
    142         org.w3c.dom.Attr img2_src = doc.createAttributeNS("", "src");
    143         img2_src.setValue("2.gif");
    144
    145         img1.setAttributeNode(img1_src);
    146         img2.setAttributeNode(img2_src);
    147         a1.appendChild(img1);
    148         a2.appendChild(img2);
    149         html.appendChild(a1);
    150         html.appendChild(a2);
    151         doc.appendChild(html);
    152
    153         List result = xpath.selectNodes(doc);
    154         assertEquals(1, result.size());
    155         assertEquals(a2, result.get(0));
    156     }
    157
    158
    159
    160
    161     public void testEvaluateString() throws JaxenException {
    162
    163         BaseXPath xpath = new DOMXPath("string(/*)");
    164
    165         doc.appendChild(doc.createElement("root"));
    166         String stringValue = (String) xpath.evaluate(doc);
    167         assertEquals("", stringValue);
    168
    169     }
    170
    171
    172     public void testNumberValueOfEmptyNodeSetIsNaN() throws JaxenException {
    173
    174         BaseXPath xpath = new DOMXPath("/x");
    175
    176         doc.appendChild(doc.createElement("root"));
    177         Double numberValue = (Double) xpath.numberValueOf(doc);
    178         assertTrue(numberValue.isNaN());
    179
    180     }
    181
    182
    183     public void testPathWithParentheses() throws JaxenException {
    184
    185         BaseXPath xpath = new DOMXPath("(/root)/child");
    186
    187         Element root = doc.createElement("root");
    188         doc.appendChild(root);
    189         Element child = doc.createElement("child");
    190         root.appendChild(child);
    191
    192         assertEquals(child, xpath.selectSingleNode(doc));
    193
    194     }
    195
    196
    197     public void testEvaluateWithMultiNodeAnswer() throws JaxenException {
    198
    199         BaseXPath xpath = new DOMXPath("(/descendant-or-self::node())");
    200
    201         doc.appendChild(doc.createElement("root"));
    202         List result = (List) xpath.evaluate(doc);
    203         assertEquals(2, result.size());
    204
    205     }
    206
    207
    208     public void testValueOfEmptyListIsEmptyString() throws JaxenException {
    209
    210         BaseXPath xpath = new DOMXPath("/element");
    211         doc.appendChild(doc.createElement("root"));
    212
    213         String stringValue = xpath.stringValueOf(doc);
    214         assertEquals("", stringValue);
    215
    216     }
    217
    218     public void testAllNodesQuery() throws JaxenException {
    219
    220         BaseXPath xpath = new DOMXPath("//. | /");
    221         org.w3c.dom.Element root = doc.createElementNS("http://www.example.org/", "root");
    222         doc.appendChild(root);
    223
    224         String stringValue = xpath.stringValueOf(doc);
    225         assertEquals("", stringValue);
    226
    227     }
    228
    229
    230     public void testAncestorAxis() throws JaxenException {
    231
    232         BaseXPath xpath = new DOMXPath("ancestor::*");
    233         org.w3c.dom.Element root = doc.createElementNS("", "root");
    234         org.w3c.dom.Element parent = doc.createElementNS("", "parent");
    235         doc.appendChild(root);
    236         org.w3c.dom.Element child = doc.createElementNS("", "child");
    237         root.appendChild(parent);
    238         parent.appendChild(child);
    239
    240         List result = xpath.selectNodes(child);
    241         assertEquals(2, result.size());
    242         assertEquals(root, result.get(0));
    243         assertEquals(parent, result.get(1));
    244
    245     }
    246
    247
    248     public void testPrecedingSiblingAxisIsInDocumentOrder() throws JaxenException {
    249
    250         BaseXPath xpath = new DOMXPath("preceding-sibling::*");
    251         org.w3c.dom.Element root = doc.createElementNS("", "root");
    252         doc.appendChild(root);
    253         org.w3c.dom.Element child1 = doc.createElementNS("", "child1");
    254         root.appendChild(child1);
    255         org.w3c.dom.Element child2 = doc.createElementNS("", "child2");
    256         root.appendChild(child2);
    257         org.w3c.dom.Element child3 = doc.createElementNS("", "child3");
    258         root.appendChild(child3);
    259
    260         List result = xpath.selectNodes(child3);
    261         assertEquals(2, result.size());
    262         assertEquals(child1, result.get(0));
    263         assertEquals(child2, result.get(1));
    264
    265     }
    266
    267
    268     public void testPrecedingAxisIsInDocumentOrder() throws JaxenException {
    269
    270         BaseXPath xpath = new DOMXPath("preceding::*");
    271         org.w3c.dom.Element root = doc.createElementNS("", "root");
    272         doc.appendChild(root);
    273         org.w3c.dom.Element parent1 = doc.createElementNS("", "parent1");
    274         root.appendChild(parent1);
    275         org.w3c.dom.Element parent2 = doc.createElementNS("", "parent2");
    276         root.appendChild(parent2);
    277         org.w3c.dom.Element child1 = doc.createElementNS("", "child1");
    278         parent2.appendChild(child1);
    279         org.w3c.dom.Element child2 = doc.createElementNS("", "child2");
    280         parent2.appendChild(child2);
    281         org.w3c.dom.Element child3 = doc.createElementNS("", "child3");
    282         parent2.appendChild(child3);
    283
    284         List result = xpath.selectNodes(child3);
    285         assertEquals(3, result.size());
    286         assertEquals(parent1, result.get(0));
    287         assertEquals(child1, result.get(1));
    288         assertEquals(child2, result.get(2));
    289
    290     }
    291
    292
    293     public void testPrecedingAxisWithPositionalPredicate() throws JaxenException {
    294
    295         BaseXPath xpath = new DOMXPath("preceding::*[1]");
    296         org.w3c.dom.Element root = doc.createElementNS("", "root");
    297         doc.appendChild(root);
    298         org.w3c.dom.Element child1 = doc.createElementNS("", "child1");
    299         root.appendChild(child1);
    300         org.w3c.dom.Element child2 = doc.createElementNS("", "child2");
    301         root.appendChild(child2);
    302         org.w3c.dom.Element child3 = doc.createElementNS("", "child3");
    303         root.appendChild(child3);
    304
    305         List result = xpath.selectNodes(child3);
    306         assertEquals(1, result.size());
    307         assertEquals(child2, result.get(0));
    308
    309     }
    310
    311
    312     public void testAncestorAxisWithPositionalPredicate() throws JaxenException {
    313
    314         BaseXPath xpath = new DOMXPath("ancestor::*[1]");
    315         org.w3c.dom.Element root = doc.createElementNS("", "root");
    316         doc.appendChild(root);
    317         org.w3c.dom.Element child1 = doc.createElementNS("", "child1");
    318         root.appendChild(child1);
    319         org.w3c.dom.Element child2 = doc.createElementNS("", "child2");
    320         child1.appendChild(child2);
    321         org.w3c.dom.Element child3 = doc.createElementNS("", "child3");
    322         child2.appendChild(child3);
    323
    324         List result = xpath.selectNodes(child3);
    325         assertEquals(1, result.size());
    326         assertEquals(child2, result.get(0));
    327
    328     }
    329
    330
    331     public void testAncestorOrSelfAxis() throws JaxenException {
    332
    333         BaseXPath xpath = new DOMXPath("ancestor-or-self::*");
    334         org.w3c.dom.Element root = doc.createElementNS("", "root");
    335         org.w3c.dom.Element parent = doc.createElementNS("", "parent");
    336         doc.appendChild(root);
    337         org.w3c.dom.Element child = doc.createElementNS("", "child");
    338         root.appendChild(parent);
    339         parent.appendChild(child);
    340
    341         List result = xpath.selectNodes(child);
    342         assertEquals(3, result.size());
    343         assertEquals(root, result.get(0));
    344         assertEquals(parent, result.get(1));
    345         assertEquals(child, result.get(2));
    346
    347     }
    348
    349
    350     // test case for JAXEN-55
    351     public void testAbbreviatedDoubleSlashAxis() throws JaxenException {
    352
    353         BaseXPath xpath = new DOMXPath("//x");
    354         org.w3c.dom.Element a = doc.createElementNS("", "a");
    355         org.w3c.dom.Element b = doc.createElementNS("", "b");
    356         doc.appendChild(a);
    357         org.w3c.dom.Element x1 = doc.createElementNS("", "x");
    358         x1.appendChild(doc.createTextNode("1"));
    359         a.appendChild(x1);
    360         a.appendChild(b);
    361         org.w3c.dom.Element x2 = doc.createElementNS("", "x");
    362         org.w3c.dom.Element x3 = doc.createElementNS("", "x");
    363         org.w3c.dom.Element x4 = doc.createElementNS("", "x");
    364         a.appendChild(x4);
    365         b.appendChild(x2);
    366         b.appendChild(x3);
    367         x2.appendChild(doc.createTextNode("2"));
    368         x3.appendChild(doc.createTextNode("3"));
    369         x4.appendChild(doc.createTextNode("4"));
    370
    371         List result = xpath.selectNodes(doc);
    372         assertEquals(4, result.size());
    373         assertEquals(x1, result.get(0));
    374         assertEquals(x2, result.get(1));
    375         assertEquals(x3, result.get(2));
    376         assertEquals(x4, result.get(3));
    377
    378     }
    379
    380
    381     // test case for JAXEN-55
    382     public void testAncestorFollowedByChildren() throws JaxenException {
    383
    384         BaseXPath xpath = new DOMXPath("/a/b/x/ancestor::*/child::x");
    385         org.w3c.dom.Element a = doc.createElementNS("", "a");
    386         org.w3c.dom.Element b = doc.createElementNS("", "b");
    387         doc.appendChild(a);
    388         org.w3c.dom.Element x1 = doc.createElementNS("", "x");
    389         x1.appendChild(doc.createTextNode("1"));
    390         a.appendChild(x1);
    391         a.appendChild(b);
    392         org.w3c.dom.Element x2 = doc.createElementNS("", "x");
    393         org.w3c.dom.Element x3 = doc.createElementNS("", "x");
    394         org.w3c.dom.Element x4 = doc.createElementNS("", "x");
    395         a.appendChild(x4);
    396         b.appendChild(x2);
    397         b.appendChild(x3);
    398         x2.appendChild(doc.createTextNode("2"));
    399         x3.appendChild(doc.createTextNode("3"));
    400         x4.appendChild(doc.createTextNode("4"));
    401
    402         List result = xpath.selectNodes(doc);
    403         assertEquals(4, result.size());
    404         assertEquals(x1, result.get(0));
    405         assertEquals(x2, result.get(1));
    406         assertEquals(x3, result.get(2));
    407         assertEquals(x4, result.get(3));
    408
    409     }
    410
    411
    412     // test case for JAXEN-55
    413     public void testDescendantAxis() throws JaxenException {
    414
    415         BaseXPath xpath = new DOMXPath("/descendant::x");
    416         org.w3c.dom.Element a = doc.createElementNS("", "a");
    417         org.w3c.dom.Element b = doc.createElementNS("", "b");
    418         doc.appendChild(a);
    419         org.w3c.dom.Element x1 = doc.createElementNS("", "x");
    420         x1.appendChild(doc.createTextNode("1"));
    421         a.appendChild(x1);
    422         a.appendChild(b);
    423         org.w3c.dom.Element x2 = doc.createElementNS("", "x");
    424         org.w3c.dom.Element x3 = doc.createElementNS("", "x");
    425         org.w3c.dom.Element x4 = doc.createElementNS("", "x");
    426         a.appendChild(x4);
    427         b.appendChild(x2);
    428         b.appendChild(x3);
    429         x2.appendChild(doc.createTextNode("2"));
    430         x3.appendChild(doc.createTextNode("3"));
    431         x4.appendChild(doc.createTextNode("4"));
    432
    433         List result = xpath.selectNodes(doc);
    434         assertEquals(4, result.size());
    435         assertEquals(x1, result.get(0));
    436         assertEquals(x2, result.get(1));
    437         assertEquals(x3, result.get(2));
    438         assertEquals(x4, result.get(3));
    439
    440     }
    441
    442     public void testDescendantAxisWithAttributes() throws JaxenException {
    443
    444         BaseXPath xpath = new DOMXPath("/descendant::x/@*");
    445         org.w3c.dom.Element a = doc.createElementNS("", "a");
    446         org.w3c.dom.Element b = doc.createElementNS("", "b");
    447         doc.appendChild(a);
    448         org.w3c.dom.Element x1 = doc.createElementNS("", "x");
    449         a.appendChild(x1);
    450         a.appendChild(b);
    451         org.w3c.dom.Element x2 = doc.createElementNS("", "x");
    452         org.w3c.dom.Element x3 = doc.createElementNS("", "x");
    453         org.w3c.dom.Element x4 = doc.createElementNS("", "x");
    454         a.appendChild(x4);
    455         b.appendChild(x2);
    456         b.appendChild(x3);
    457
    458         Attr a1 = doc.createAttribute("name");
    459         a1.setNodeValue("1");
    460         x1.setAttributeNode(a1);
    461         Attr a2 = doc.createAttribute("name");
    462         a2.setNodeValue("2");
    463         x2.setAttributeNode(a2);
    464         Attr a3 = doc.createAttribute("name");
    465         a3.setNodeValue("3");
    466         x3.setAttributeNode(a3);
    467         Attr a4 = doc.createAttribute("name");
    468         a4.setNodeValue("4");
    469         x4.setAttributeNode(a4);
    470
    471         List result = xpath.selectNodes(doc);
    472         assertEquals(4, result.size());
    473         assertEquals(a1, result.get(0));
    474         assertEquals(a2, result.get(1));
    475         assertEquals(a3, result.get(2));
    476         assertEquals(a4, result.get(3));
    477
    478     }
    479
    480     public void testDescendantAxisWithNamespaceNodes() throws JaxenException {
    481
    482         BaseXPath xpath = new DOMXPath("/descendant::x/namespace::node()");
    483         org.w3c.dom.Element a = doc.createElementNS("", "a");
    484         org.w3c.dom.Element b = doc.createElementNS("", "b");
    485         doc.appendChild(a);
    486         org.w3c.dom.Element x1 = doc.createElementNS("", "x");
    487         a.appendChild(x1);
    488         a.appendChild(b);
    489         org.w3c.dom.Element x2 = doc.createElementNS("", "x");
    490         org.w3c.dom.Element x3 = doc.createElementNS("", "x");
    491         org.w3c.dom.Element x4 = doc.createElementNS("", "x");
    492         a.appendChild(x4);
    493         b.appendChild(x2);
    494         b.appendChild(x3);
    495
    496         Attr a1 = doc.createAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:a");
    497         a1.setNodeValue("http://www.example.org/");
    498         x1.setAttributeNode(a1);
    499         Attr a2 = doc.createAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:b");
    500         a2.setNodeValue("http://www.example.org/");
    501         x2.setAttributeNode(a2);
    502         Attr a3 = doc.createAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:c");
    503         a3.setNodeValue("http://www.example.org/");
    504         x3.setAttributeNode(a3);
    505         Attr a4 = doc.createAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:d");
    506         a4.setNodeValue("http://www.example.org/");
    507         x4.setAttributeNode(a4);
    508
    509         List result = xpath.selectNodes(doc);
    510         assertEquals(8, result.size());
    511         Iterator iterator = result.iterator();
    512         StringBuffer sb = new StringBuffer(4);
    513         while (iterator.hasNext()) {
    514             NamespaceNode ns = (NamespaceNode) iterator.next();
    515             if (ns.getNodeValue().equals("http://www.example.org/")) {
    516                 String name = ns.getNodeName();
    517                 sb.append(name);
    518             }
    519         }
    520         assertEquals("abcd", sb.toString());
    521
    522     }
    523
    524     public void testMultipleAttributesOnElement() throws JaxenException {
    525
    526         BaseXPath xpath = new DOMXPath("/descendant::x/@*");
    527         org.w3c.dom.Element a = doc.createElementNS("", "a");
    528         org.w3c.dom.Element b = doc.createElementNS("", "b");
    529         doc.appendChild(a);
    530         org.w3c.dom.Element x1 = doc.createElementNS("", "x");
    531         a.appendChild(x1);
    532         a.appendChild(b);
    533
    534         Attr a1 = doc.createAttribute("name1");
    535         a1.setNodeValue("1");
    536         x1.setAttributeNode(a1);
    537         Attr a2 = doc.createAttribute("name2");
    538         a2.setNodeValue("2");
    539         x1.setAttributeNode(a2);
    540         Attr a3 = doc.createAttribute("name3");
    541         a3.setNodeValue("3");
    542         x1.setAttributeNode(a3);
    543         Attr a4 = doc.createAttribute("name4");
    544         a4.setNodeValue("4");
    545         x1.setAttributeNode(a4);
    546
    547         List result = xpath.selectNodes(doc);
    548         assertEquals(4, result.size());
    549         assertTrue(result.contains(a1));
    550         assertTrue(result.contains(a2));
    551         assertTrue(result.contains(a3));
    552         assertTrue(result.contains(a4));
    553
    554     }
    555
    556     public void testXMLNamespaceAttributeOrderOnAncestorAxis()
    557       throws JaxenException {
    558
    559         org.w3c.dom.Element superroot = doc.createElement("superroot");
    560         doc.appendChild(superroot);
    561         org.w3c.dom.Element root = doc.createElement("root");
    562         superroot.appendChild(root);
    563
    564         org.w3c.dom.Attr p0 = doc.createAttributeNS("http://www.w3.org/XML/1998/namespace", "xml:id");
    565         p0.setValue("p0");
    566         superroot.setAttributeNodeNS(p0);
    567         org.w3c.dom.Attr p1 = doc.createAttributeNS("http://www.w3.org/XML/1998/namespace", "xml:id");
    568         p1.setValue("p1");
    569         root.setAttributeNodeNS(p1);
    570
    571         org.w3c.dom.Element child = doc.createElement("child312");
    572         root.appendChild(child);
    573
    574         BaseXPath xpath = new DOMXPath("ancestor::*/@xml:*");
    575         List result = xpath.selectNodes(child);
    576         assertEquals(2, result.size());
    577         assertEquals(p0, result.get(0));
    578         assertEquals(p1, result.get(1));
    579
    580     }
    581
    582     public void testDescendantAxisWithAttributesAndChildren() throws JaxenException {
    583
    584         BaseXPath xpath = new DOMXPath("/descendant::x/@* | /descendant::x");
    585         org.w3c.dom.Element a = doc.createElementNS("", "a");
    586         org.w3c.dom.Element b = doc.createElementNS("", "b");
    587         doc.appendChild(a);
    588         org.w3c.dom.Element x1 = doc.createElementNS("", "x");
    589         a.appendChild(x1);
    590         a.appendChild(b);
    591         org.w3c.dom.Element x2 = doc.createElementNS("", "x");
    592         org.w3c.dom.Element x3 = doc.createElementNS("", "x");
    593         org.w3c.dom.Element x4 = doc.createElementNS("", "x");
    594         a.appendChild(x4);
    595         b.appendChild(x2);
    596         b.appendChild(x3);
    597
    598         Attr a1 = doc.createAttribute("name");
    599         a1.setNodeValue("1");
    600         x1.setAttributeNode(a1);
    601         Attr a2 = doc.createAttribute("name");
    602         a2.setNodeValue("2");
    603         x2.setAttributeNode(a2);
    604         Attr a3 = doc.createAttribute("name");
    605         a3.setNodeValue("3");
    606         x3.setAttributeNode(a3);
    607         Attr a4 = doc.createAttribute("name");
    608         a4.setNodeValue("4");
    609         x4.setAttributeNode(a4);
    610
    611         List result = xpath.selectNodes(doc);
    612         assertEquals(8, result.size());
    613         assertEquals(x1, result.get(0));
    614         assertEquals(a1, result.get(1));
    615         assertEquals(x2, result.get(2));
    616         assertEquals(a2, result.get(3));
    617         assertEquals(x3, result.get(4));
    618         assertEquals(a3, result.get(5));
    619         assertEquals(x4, result.get(6));
    620         assertEquals(a4, result.get(7));
    621
    622     }
    623
    624     public void testAncestorAxisWithAttributes() throws JaxenException {
    625
    626         BaseXPath xpath = new DOMXPath("ancestor::*/@*");
    627         org.w3c.dom.Element a = doc.createElementNS("", "a");
    628         org.w3c.dom.Element b = doc.createElementNS("", "b");
    629         doc.appendChild(a);
    630         a.appendChild(b);
    631         org.w3c.dom.Element x3 = doc.createElementNS("", "x");
    632         b.appendChild(x3);
    633
    634         Attr a1 = doc.createAttribute("name");
    635         a1.setNodeValue("1");
    636         a.setAttributeNode(a1);
    637         Attr a2 = doc.createAttribute("name");
    638         a2.setNodeValue("2");
    639         b.setAttributeNode(a2);
    640         Attr a3 = doc.createAttribute("name");
    641         x3.setNodeValue("3");
    642         x3.setAttributeNode(a3);
    643
    644         List result = xpath.selectNodes(x3);
    645         assertEquals(2, result.size());
    646         assertEquals(a1, result.get(0));
    647         assertEquals(a2, result.get(1));
    648
    649     }
    650
    651     // test for Jaxen-83
    652     public void testPrincipalNodeTypeOfSelfAxisIsElement() throws JaxenException {
    653
    654         BaseXPath xpath = new DOMXPath("child/@*[self::test]");
    655         org.w3c.dom.Element a = doc.createElementNS("", "child");
    656         org.w3c.dom.Attr test = doc.createAttributeNS("", "test");
    657         test.setValue("value");
    658         a.setAttributeNode(test);
    659         doc.appendChild(a);
    660
    661         List result = xpath.selectNodes(doc);
    662         assertEquals(0, result.size());
    663
    664     }
    665
    666     // test to make sure Jaxen-83 fix doesn't go too far
    667     public void testSelfAxisWithNodeTestCanReturnNonPrincipalNodeType() throws JaxenException {
    668
    669         BaseXPath xpath = new DOMXPath("child/@*[self::node()]");
    670         org.w3c.dom.Element a = doc.createElementNS("", "child");
    671         org.w3c.dom.Attr test = doc.createAttributeNS("", "test");
    672         test.setValue("value");
    673         a.setAttributeNode(test);
    674         doc.appendChild(a);
    675
    676         List result = xpath.selectNodes(doc);
    677         assertEquals(1, result.size());
    678
    679     }
    680
    681     // another Jaxen-55 test to try to pin down exactly what does
    682     // and doesn't work
    683     public void testDescendantOrSelfAxis() throws JaxenException {
    684
    685         BaseXPath xpath = new DOMXPath("/descendant-or-self::x");
    686         org.w3c.dom.Element a = doc.createElementNS("", "a");
    687         org.w3c.dom.Element b = doc.createElementNS("", "b");
    688         doc.appendChild(a);
    689         org.w3c.dom.Element x1 = doc.createElementNS("", "x");
    690         x1.appendChild(doc.createTextNode("1"));
    691         a.appendChild(x1);
    692         a.appendChild(b);
    693         org.w3c.dom.Element x2 = doc.createElementNS("", "x");
    694         org.w3c.dom.Element x3 = doc.createElementNS("", "x");
    695         org.w3c.dom.Element x4 = doc.createElementNS("", "x");
    696         a.appendChild(x4);
    697         b.appendChild(x2);
    698         b.appendChild(x3);
    699         x2.appendChild(doc.createTextNode("2"));
    700         x3.appendChild(doc.createTextNode("3"));
    701         x4.appendChild(doc.createTextNode("4"));
    702
    703         List result = xpath.selectNodes(doc);
    704         assertEquals(4, result.size());
    705         assertEquals(x1, result.get(0));
    706         assertEquals(x2, result.get(1));
    707         assertEquals(x3, result.get(2));
    708         assertEquals(x4, result.get(3));
    709
    710     }
    711
    712
    713     public void testDuplicateNodes() throws JaxenException {
    714
    715         BaseXPath xpath = new DOMXPath("//x | //*");
    716         org.w3c.dom.Element a = doc.createElementNS("", "a");
    717         org.w3c.dom.Element b = doc.createElementNS("", "b");
    718         doc.appendChild(a);
    719         org.w3c.dom.Element x1 = doc.createElementNS("", "x");
    720         x1.appendChild(doc.createTextNode("1"));
    721         a.appendChild(x1);
    722         a.appendChild(b);
    723         org.w3c.dom.Element x2 = doc.createElementNS("", "x");
    724         org.w3c.dom.Element x3 = doc.createElementNS("", "x");
    725         org.w3c.dom.Element x4 = doc.createElementNS("", "x");
    726         a.appendChild(x4);
    727         b.appendChild(x2);
    728         b.appendChild(x3);
    729         x2.appendChild(doc.createTextNode("2"));
    730         x3.appendChild(doc.createTextNode("3"));
    731         x4.appendChild(doc.createTextNode("4"));
    732
    733         List result = xpath.selectNodes(doc);
    734         assertEquals(6, result.size());
    735
    736     }
    737
    738     public void testUnionOfNodesWithNonNodes() throws JaxenException {
    739
    740         BaseXPath xpath = new DOMXPath("count(//*) | //x ");
    741         org.w3c.dom.Element a = doc.createElementNS("", "a");
    742         org.w3c.dom.Element b = doc.createElementNS("", "b");
    743         doc.appendChild(a);
    744         org.w3c.dom.Element x1 = doc.createElementNS("", "x");
    745         x1.appendChild(doc.createTextNode("1"));
    746         a.appendChild(x1);
    747         a.appendChild(b);
    748         org.w3c.dom.Element x2 = doc.createElementNS("", "x");
    749         org.w3c.dom.Element x3 = doc.createElementNS("", "x");
    750         org.w3c.dom.Element x4 = doc.createElementNS("", "x");
    751         a.appendChild(x4);
    752         b.appendChild(x2);
    753         b.appendChild(x3);
    754         x2.appendChild(doc.createTextNode("2"));
    755         x3.appendChild(doc.createTextNode("3"));
    756         x4.appendChild(doc.createTextNode("4"));
    757
    758         try {
    759             xpath.selectNodes(doc);
    760             fail("Allowed union with non-node-set");
    761         }
    762         catch (JaxenException ex) {
    763             assertNotNull(ex.getMessage());
    764         }
    765
    766     }
    767
    768     public void testUnionOfEmptyNodeSetWithNonNodes() throws JaxenException {
    769
    770         BaseXPath xpath = new DOMXPath("//y | count(//*)");
    771         org.w3c.dom.Element a = doc.createElementNS("", "a");
    772         org.w3c.dom.Element b = doc.createElementNS("", "b");
    773         doc.appendChild(a);
    774         org.w3c.dom.Element x1 = doc.createElementNS("", "x");
    775         x1.appendChild(doc.createTextNode("1"));
    776         a.appendChild(x1);
    777         a.appendChild(b);
    778         org.w3c.dom.Element x2 = doc.createElementNS("", "x");
    779         b.appendChild(x2);
    780         x2.appendChild(doc.createTextNode("2"));
    781
    782         try {
    783             xpath.selectNodes(doc);
    784             fail("Allowed union with non-node-set");
    785         }
    786         catch (JaxenException ex) {
    787             assertNotNull(ex.getMessage());
    788         }
    789
    790     }
    791
    792     public void testSelectSingleNodeSelectsNothing()
    793       throws JaxenException {
    794
    795         BaseXPath xpath = new DOMXPath("id('p1')");
    796         org.w3c.dom.Element a = doc.createElementNS("", "a");
    797         doc.appendChild(a);
    798         Object result = xpath.selectSingleNode(doc);
    799         assertNull(result);
    800
    801     }
    802
    803     public void testSAXPathExceptionThrownFromConstructor() {
    804
    805         System.setProperty( XPathReaderFactory.DRIVER_PROPERTY,
    806                             "java.lang.String" );
    807
    808         try {
    809             new DOMXPath("id('p1')");
    810         }
    811         catch (JaxenException e) {
    812             assertNotNull(e.getMessage());
    813         }
    814         finally {
    815             System.setProperty( XPathReaderFactory.DRIVER_PROPERTY,
    816                             "" );
    817         }
    818
    819     }
    820
    821     public void testBooleanValueOfEmptyNodeSetIsFalse()
    822       throws JaxenException {
    823
    824         BaseXPath xpath = new DOMXPath("/b/c");
    825         org.w3c.dom.Element a = doc.createElementNS("", "a");
    826         doc.appendChild(a);
    827         List result = xpath.selectNodes(doc);
    828         assertTrue(! xpath.booleanValueOf(result));
    829
    830     }
    831
    832     public void testAddNamespaceWithNonSimpleNamespaceContext() throws JaxenException {
    833
    834         BaseXPath xpath = new DOMXPath("/b/c");
    835         xpath.setNamespaceContext(new NamespaceContext() {
    836
    837             public String translateNamespacePrefixToUri(String prefix) {
    838                 return prefix;
    839             }
    840
    841         });
    842         try {
    843             xpath.addNamespace("pre", "foo");
    844             fail("Added namespace");
    845         }
    846         catch (JaxenException ex) {
    847             assertNotNull(ex.getMessage());
    848         }
    849
    850     }
    851
    852     public void testDebug() throws JaxenException {
    853
    854         BaseXPath xpath = new DOMXPath("/b/c");
    855         assertEquals("[(DefaultXPath): [(DefaultAbsoluteLocationPath): [(DefaultNameStep): :b]/[(DefaultNameStep): :c]]]", xpath.debug());
    856
    857     }
    858
    859     public void testGetRootExpr() throws JaxenException {
    860         BaseXPath xpath = new DOMXPath("/b/c");
    861         assertTrue(xpath.getRootExpr() instanceof org.jaxen.expr.LocationPath);
    862     }
    863
    864     public void testUnionUsesDocumentOrder() throws JaxenException {
    865
    866         BaseXPath xpath = new DOMXPath("/descendant::x | /a | /a/b");
    867         org.w3c.dom.Element a = doc.createElementNS("", "a");
    868         org.w3c.dom.Element b = doc.createElementNS("", "b");
    869         doc.appendChild(a);
    870         org.w3c.dom.Element x1 = doc.createElementNS("", "x");
    871         x1.appendChild(doc.createTextNode("1"));
    872         a.appendChild(x1);
    873         a.appendChild(b);
    874         org.w3c.dom.Element x2 = doc.createElementNS("", "x");
    875         org.w3c.dom.Element x3 = doc.createElementNS("", "x");
    876         org.w3c.dom.Element x4 = doc.createElementNS("", "x");
    877         a.appendChild(x4);
    878         b.appendChild(x2);
    879         b.appendChild(x3);
    880         x2.appendChild(doc.createTextNode("2"));
    881         x3.appendChild(doc.createTextNode("3"));
    882         x4.appendChild(doc.createTextNode("4"));
    883
    884         List result = xpath.selectNodes(doc);
    885         assertEquals(6, result.size());
    886         assertEquals(a, result.get(0));
    887         assertEquals(x1, result.get(1));
    888         assertEquals(b, result.get(2));
    889         assertEquals(x2, result.get(3));
    890         assertEquals(x3, result.get(4));
    891         assertEquals(x4, result.get(5));
    892
    893     }
    894
    895     public void testArithmeticAssociativity() throws JaxenException {
    896         XPath xpath = new DOMXPath("2+1-1+1");
    897         Double result = (Double) xpath.evaluate(doc);
    898         assertEquals(3, result.intValue());
    899     }
    900
    901     public void testLogicalAssociativity() throws JaxenException {
    902         XPath xpath = new DOMXPath("false() or true() and true() and false()");
    903         Boolean result = (Boolean) xpath.evaluate(doc);
    904         assertFalse(result.booleanValue());
    905     }
    906
    907     public void testRelationalAssociativity3() throws JaxenException {
    908         XPath xpath = new DOMXPath("3 > 2 > 1");
    909         Boolean result = (Boolean) xpath.evaluate(doc);
    910         assertFalse(result.booleanValue());
    911     }
    912
    913     public void testRelationalAssociativity4() throws JaxenException {
    914         XPath xpath = new DOMXPath("4 > 3 > 2 > 1");
    915         Boolean result = (Boolean) xpath.evaluate(doc);
    916         assertFalse(result.booleanValue());
    917     }
    918
    919     public void testRelationalGTAssociativity5() throws JaxenException {
    920         XPath xpath = new DOMXPath("5 > 4 > 3 > 2 > 1");
    921         Boolean result = (Boolean) xpath.evaluate(doc);
    922         assertFalse(result.booleanValue());
    923     }
    924
    925     public void testRelationalLTAssociativity5() throws JaxenException {
    926         XPath xpath = new DOMXPath("1 < 2 < 3 < 4 < 5");
    927         Boolean result = (Boolean) xpath.evaluate(doc);
    928         assertTrue(result.booleanValue());
    929     }
    930
    931     public void testRelationalLEAssociativity5() throws JaxenException {
    932         XPath xpath = new DOMXPath("1 <= 2 <= 3 <= 4 <= 5");
    933         Boolean result = (Boolean) xpath.evaluate(doc);
    934         assertTrue(result.booleanValue());
    935     }
    936
    937     public void testRelationalGEAssociativity5() throws JaxenException {
    938         XPath xpath = new DOMXPath("5 >= 4 >= 3 >= 2 >= 1");
    939         Boolean result = (Boolean) xpath.evaluate(doc);
    940         assertFalse(result.booleanValue());
    941     }
    942
    943     public void testRelationalGEAssociativity3() throws JaxenException {
    944         XPath xpath = new DOMXPath("3 >= 2 >= 1");
    945         Boolean result = (Boolean) xpath.evaluate(doc);
    946         assertTrue(result.booleanValue());
    947     }
    948
    949     public void testRelationalGEAssociativity2() throws JaxenException {
    950         XPath xpath = new DOMXPath("2 >= 1");
    951         Boolean result = (Boolean) xpath.evaluate(doc);
    952         assertTrue(result.booleanValue());
    953     }
    954
    955     public void testRelationalGEAssociativity4() throws JaxenException {
    956         XPath xpath = new DOMXPath("4 >= 3 >= 2 >= 1");
    957         Boolean result = (Boolean) xpath.evaluate(doc);
    958         assertFalse(result.booleanValue());
    959     }
    960
    961     // This is the same test but with parentheses to make explicit
    962     // how the previous test should be evaluated.
    963     public void testRelationalAssociativity5P() throws JaxenException {
    964         XPath xpath = new DOMXPath("((((5 > 4) > 3) > 2) > 1)");
    965         Boolean result = (Boolean) xpath.evaluate(doc);
    966         assertFalse(result.booleanValue());
    967     }
    968
    969     public void testInequalityAssociativity5() throws JaxenException {
    970         XPath xpath = new DOMXPath("2 != 3 != 1 != 4 != 0");
    971         Boolean result = (Boolean) xpath.evaluate(doc);
    972         assertTrue(result.booleanValue());
    973     }
    974
    975     // This is the same test but with parentheses to make explicit
    976     // how the previous test should be evaluated.
    977     public void testInequalityAssociativity5P() throws JaxenException {
    978         XPath xpath = new DOMXPath("(((2 != 3) != 1) != 4) != 0");
    979         Boolean result = (Boolean) xpath.evaluate(doc);
    980         assertTrue(result.booleanValue());
    981     }
    982
    983     public void testInequalityAssociativity5B() throws JaxenException {
    984         XPath xpath = new DOMXPath("2 != 3 != 1 != 4 != 1");
    985         Boolean result = (Boolean) xpath.evaluate(doc);
    986         assertFalse(result.booleanValue());
    987     }
    988
    989     // This is the same test but with parentheses to make explicit
    990     // how the previous test should be evaluated.
    991     public void testInequalityAssociativity5BP() throws JaxenException {
    992         XPath xpath = new DOMXPath("(((2 != 3) != 1) != 4) != 1");
    993         Boolean result = (Boolean) xpath.evaluate(doc);
    994         assertFalse(result.booleanValue());
    995     }
    996
    997     public void testEqualityAssociativity5() throws JaxenException {
    998         XPath xpath = new DOMXPath("2 = 3 = 1 = 4 = 0");
    999         Boolean result = (Boolean) xpath.evaluate(doc);
    1000         assertTrue(result.booleanValue());
    1001     }
    1002
    1003     // This is the same test but with parentheses to make explicit
    1004     // how the previous test should be evaluated.
    1005     public void testEqualityAssociativity5P() throws JaxenException {
    1006         XPath xpath = new DOMXPath("(((2 = 3) = 1) = 4) = 0");
    1007         Boolean result = (Boolean) xpath.evaluate(doc);
    1008         assertTrue(result.booleanValue());
    1009     }
    1010
    1011     public void testEqualityAssociativity5B() throws JaxenException {
    1012         XPath xpath = new DOMXPath("2 = 3 = 1 = 4 = 1");
    1013         Boolean result = (Boolean) xpath.evaluate(doc);
    1014         assertFalse(result.booleanValue());
    1015     }
    1016
    1017     // This is the same test but with parentheses to make explicit
    1018     // how the previous test should be evaluated.
    1019     public void testEqualityAssociativity5BP() throws JaxenException {
    1020         XPath xpath = new DOMXPath("(((2 = 3) = 1) = 4) = 1");
    1021         Boolean result = (Boolean) xpath.evaluate(doc);
    1022         assertFalse(result.booleanValue());
    1023     }
    1024
    1025     public void testMoreComplexArithmeticAssociativity() throws JaxenException {
    1026         XPath xpath = new DOMXPath("1+2+1-1+1");
    1027         Double result = (Double) xpath.evaluate(doc);
    1028         assertEquals(4, result.intValue());
    1029     }
    1030
    1031
    1032     public void testMostComplexArithmeticAssociativity() throws JaxenException {
    1033         XPath xpath = new DOMXPath("1+1+2+1-1+1");
    1034         Double result = (Double) xpath.evaluate(doc);
    1035         assertEquals(5, result.intValue());
    1036     }
    1037
    1038
    1039     public void testSimplerArithmeticAssociativity() throws JaxenException {
    1040         XPath xpath = new DOMXPath("1-1+1");
    1041         Double result = (Double) xpath.evaluate(doc);
    1042         assertEquals(1, result.intValue());
    1043     }
    1044
    1045
    1046     public void testNamespaceNodesComeBeforeAttributeNodesInDocumentOrder() throws JaxenException {
    1047
    1048         org.w3c.dom.Element root = doc.createElementNS("http://www.example.org", "pre:b");
    1049         doc.appendChild(root);
    1050         root.setAttribute("name", "value");
    1051         XPath xpath = new DOMXPath("/*/attribute::* | /*/namespace::node()");
    1052         List result = xpath.selectNodes(doc);
    1053         assertTrue(((org.w3c.dom.Node) result.get(0)).getNodeType() == Pattern.NAMESPACE_NODE);
    1054         assertTrue(((org.w3c.dom.Node) result.get(1)).getNodeType() == Pattern.NAMESPACE_NODE);
    1055         assertTrue(((org.w3c.dom.Node) result.get(2)).getNodeType() == Node.ATTRIBUTE_NODE);
    1056
    1057         // now flip the order of the statement and retest
    1058         xpath = new DOMXPath("/*/namespace::node() | /*/attribute::* ");
    1059         result = xpath.selectNodes(doc);
    1060         assertTrue(((org.w3c.dom.Node) result.get(0)).getNodeType() == Pattern.NAMESPACE_NODE);
    1061         assertTrue(((org.w3c.dom.Node) result.get(1)).getNodeType() == Pattern.NAMESPACE_NODE);
    1062         assertTrue(((org.w3c.dom.Node) result.get(2)).getNodeType() == Node.ATTRIBUTE_NODE);
    1063
    1064     }
    1065
    1066     public void testJaxen97() throws JaxenException {
    1067         // jaxen 97 claims this expression throws an exception.
    1068         new DOMXPath("/aaa:element/text()");
    1069     }
    1070
    1071     public void testAttributeNodesOnParentComeBeforeNamespaceNodesInChildInDocumentOrder()
    1072      throws JaxenException {
    1073
    1074         org.w3c.dom.Element root = doc.createElement("root");
    1075         doc.appendChild(root);
    1076         root.setAttribute("name", "value");
    1077         Element child = doc.createElementNS("http://www.example.org", "pre:child");
    1078         root.appendChild(child);
    1079
    1080         XPath xpath = new DOMXPath("/*/*/namespace::node() | //attribute::* ");
    1081         List result = xpath.selectNodes(doc);
    1082         assertEquals(3, result.size());
    1083         assertTrue(((org.w3c.dom.Node) result.get(0)).getNodeType() == Node.ATTRIBUTE_NODE);
    1084         assertTrue(((org.w3c.dom.Node) result.get(1)).getNodeType() == Pattern.NAMESPACE_NODE);
    1085
    1086     }
    1087
    1088     public void testJaxen107() throws JaxenException {
    1089
    1090         org.w3c.dom.Element a = doc.createElementNS("http://www.a.com/", "a:foo");
    1091         doc.appendChild(a);
    1092         Element b = doc.createElementNS("http://www.b.com/", "b:bar");
    1093         a.appendChild(b);
    1094
    1095         XPath xpath = new DOMXPath("/a:foo/b:bar/namespace::*/parent::*");
    1096         SimpleNamespaceContext context1 = new SimpleNamespaceContext();
    1097         context1.addNamespace("a", "http://www.a.com/");
    1098         context1.addNamespace("b", "http://www.b.com/");
    1099         xpath.setNamespaceContext(context1);
    1100         List result = xpath.selectNodes(doc);
    1101         assertEquals(1, result.size());
    1102         assertEquals(b, result.get(0));
    1103
    1104     }
    1105
    1106
    1107     public void testJaxen107FromFile() throws JaxenException, SAXException, IOException {
    1108
    1109         doc = builder.parse(new File("xml/testNamespaces.xml"));
    1110         XPath xpath = new DOMXPath("/Template/Application2/namespace::*/parent::*");
    1111         List result = xpath.selectNodes(doc);
    1112         assertEquals(1, result.size());
    1113
    1114     }
    1115
    1116     public void testSelectNodesReturnsANonNodeSet() throws JaxenException {
    1117         XPath xpath = new DOMXPath("1 + 2 + 3");
    1118         List result = xpath.selectNodes(doc);
    1119         assertEquals(1, result.size());
    1120     }
    1121
    1122     public void testNonElementContextNode() throws JaxenException {
    1123
    1124         org.w3c.dom.Element a = doc.createElementNS("http://www.a.com/", "a:foo");
    1125         doc.appendChild(a);
    1126         Text b = doc.createTextNode("ready");
    1127         a.appendChild(b);
    1128
    1129         XPath xpath = new DOMXPath("..");
    1130         List result = (List) xpath.evaluate(b);
    1131         assertEquals(1, result.size());
    1132         assertEquals(a, result.get(0));
    1133
    1134     }
    1135
    1136     public void testNonNodeContext() throws JaxenException {
    1137
    1138         org.w3c.dom.Element a = doc.createElementNS("http://www.a.com/", "a:foo");
    1139         doc.appendChild(a);
    1140         Text b = doc.createTextNode("ready");
    1141         a.appendChild(b);
    1142
    1143         XPath xpath = new DOMXPath("..");
    1144         try {
    1145             xpath.evaluate("String");
    1146             fail("Allowed String as context");
    1147         }
    1148         catch (ClassCastException ex) {
    1149             // success
    1150         }
    1151
    1152     }
    1153
    1154
    1155
    1156 }