[libjaxen-java] 18/49: Clone debian branch (r2561).

Emmanuel Bourg ebourg-guest at moszumanska.debian.org
Wed Oct 25 13:22:09 UTC 2017


This is an automated email from the git hooks/post-receive script.

ebourg-guest pushed a commit to branch master
in repository libjaxen-java.

commit fd217f5d9c1fe783090f793e4ccc23f04c09c2a6
Author: Marcus Better <marcus at better.se>
Date:   Mon Oct 9 16:58:40 2006 +0000

    Clone debian branch (r2561).
---
 libjaxen-java/LICENSE.txt                          |   33 +
 libjaxen-java/build.xml                            |  176 +
 libjaxen-java/debian/README.Debian                 |   14 +
 libjaxen-java/debian/ant.properties                |    1 +
 libjaxen-java/debian/changelog                     |   43 +
 libjaxen-java/debian/compat                        |    1 +
 libjaxen-java/debian/control                       |   21 +
 libjaxen-java/debian/copyright                     |   51 +
 libjaxen-java/debian/dirs                          |    1 +
 libjaxen-java/debian/doc-base                      |    9 +
 libjaxen-java/debian/docs                          |    1 +
 ...0_BuildXml_DisableXomDom4J_CompileAndTest.patch |   56 +
 .../debian/patches/01_RemoveXomDom4jTests.patch    |   38 +
 libjaxen-java/debian/rules                         |   64 +
 libjaxen-java/debian/svn-deblayout                 |    2 +
 libjaxen-java/debian/watch                         |    3 +
 libjaxen-java/maven.xml                            |   26 +
 libjaxen-java/project.properties                   |   77 +
 libjaxen-java/project.xml                          |  339 +
 libjaxen-java/src/conf/MANIFEST.MF                 |    9 +
 libjaxen-java/src/doc/default.css                  |  124 +
 libjaxen-java/src/doc/download.xml                 |   86 +
 libjaxen-java/src/doc/faq.xml                      |  117 +
 libjaxen-java/src/doc/index.xml                    |   73 +
 libjaxen-java/src/doc/project.xml                  |   41 +
 libjaxen-java/src/doc/status.xml                   |  145 +
 libjaxen-java/src/doc/style/document.xsl           |  202 +
 libjaxen-java/src/doc/style/images/ball.gif        |  Bin 0 -> 377 bytes
 libjaxen-java/src/doc/style/images/blank.gif       |  Bin 0 -> 807 bytes
 libjaxen-java/src/doc/style/images/blueball.gif    |  Bin 0 -> 377 bytes
 libjaxen-java/src/doc/style/images/jars.gif        |  Bin 0 -> 2159 bytes
 libjaxen-java/src/doc/style/images/logo.gif        |  Bin 0 -> 1508 bytes
 libjaxen-java/src/doc/style/javadoc.css            |   27 +
 libjaxen-java/src/doc/style/style.xsl              |  322 +
 .../src/java/main/org/jaxen/BaseXPath.java         |  708 ++
 libjaxen-java/src/java/main/org/jaxen/Context.java |  274 +
 .../src/java/main/org/jaxen/ContextSupport.java    |  250 +
 .../src/java/main/org/jaxen/DefaultNavigator.java  |  299 +
 .../src/java/main/org/jaxen/Function.java          |   87 +
 .../java/main/org/jaxen/FunctionCallException.java |  111 +
 .../src/java/main/org/jaxen/FunctionContext.java   |   92 +
 .../src/java/main/org/jaxen/JaxenConstants.java    |   76 +
 .../src/java/main/org/jaxen/JaxenException.java    |  111 +
 .../src/java/main/org/jaxen/JaxenHandler.java      |  616 ++
 .../java/main/org/jaxen/JaxenRuntimeException.java |  146 +
 .../java/main/org/jaxen/NamedAccessNavigator.java  |   99 +
 .../src/java/main/org/jaxen/NamespaceContext.java  |   99 +
 .../src/java/main/org/jaxen/Navigator.java         |  549 ++
 .../src/java/main/org/jaxen/QualifiedName.java     |  104 +
 .../java/main/org/jaxen/SimpleFunctionContext.java |  130 +
 .../main/org/jaxen/SimpleNamespaceContext.java     |  149 +
 .../java/main/org/jaxen/SimpleVariableContext.java |  144 +
 .../java/main/org/jaxen/UnresolvableException.java |   74 +
 .../main/org/jaxen/UnsupportedAxisException.java   |   77 +
 .../src/java/main/org/jaxen/VariableContext.java   |  114 +
 libjaxen-java/src/java/main/org/jaxen/XPath.java   |  399 ++
 .../java/main/org/jaxen/XPathFunctionContext.java  |  303 +
 .../java/main/org/jaxen/XPathSyntaxException.java  |  168 +
 .../src/java/main/org/jaxen/dom/DOMXPath.java      |   90 +
 .../java/main/org/jaxen/dom/DocumentNavigator.java | 1064 +++
 .../src/java/main/org/jaxen/dom/NamespaceNode.java |  867 +++
 .../src/java/main/org/jaxen/dom/package.html       |   13 +
 .../main/org/jaxen/dom4j/DocumentNavigator.java    |  501 ++
 .../src/java/main/org/jaxen/dom4j/Dom4jXPath.java  |   94 +
 .../src/java/main/org/jaxen/dom4j/package.html     |   13 +
 .../src/java/main/org/jaxen/expr/AdditiveExpr.java |   53 +
 .../src/java/main/org/jaxen/expr/AllNodeStep.java  |   51 +
 .../src/java/main/org/jaxen/expr/BinaryExpr.java   |   56 +
 .../java/main/org/jaxen/expr/CommentNodeStep.java  |   51 +
 .../jaxen/expr/DefaultAbsoluteLocationPath.java    |  121 +
 .../main/org/jaxen/expr/DefaultAdditiveExpr.java   |   64 +
 .../main/org/jaxen/expr/DefaultAllNodeStep.java    |   91 +
 .../java/main/org/jaxen/expr/DefaultAndExpr.java   |  106 +
 .../java/main/org/jaxen/expr/DefaultArithExpr.java |   66 +
 .../main/org/jaxen/expr/DefaultBinaryExpr.java     |  103 +
 .../org/jaxen/expr/DefaultCommentNodeStep.java     |   92 +
 .../java/main/org/jaxen/expr/DefaultDivExpr.java   |   88 +
 .../main/org/jaxen/expr/DefaultEqualityExpr.java   |  155 +
 .../main/org/jaxen/expr/DefaultEqualsExpr.java     |   93 +
 .../src/java/main/org/jaxen/expr/DefaultExpr.java  |   93 +
 .../main/org/jaxen/expr/DefaultFilterExpr.java     |  183 +
 .../org/jaxen/expr/DefaultFunctionCallExpr.java    |  203 +
 .../jaxen/expr/DefaultGreaterThanEqualExpr.java    |   74 +
 .../org/jaxen/expr/DefaultGreaterThanExpr.java     |   76 +
 .../org/jaxen/expr/DefaultLessThanEqualExpr.java   |   75 +
 .../main/org/jaxen/expr/DefaultLessThanExpr.java   |   74 +
 .../main/org/jaxen/expr/DefaultLiteralExpr.java    |   91 +
 .../main/org/jaxen/expr/DefaultLocationPath.java   |  164 +
 .../main/org/jaxen/expr/DefaultLogicalExpr.java    |   60 +
 .../java/main/org/jaxen/expr/DefaultMinusExpr.java |   90 +
 .../java/main/org/jaxen/expr/DefaultModExpr.java   |   88 +
 .../org/jaxen/expr/DefaultMultiplicativeExpr.java  |   66 +
 .../main/org/jaxen/expr/DefaultMultiplyExpr.java   |   89 +
 .../java/main/org/jaxen/expr/DefaultNameStep.java  |  413 ++
 .../main/org/jaxen/expr/DefaultNotEqualsExpr.java  |   94 +
 .../main/org/jaxen/expr/DefaultNumberExpr.java     |   92 +
 .../java/main/org/jaxen/expr/DefaultOrExpr.java    |  108 +
 .../java/main/org/jaxen/expr/DefaultPathExpr.java  |  151 +
 .../java/main/org/jaxen/expr/DefaultPlusExpr.java  |   88 +
 .../java/main/org/jaxen/expr/DefaultPredicate.java |  101 +
 .../expr/DefaultProcessingInstructionNodeStep.java |  111 +
 .../main/org/jaxen/expr/DefaultRelationalExpr.java |  142 +
 .../jaxen/expr/DefaultRelativeLocationPath.java    |   73 +
 .../src/java/main/org/jaxen/expr/DefaultStep.java  |  171 +
 .../main/org/jaxen/expr/DefaultTextNodeStep.java   |   89 +
 .../java/main/org/jaxen/expr/DefaultTruthExpr.java |  119 +
 .../java/main/org/jaxen/expr/DefaultUnaryExpr.java |  102 +
 .../java/main/org/jaxen/expr/DefaultUnionExpr.java |  131 +
 .../jaxen/expr/DefaultVariableReferenceExpr.java   |  112 +
 .../java/main/org/jaxen/expr/DefaultXPathExpr.java |  106 +
 .../main/org/jaxen/expr/DefaultXPathFactory.java   |  376 ++
 .../src/java/main/org/jaxen/expr/EqualityExpr.java |   50 +
 .../src/java/main/org/jaxen/expr/Expr.java         |   61 +
 .../src/java/main/org/jaxen/expr/FilterExpr.java   |   66 +
 .../java/main/org/jaxen/expr/FunctionCallExpr.java |   59 +
 .../src/java/main/org/jaxen/expr/IdentitySet.java  |   85 +
 .../src/java/main/org/jaxen/expr/LiteralExpr.java  |   55 +
 .../src/java/main/org/jaxen/expr/LocationPath.java |   61 +
 .../src/java/main/org/jaxen/expr/LogicalExpr.java  |   51 +
 .../main/org/jaxen/expr/MultiplicativeExpr.java    |   51 +
 .../src/java/main/org/jaxen/expr/NameStep.java     |   54 +
 .../java/main/org/jaxen/expr/NodeComparator.java   |  157 +
 .../src/java/main/org/jaxen/expr/NumberExpr.java   |   53 +
 .../src/java/main/org/jaxen/expr/PathExpr.java     |   58 +
 .../src/java/main/org/jaxen/expr/Predicate.java    |   67 +
 .../src/java/main/org/jaxen/expr/PredicateSet.java |  234 +
 .../src/java/main/org/jaxen/expr/Predicated.java   |   60 +
 .../jaxen/expr/ProcessingInstructionNodeStep.java  |   52 +
 .../java/main/org/jaxen/expr/RelationalExpr.java   |   50 +
 .../src/java/main/org/jaxen/expr/Step.java         |  101 +
 .../src/java/main/org/jaxen/expr/TextNodeStep.java |   51 +
 .../src/java/main/org/jaxen/expr/UnaryExpr.java    |   55 +
 .../src/java/main/org/jaxen/expr/UnionExpr.java    |   54 +
 .../main/org/jaxen/expr/VariableReferenceExpr.java |   56 +
 .../src/java/main/org/jaxen/expr/Visitable.java    |   50 +
 .../src/java/main/org/jaxen/expr/Visitor.java      |   71 +
 .../java/main/org/jaxen/expr/VisitorSupport.java   |   89 +
 .../src/java/main/org/jaxen/expr/XPathExpr.java    |   67 +
 .../src/java/main/org/jaxen/expr/XPathFactory.java |  121 +
 .../org/jaxen/expr/iter/IterableAncestorAxis.java  |   75 +
 .../expr/iter/IterableAncestorOrSelfAxis.java      |   73 +
 .../org/jaxen/expr/iter/IterableAttributeAxis.java |  109 +
 .../main/org/jaxen/expr/iter/IterableAxis.java     |  112 +
 .../org/jaxen/expr/iter/IterableChildAxis.java     |  111 +
 .../jaxen/expr/iter/IterableDescendantAxis.java    |   73 +
 .../expr/iter/IterableDescendantOrSelfAxis.java    |   73 +
 .../org/jaxen/expr/iter/IterableFollowingAxis.java |   73 +
 .../expr/iter/IterableFollowingSiblingAxis.java    |   73 +
 .../org/jaxen/expr/iter/IterableNamespaceAxis.java |   73 +
 .../org/jaxen/expr/iter/IterableParentAxis.java    |   73 +
 .../org/jaxen/expr/iter/IterablePrecedingAxis.java |   73 +
 .../expr/iter/IterablePrecedingSiblingAxis.java    |   73 +
 .../main/org/jaxen/expr/iter/IterableSelfAxis.java |   73 +
 .../src/java/main/org/jaxen/expr/iter/package.html |   13 +
 .../src/java/main/org/jaxen/expr/package.html      |   14 +
 .../main/org/jaxen/function/BooleanFunction.java   |  200 +
 .../main/org/jaxen/function/CeilingFunction.java   |  131 +
 .../main/org/jaxen/function/ConcatFunction.java    |  127 +
 .../main/org/jaxen/function/ContainsFunction.java  |  136 +
 .../main/org/jaxen/function/CountFunction.java     |  117 +
 .../main/org/jaxen/function/FalseFunction.java     |  104 +
 .../main/org/jaxen/function/FloorFunction.java     |  129 +
 .../java/main/org/jaxen/function/IdFunction.java   |  159 +
 .../java/main/org/jaxen/function/LangFunction.java |  194 +
 .../java/main/org/jaxen/function/LastFunction.java |  114 +
 .../main/org/jaxen/function/LocalNameFunction.java |  170 +
 .../java/main/org/jaxen/function/NameFunction.java |  175 +
 .../org/jaxen/function/NamespaceUriFunction.java   |  188 +
 .../org/jaxen/function/NormalizeSpaceFunction.java |  174 +
 .../java/main/org/jaxen/function/NotFunction.java  |  122 +
 .../main/org/jaxen/function/NumberFunction.java    |  240 +
 .../main/org/jaxen/function/PositionFunction.java  |  115 +
 .../main/org/jaxen/function/RoundFunction.java     |  133 +
 .../org/jaxen/function/StartsWithFunction.java     |  136 +
 .../main/org/jaxen/function/StringFunction.java    |  355 +
 .../org/jaxen/function/StringLengthFunction.java   |  156 +
 .../org/jaxen/function/SubstringAfterFunction.java |  145 +
 .../jaxen/function/SubstringBeforeFunction.java    |  146 +
 .../main/org/jaxen/function/SubstringFunction.java |  250 +
 .../java/main/org/jaxen/function/SumFunction.java  |  137 +
 .../main/org/jaxen/function/TranslateFunction.java |  253 +
 .../java/main/org/jaxen/function/TrueFunction.java |  104 +
 .../org/jaxen/function/ext/EndsWithFunction.java   |   94 +
 .../org/jaxen/function/ext/EvaluateFunction.java   |  107 +
 .../jaxen/function/ext/LocaleFunctionSupport.java  |  169 +
 .../main/org/jaxen/function/ext/LowerFunction.java |  117 +
 .../jaxen/function/ext/MatrixConcatFunction.java   |  165 +
 .../main/org/jaxen/function/ext/UpperFunction.java |  115 +
 .../java/main/org/jaxen/function/ext/package.html  |   13 +
 .../src/java/main/org/jaxen/function/package.html  |   13 +
 .../org/jaxen/function/xslt/DocumentFunction.java  |   89 +
 .../java/main/org/jaxen/function/xslt/package.html |   13 +
 .../main/org/jaxen/javabean/DocumentNavigator.java |  374 ++
 .../src/java/main/org/jaxen/javabean/Element.java  |   32 +
 .../main/org/jaxen/javabean/ElementIterator.java   |   37 +
 .../main/org/jaxen/javabean/JavaBeanXPath.java     |  158 +
 .../src/java/main/org/jaxen/javabean/package.html  |   13 +
 .../main/org/jaxen/jdom/DocumentNavigator.java     |  583 ++
 .../src/java/main/org/jaxen/jdom/JDOMXPath.java    |   93 +
 .../java/main/org/jaxen/jdom/XPathNamespace.java   |  112 +
 .../src/java/main/org/jaxen/jdom/package.html      |   13 +
 .../src/java/main/org/jaxen/overview.html          |   74 +
 libjaxen-java/src/java/main/org/jaxen/package.html |   14 +
 .../src/java/main/org/jaxen/pantry/Test.java       |   48 +
 .../main/org/jaxen/pattern/AnyChildNodeTest.java   |   94 +
 .../java/main/org/jaxen/pattern/AnyNodeTest.java   |   89 +
 .../org/jaxen/pattern/LocationPathPattern.java     |  319 +
 .../src/java/main/org/jaxen/pattern/NameTest.java  |  129 +
 .../java/main/org/jaxen/pattern/NamespaceTest.java |  132 +
 .../java/main/org/jaxen/pattern/NoNodeTest.java    |   91 +
 .../src/java/main/org/jaxen/pattern/NodeTest.java  |   59 +
 .../java/main/org/jaxen/pattern/NodeTypeTest.java  |  133 +
 .../src/java/main/org/jaxen/pattern/Pattern.java   |  176 +
 .../main/org/jaxen/pattern/PatternHandler.java     |  351 +
 .../java/main/org/jaxen/pattern/PatternParser.java |  300 +
 .../java/main/org/jaxen/pattern/TextNodeTest.java  |   86 +
 .../java/main/org/jaxen/pattern/UnionPattern.java  |  164 +
 .../src/java/main/org/jaxen/pattern/package.html   |    9 +
 .../src/java/main/org/jaxen/saxpath/Axis.java      |  247 +
 .../src/java/main/org/jaxen/saxpath/Operator.java  |  135 +
 .../main/org/jaxen/saxpath/SAXPathEventSource.java |   76 +
 .../main/org/jaxen/saxpath/SAXPathException.java   |  172 +
 .../java/main/org/jaxen/saxpath/XPathHandler.java  |  319 +
 .../java/main/org/jaxen/saxpath/XPathReader.java   |   69 +
 .../org/jaxen/saxpath/XPathSyntaxException.java    |  160 +
 .../java/main/org/jaxen/saxpath/base/Token.java    |  117 +
 .../main/org/jaxen/saxpath/base/TokenTypes.java    |  183 +
 .../java/main/org/jaxen/saxpath/base/Verifier.java |  508 ++
 .../main/org/jaxen/saxpath/base/XPathLexer.java    |  941 +++
 .../main/org/jaxen/saxpath/base/XPathReader.java   | 1100 ++++
 .../java/main/org/jaxen/saxpath/base/package.html  |   14 +
 .../jaxen/saxpath/helpers/DefaultXPathHandler.java |  254 +
 .../jaxen/saxpath/helpers/XPathReaderFactory.java  |  170 +
 .../main/org/jaxen/saxpath/helpers/package.html    |   13 +
 .../src/java/main/org/jaxen/saxpath/package.html   |   14 +
 .../main/org/jaxen/util/AncestorAxisIterator.java  |   64 +
 .../org/jaxen/util/AncestorOrSelfAxisIterator.java |   97 +
 .../org/jaxen/util/DescendantAxisIterator.java     |  116 +
 .../jaxen/util/DescendantOrSelfAxisIterator.java   |   60 +
 .../main/org/jaxen/util/FollowingAxisIterator.java |  153 +
 .../jaxen/util/FollowingSiblingAxisIterator.java   |  108 +
 .../java/main/org/jaxen/util/LinkedIterator.java   |  114 +
 .../main/org/jaxen/util/PrecedingAxisIterator.java |  178 +
 .../jaxen/util/PrecedingSiblingAxisIterator.java   |  138 +
 .../java/main/org/jaxen/util/SelfAxisIterator.java |   60 +
 .../main/org/jaxen/util/SingleObjectIterator.java  |   90 +
 .../java/main/org/jaxen/util/SingletonList.java    |   77 +
 .../java/main/org/jaxen/util/StackedIterator.java  |  172 +
 .../java/main/org/jaxen/util/XPath2XMLVisitor.java |  237 +
 .../src/java/main/org/jaxen/util/package.html      |   13 +
 .../java/main/org/jaxen/xom/DocumentNavigator.java |  408 ++
 .../src/java/main/org/jaxen/xom/XOMXPath.java      |   90 +
 .../src/java/main/org/w3c/dom/UserDataHandler.java |   23 +
 libjaxen-java/src/java/samples/DOMDemo.java        |  113 +
 libjaxen-java/src/java/samples/Dom4jDemo.java      |  117 +
 libjaxen-java/src/java/samples/JDOMDemo.java       |  112 +
 .../java/test/org/jaxen/test/AddNamespaceTest.java |   80 +
 .../jaxen/test/AncestorOrSelfAxisIteratorTest.java |  103 +
 .../java/test/org/jaxen/test/ArithmeticTest.java   |  113 +
 .../src/java/test/org/jaxen/test/AxisTest.java     |   76 +
 .../src/java/test/org/jaxen/test/BaseTests.java    |   74 +
 .../java/test/org/jaxen/test/BaseXPathTest.java    | 1163 ++++
 .../src/java/test/org/jaxen/test/BooleanTest.java  |  211 +
 .../src/java/test/org/jaxen/test/CeilingTest.java  |  141 +
 .../src/java/test/org/jaxen/test/ConcatTest.java   |   99 +
 .../org/jaxen/test/ConformanceXPathHandler.java    |  327 +
 .../src/java/test/org/jaxen/test/ContainsTest.java |  172 +
 .../src/java/test/org/jaxen/test/ContextTest.java  |  173 +
 .../src/java/test/org/jaxen/test/CoreTests.java    |   95 +
 .../src/java/test/org/jaxen/test/CountTest.java    |  146 +
 .../test/org/jaxen/test/DOM3NamespaceTest.java     |  130 +
 .../test/org/jaxen/test/DOM4JNavigatorTest.java    |  111 +
 .../java/test/org/jaxen/test/DOM4JPerformance.java |   68 +
 .../src/java/test/org/jaxen/test/DOM4JTests.java   |   75 +
 .../java/test/org/jaxen/test/DOM4JXPathTest.java   |  187 +
 .../java/test/org/jaxen/test/DOMNavigatorTest.java |  163 +
 .../src/java/test/org/jaxen/test/DOMTests.java     |   78 +
 .../src/java/test/org/jaxen/test/DOMXPathTest.java |  297 +
 .../test/org/jaxen/test/DefaultXPathExprTest.java  |  128 +
 .../org/jaxen/test/DescendantAxisIteratorTest.java |  104 +
 .../src/java/test/org/jaxen/test/EqualsTest.java   |  118 +
 .../src/java/test/org/jaxen/test/ExprTests.java    |   77 +
 .../test/org/jaxen/test/ExtensionFunctionTest.java |  143 +
 .../src/java/test/org/jaxen/test/FalseTest.java    |  105 +
 .../src/java/test/org/jaxen/test/FloorTest.java    |  155 +
 .../org/jaxen/test/FollowingAxisIteratorTest.java  |  109 +
 .../test/FollowingSiblingAxisIteratorTest.java     |  109 +
 .../org/jaxen/test/FunctionCallExceptionTest.java  |   86 +
 .../test/org/jaxen/test/FunctionContextTest.java   |  158 +
 .../java/test/org/jaxen/test/FunctionTests.java    |  100 +
 .../src/java/test/org/jaxen/test/HelpersTests.java |   73 +
 .../src/java/test/org/jaxen/test/IdTest.java       |  212 +
 .../test/org/jaxen/test/JDOMNavigatorTest.java     |   95 +
 .../java/test/org/jaxen/test/JDOMPerformance.java  |   68 +
 .../src/java/test/org/jaxen/test/JDOMTests.java    |   74 +
 .../java/test/org/jaxen/test/JDOMXPathTest.java    |  207 +
 .../test/org/jaxen/test/JavaBeanNavigatorTest.java |   42 +
 .../java/test/org/jaxen/test/JavaBeanTests.java    |   73 +
 .../test/org/jaxen/test/JaxenExceptionTest.java    |   87 +
 .../java/test/org/jaxen/test/JaxenHandlerTest.java |  169 +
 .../org/jaxen/test/JaxenRuntimeExceptionTest.java  |   90 +
 .../src/java/test/org/jaxen/test/JaxenTests.java   |   86 +
 .../src/java/test/org/jaxen/test/LangTest.java     |  347 +
 .../src/java/test/org/jaxen/test/LastTest.java     |  142 +
 .../java/test/org/jaxen/test/LocalNameTest.java    |  191 +
 .../java/test/org/jaxen/test/MockXPathReader.java  |   72 +
 .../src/java/test/org/jaxen/test/ModTest.java      |   90 +
 .../src/java/test/org/jaxen/test/NameTest.java     |  184 +
 .../java/test/org/jaxen/test/NamespaceTest.java    |  194 +
 .../java/test/org/jaxen/test/NamespaceURITest.java |  186 +
 .../test/org/jaxen/test/NormalizeSpaceTest.java    |  125 +
 .../src/java/test/org/jaxen/test/NotTest.java      |  169 +
 .../src/java/test/org/jaxen/test/NumberTest.java   |  155 +
 .../test/org/jaxen/test/PatternHandlerTest.java    |  122 +
 .../src/java/test/org/jaxen/test/PatternTests.java |   73 +
 .../src/java/test/org/jaxen/test/Person.java       |   44 +
 .../src/java/test/org/jaxen/test/PositionTest.java |   98 +
 .../org/jaxen/test/PrecedingAxisIteratorTest.java  |  109 +
 .../test/PrecedingSiblingAxisIteratorTest.java     |  109 +
 .../src/java/test/org/jaxen/test/PriorityTest.java |  147 +
 .../src/java/test/org/jaxen/test/RoundTest.java    |  140 +
 .../test/org/jaxen/test/SAXPathExceptionTest.java  |   85 +
 .../src/java/test/org/jaxen/test/SAXPathTests.java |   74 +
 .../org/jaxen/test/SimpleNamespaceContextTest.java |  161 +
 .../org/jaxen/test/SimpleVariableContextTest.java  |  125 +
 .../org/jaxen/test/SingleObjectIteratorTest.java   |   83 +
 .../test/org/jaxen/test/SingletonListTest.java     |   69 +
 .../java/test/org/jaxen/test/StartsWithTest.java   |  172 +
 .../java/test/org/jaxen/test/StringLengthTest.java |  153 +
 .../src/java/test/org/jaxen/test/StringTest.java   |  195 +
 .../test/org/jaxen/test/SubstringAfterTest.java    |  180 +
 .../test/org/jaxen/test/SubstringBeforeTest.java   |  180 +
 .../java/test/org/jaxen/test/SubstringTest.java    |  263 +
 .../src/java/test/org/jaxen/test/SumTest.java      |  112 +
 .../test/org/jaxen/test/TranslateFunctionTest.java |  197 +
 .../src/java/test/org/jaxen/test/TrueTest.java     |   98 +
 .../org/jaxen/test/UnresolvableExceptionTest.java  |  109 +
 .../jaxen/test/UnsupportedAxisExceptionTest.java   |   74 +
 .../src/java/test/org/jaxen/test/UtilTests.java    |   80 +
 .../test/org/jaxen/test/VariableContextTest.java   |  115 +
 .../java/test/org/jaxen/test/XOMNavigatorTest.java |   73 +
 .../java/test/org/jaxen/test/XOMPerformance.java   |   67 +
 .../src/java/test/org/jaxen/test/XOMTests.java     |   74 +
 .../src/java/test/org/jaxen/test/XOMXPathTest.java |  106 +
 .../org/jaxen/test/XPathReaderFactoryTest.java     |  150 +
 .../java/test/org/jaxen/test/XPathReaderTest.java  |  472 ++
 .../org/jaxen/test/XPathSyntaxExceptionTest.java   |  106 +
 .../java/test/org/jaxen/test/XPathTestBase.java    | 1722 +++++
 libjaxen-java/src/javadoc/j2se/package-list        |   76 +
 libjaxen-java/src/javadoc/jaxp/package-list        |    9 +
 libjaxen-java/src/latex/intro-slides.tex           | 2676 ++++++++
 libjaxen-java/xml/axis.xml                         |   25 +
 libjaxen-java/xml/basic.xml                        |   11 +
 libjaxen-java/xml/basicupdate.xml                  |   47 +
 libjaxen-java/xml/cdata.xml                        |    1 +
 libjaxen-java/xml/contents.xml                     |   70 +
 libjaxen-java/xml/defaultNamespace.xml             |    6 +
 libjaxen-java/xml/evaluate.xml                     |   28 +
 libjaxen-java/xml/fibo.xml                         |   29 +
 libjaxen-java/xml/id.xml                           |   21 +
 libjaxen-java/xml/jaxen24.xml                      |    2 +
 libjaxen-java/xml/jaxen3.xml                       |   15 +
 libjaxen-java/xml/lang.xml                         |   11 +
 libjaxen-java/xml/message.xml                      |   27 +
 libjaxen-java/xml/moreover.xml                     |  244 +
 libjaxen-java/xml/much_ado.xml                     | 6850 ++++++++++++++++++++
 libjaxen-java/xml/namespaces.xml                   |   18 +
 libjaxen-java/xml/nitf.xml                         |   67 +
 libjaxen-java/xml/numbers.xml                      |   18 +
 libjaxen-java/xml/pi.xml                           |   13 +
 libjaxen-java/xml/pi2.xml                          |    6 +
 libjaxen-java/xml/simple.xml                       |    2 +
 libjaxen-java/xml/simplevariablecontext.ser        |  Bin 0 -> 428 bytes
 libjaxen-java/xml/test/tests.xml                   |  685 ++
 libjaxen-java/xml/test/tests.xsl                   |  369 ++
 libjaxen-java/xml/testNamespaces.xml               |   22 +
 libjaxen-java/xml/text.xml                         |   10 +
 libjaxen-java/xml/underscore.xml                   |    6 +
 libjaxen-java/xml/web.xml                          |   42 +
 libjaxen-java/xml/web2.xml                         |    7 +
 380 files changed, 60496 insertions(+)

diff --git a/libjaxen-java/LICENSE.txt b/libjaxen-java/LICENSE.txt
new file mode 100644
index 0000000..a0ca747
--- /dev/null
+++ b/libjaxen-java/LICENSE.txt
@@ -0,0 +1,33 @@
+/*
+ $Id: LICENSE.txt,v 1.5 2006/02/05 21:49:04 elharo Exp $
+
+ Copyright 2003-2006 The Werken Company. All Rights Reserved.
+ 
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+  * Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+
+  * Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+
+  * Neither the name of the Jaxen Project nor the names of its
+    contributors may be used to endorse or promote products derived 
+    from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ */
diff --git a/libjaxen-java/build.xml b/libjaxen-java/build.xml
new file mode 100644
index 0000000..5d3cf05
--- /dev/null
+++ b/libjaxen-java/build.xml
@@ -0,0 +1,176 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--build.xml generated by maven from project.xml version 1.1-beta-11
+  on date October 8 2006, time 1741-->
+
+<project default="jar" name="jaxen" basedir=".">
+  <property name="defaulttargetdir" value="target">
+  </property>
+  <property name="libdir" value="target/lib">
+  </property>
+  <property name="classesdir" value="target/classes">
+  </property>
+  <property name="testclassesdir" value="target/test-classes">
+  </property>
+  <property name="testclassesdir" value="target/test-classes">
+  </property>
+  <property name="testreportdir" value="target/test-reports">
+  </property>
+  <property name="distdir" value="dist">
+  </property>
+  <property name="javadocdir" value="dist/docs/api">
+  </property>
+  <property name="final.name" value="jaxen-1.1-beta-11">
+  </property>
+  <path id="build.classpath">
+    <fileset dir="${libdir}">
+      <include name="**/*.jar">
+      </include>
+    </fileset>
+  </path>
+  <target name="init" description="o Initializes some properties">
+    <mkdir dir="${libdir}">
+    </mkdir>
+    <condition property="noget">
+      <equals arg2="only" arg1="${build.sysclasspath}">
+      </equals>
+    </condition>
+    <!--Test if JUNIT is present in ANT classpath-->
+
+    <available property="Junit.present" classname="junit.framework.Test">
+    </available>
+  </target>
+  <target name="compile" description="o Compile the code" depends="get-deps">
+    <mkdir dir="${classesdir}">
+    </mkdir>
+    <javac destdir="${classesdir}" deprecation="true" debug="true" optimize="false" excludes="**/package.html">
+      <exclude name="org/jaxen/dom4j/*"/>
+      <exclude name="org/jaxen/xom/*"/>
+      <src>
+        <pathelement location="src/java/main">
+        </pathelement>
+      </src>
+      <classpath refid="build.classpath">
+      </classpath>
+    </javac>
+  </target>
+  <target name="jar" description="o Create the jar" depends="compile,test">
+    <jar jarfile="${defaulttargetdir}/${final.name}.jar" excludes="**/package.html" basedir="${classesdir}">
+    </jar>
+  </target>
+  <target name="clean" description="o Clean up the generated directories">
+    <delete dir="${defaulttargetdir}">
+    </delete>
+    <delete dir="${distdir}">
+    </delete>
+  </target>
+  <target name="dist" description="o Create a distribution" depends="jar, javadoc">
+    <mkdir dir="dist">
+    </mkdir>
+    <copy todir="dist">
+      <fileset dir="${defaulttargetdir}" includes="*.jar">
+      </fileset>
+      <fileset dir="${basedir}" includes="LICENSE*, README*">
+      </fileset>
+    </copy>
+  </target>
+  <target name="test" description="o Run the test cases" if="test.failure" depends="internal-test">
+    <fail message="There were test failures.">
+    </fail>
+  </target>
+  <target name="internal-test" if="Junit.present" depends="junit-present,compile-tests">
+    <mkdir dir="${testreportdir}">
+    </mkdir>
+    <junit dir="./" failureproperty="test.failure" printSummary="yes" fork="true" haltonerror="true">
+      <sysproperty key="basedir" value=".">
+      </sysproperty>
+      <formatter type="xml">
+      </formatter>
+      <formatter usefile="false" type="plain">
+      </formatter>
+      <classpath>
+        <pathelement location="/usr/share/java/jdom1.jar"/>
+        <path refid="build.classpath">
+        </path>
+        <pathelement path="${testclassesdir}">
+        </pathelement>
+        <pathelement path="${classesdir}">
+        </pathelement>
+      </classpath>
+      <batchtest todir="${testreportdir}">
+        <fileset dir="src/java/test">
+          <include name="**/*Test.java"/>
+          <exclude name="org/jaxen/test/DOM4J*.java"/>
+          <exclude name="org/jaxen/test/XOM*.java"/>
+        </fileset>
+      </batchtest>
+    </junit>
+  </target>
+  <target name="junit-present" unless="Junit.present" depends="init">
+    <echo>================================= WARNING ================================</echo>
+    <echo>Junit isn't present in your ${ANT_HOME}/lib directory. Tests not executed.</echo>
+    <echo>==========================================================================</echo>
+  </target>
+  <target name="compile-tests" if="Junit.present" depends="junit-present,compile">
+    <mkdir dir="${testclassesdir}">
+    </mkdir>
+    <javac destdir="${testclassesdir}" deprecation="true" debug="true" optimize="false" excludes="**/package.html">
+      <exclude name="org/jaxen/test/DOM4J*.java"/>
+      <exclude name="org/jaxen/test/XOM*.java"/>
+      <src>
+        <pathelement location="src/java/test">
+        </pathelement>
+      </src>
+      <classpath>
+        <path refid="build.classpath">
+        </path>
+        <pathelement path="${classesdir}">
+        </pathelement>
+      </classpath>
+    </javac>
+  </target>
+  <target name="javadoc" description="o Generate javadoc" depends="get-deps">
+    <mkdir dir="${javadocdir}">
+    </mkdir>
+    <tstamp>
+      <format pattern="2001-yyyy" property="year">
+      </format>
+    </tstamp>
+    <property name="copyright" value="Copyright &copy; 2001-2006 Codehaus. All Rights Reserved.">
+    </property>
+    <property name="title" value="jaxen 1.1-beta-11 API">
+    </property>
+    <javadoc use="true" private="true" destdir="${javadocdir}" author="true" version="true" sourcepath="src/java/main" packagenames="org.jaxen.*">
+      <classpath>
+        <path refid="build.classpath">
+        </path>
+      </classpath>
+    </javadoc>
+  </target>
+  <target name="get-deps" unless="noget" depends="init">
+    <!--Proxy settings works only with a JDK 1.2 and higher.-->
+
+    <setproxy>
+    </setproxy>
+    <get dest="${libdir}/dom4j-1.6.1.jar" usetimestamp="true" ignoreerrors="true" src="http://www.ibiblio.org/maven//dom4j/jars/dom4j-1.6.1.jar">
+    </get>
+    <get dest="${libdir}/jdom-1.0.jar" usetimestamp="true" ignoreerrors="true" src="http://www.ibiblio.org/maven//jdom/jars/jdom-1.0.jar">
+    </get>
+    <get dest="${libdir}/xml-apis-1.3.02.jar" usetimestamp="true" ignoreerrors="true" src="http://www.ibiblio.org/maven//xml-apis/jars/xml-apis-1.3.02.jar">
+    </get>
+    <get dest="${libdir}/xercesImpl-2.6.2.jar" usetimestamp="true" ignoreerrors="true" src="http://www.ibiblio.org/maven//xerces/jars/xercesImpl-2.6.2.jar">
+    </get>
+    <get dest="${libdir}/xom-1.0b3.jar" usetimestamp="true" ignoreerrors="true" src="http://www.ibiblio.org/maven//xom/jars/xom-1.0b3.jar">
+    </get>
+    <get dest="${libdir}/maven-cobertura-plugin-1.1.1.jar" usetimestamp="true" ignoreerrors="true" src="http://www.ibiblio.org/maven//maven-plugins/plugins/maven-cobertura-plugin-1.1.1.jar">
+    </get>
+    <get dest="${libdir}/maven-findbugs-plugin-0.9.2.jar" usetimestamp="true" ignoreerrors="true" src="http://www.ibiblio.org/maven//maven-plugins/plugins/maven-findbugs-plugin-0.9.2.jar">
+    </get>
+  </target>
+  <target name="install-maven">
+    <get dest="${user.home}/maven-install-latest.jar" usetimestamp="true" src="${repo}/maven/maven-install-latest.jar">
+    </get>
+    <unjar dest="${maven.home}" src="${user.home}/maven-install-latest.jar">
+    </unjar>
+  </target>
+</project>
\ No newline at end of file
diff --git a/libjaxen-java/debian/README.Debian b/libjaxen-java/debian/README.Debian
new file mode 100644
index 0000000..3b4100c
--- /dev/null
+++ b/libjaxen-java/debian/README.Debian
@@ -0,0 +1,14 @@
+libjaxen-java for Debian
+------------------------
+
+Jaxen in Debian supports JDOM, DOM out of the box.
+
+Due to circular dependencies which need to be solved upstream we split
+the XOM and DOM4J XPath support parts out to their respective packages
+in debian (currently there is only a dom4j package).
+
+As one needs the dom4j jar is one wants to use jaxen with dom4j there is
+no difference from a user point of view if some classes are in the dom4j jar
+instead of the jaxen jar.
+
+ -- Arnaud Vandyck <avdyk at debian.org>, Fri Apr 15 16:31:06 2005
diff --git a/libjaxen-java/debian/ant.properties b/libjaxen-java/debian/ant.properties
new file mode 100644
index 0000000..f425dac
--- /dev/null
+++ b/libjaxen-java/debian/ant.properties
@@ -0,0 +1 @@
+noget=true
diff --git a/libjaxen-java/debian/changelog b/libjaxen-java/debian/changelog
new file mode 100644
index 0000000..e3ee698
--- /dev/null
+++ b/libjaxen-java/debian/changelog
@@ -0,0 +1,43 @@
+libjaxen-java (1.1~beta11-1) unstable; urgency=low
+
+  [ Wolfgang Baer ]
+  * libsaxpath-java code is now included in the jaxen source base
+    + No more libsaxpath-java binary from this source
+    + Added conflicts, replaces with libsaxpath-java
+  * Updated jdom dependency to libjdom1-java
+  * Updated documentation everywhere (description, README.Debian, download
+    location and copyright)
+  * Applied several patches: 01_RemoveXomDom4jTests.patch - to disable
+    outsourced dom4j/xom functionality from tests.
+  * Enabled junit tests
+
+  [ Marcus Better ]
+  * New upstream release.
+  * debian/rules: Don't use cdbs. Build with gcj instead of kaffe.
+  * Don't use dpatch.
+  * debian/copyright: Updated information.
+
+ -- Marcus Better <marcus at better.se>  Mon,  9 Oct 2006 12:18:00 +0200
+
+libjaxen-java (1.0FCS-3) unstable; urgency=low
+
+  * Removed libgnujaxp-java dependency - not needed anymore
+  * Removed unused build dependency / dependency on old package libdom1-java 
+  * debian/rules: Removed jikes build compiler property
+  * Bumped debhelper version dependency to fix linda error
+  * Added myself to uploaders
+
+ -- Wolfgang Baer <WBaer at gmx.de>  Thu,  5 Jan 2006 10:34:13 +0100
+
+libjaxen-java (1.0FCS-2) unstable; urgency=low
+
+  * ant transition
+  * Standards-Version to 3.6.2, no change needed.
+
+ -- Arnaud Vandyck <avdyk at debian.org>  Tue,  4 Oct 2005 13:46:44 +0200
+
+libjaxen-java (1.0FCS-1) unstable; urgency=low
+
+  * Initial Release.
+
+ -- Arnaud Vandyck <avdyk at debian.org>  Fri, 15 Apr 2005 17:42:45 +0200
diff --git a/libjaxen-java/debian/compat b/libjaxen-java/debian/compat
new file mode 100644
index 0000000..7ed6ff8
--- /dev/null
+++ b/libjaxen-java/debian/compat
@@ -0,0 +1 @@
+5
diff --git a/libjaxen-java/debian/control b/libjaxen-java/debian/control
new file mode 100644
index 0000000..2ba6389
--- /dev/null
+++ b/libjaxen-java/debian/control
@@ -0,0 +1,21 @@
+Source: libjaxen-java
+Section: libs
+Priority: optional
+Maintainer: Debian Java Maintainers <pkg-java-maintainers at lists.alioth.debian.org>
+Uploaders: Arnaud Vandyck <avdyk at debian.org>, Wolfgang Baer <WBaer at gmx.de>, Marcus Better <marcus at better.se>
+Build-Depends: debhelper (>= 5.0.0), ant, ant-optional
+Build-Depends-Indep: java-gcj-compat-dev, junit, libjdom1-java, libxerces2-java
+Standards-Version: 3.7.2
+
+Package: libjaxen-java
+Architecture: all
+Depends: kaffe | java1-runtime | java2-runtime, libjdom1-java, libxerces2-java
+Suggests: java-virtual-machine
+Conflicts: libsaxpath-java
+Replaces: libsaxpath-java
+Description: Java XPath engine
+ jaxen is a universal object model walker, capable of evaluating XPath
+ expressions across multiple models. Currently supported are dom4j,
+ JDOM, and DOM.
+ .
+  Homepage: http://jaxen.org
diff --git a/libjaxen-java/debian/copyright b/libjaxen-java/debian/copyright
new file mode 100644
index 0000000..ffb178c
--- /dev/null
+++ b/libjaxen-java/debian/copyright
@@ -0,0 +1,51 @@
+This package was debianized by Arnaud Vandyck <avdyk at debian.org> on
+Fri, 15 Apr 2005 15:53:37 +0200.
+
+It was downloaded from <http://jaxen.org>.
+
+Upstream Authors: Attila Szegedi, Bob McWhirter <bob at werken.com>,
+Bradley S. Huffman, Brett McLaughlin, David Megginson, Elliotte Rusty
+Harold, Erwin Bolwidt <ejb at klomp.org>, James Pereira
+<JPereira at CT.BBD.CO.ZA>, James Strachan <jstrachan at apache.org>, Jan
+Dvorak <jan.dvorak at mathan.cz>, Jason Hunter, Jérôme Nègre
+<jerome.negre at e-xmlmedia.fr>, Mark Wilson <mark at wilsoncom.de>, Stephen
+Colebourne.
+
+jaxen is Copyright (C) 2000-2005 Bob McWhirter and James Strachan
+                       2000-2004 Jason Hunter and Brett McLaughlin
+                       2001-2006 Codehaus
+                       2003-2006 The Werken Company
+                       2005-2006 Elliotte Rusty Harold
+
+License:
+
+     Redistribution and use in source and binary forms, with or without
+     modification, are permitted provided that the following conditions are
+     met:
+
+      * Redistributions of source code must retain the above copyright
+	notice, this list of conditions and the following disclaimer.
+
+      * Redistributions in binary form must reproduce the above copyright
+	notice, this list of conditions and the following disclaimer in the
+	documentation and/or other materials provided with the distribution.
+
+      * Neither the name of the Jaxen Project nor the names of its
+	contributors may be used to endorse or promote products derived 
+	from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+    IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+    TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+    PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+    OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+The contributions to the Debian packaging by Marcus Better are
+Copyright (C) 2006 Marcus Better <marcus at better.se> and are licensed
+under the same license as above.
diff --git a/libjaxen-java/debian/dirs b/libjaxen-java/debian/dirs
new file mode 100644
index 0000000..13c9f03
--- /dev/null
+++ b/libjaxen-java/debian/dirs
@@ -0,0 +1 @@
+usr/share/java
diff --git a/libjaxen-java/debian/doc-base b/libjaxen-java/debian/doc-base
new file mode 100644
index 0000000..904ac74
--- /dev/null
+++ b/libjaxen-java/debian/doc-base
@@ -0,0 +1,9 @@
+Document: libjaxen-java
+Title: jaxen API
+Author: jaxen developers
+Abstract: JavaDoc documentation for jaxen
+Section: Apps/Programming
+
+Format: HTML
+Index: /usr/share/doc/libjaxen-java/api/index.html
+Files: /usr/share/doc/libjaxen-java/api/*
diff --git a/libjaxen-java/debian/docs b/libjaxen-java/debian/docs
new file mode 100644
index 0000000..81a398b
--- /dev/null
+++ b/libjaxen-java/debian/docs
@@ -0,0 +1 @@
+dist/docs/api
diff --git a/libjaxen-java/debian/patches/00_BuildXml_DisableXomDom4J_CompileAndTest.patch b/libjaxen-java/debian/patches/00_BuildXml_DisableXomDom4J_CompileAndTest.patch
new file mode 100644
index 0000000..f17ad3b
--- /dev/null
+++ b/libjaxen-java/debian/patches/00_BuildXml_DisableXomDom4J_CompileAndTest.patch
@@ -0,0 +1,56 @@
+--- build.xml.orig	2006-02-12 18:03:46.000000000 +0100
++++ build.xml	2006-02-12 16:10:59.000000000 +0100
+@@ -44,6 +44,8 @@
+     <mkdir dir="${classesdir}">
+     </mkdir>
+     <javac destdir="${classesdir}" deprecation="true" debug="true" optimize="false" excludes="**/package.html">
++      <exclude name="org/jaxen/dom4j/*"/>
++      <exclude name="org/jaxen/xom/*"/>
+       <src>
+         <pathelement location="src/java/main">
+         </pathelement>
+@@ -79,7 +81,7 @@
+   <target name="internal-test" if="Junit.present" depends="junit-present,compile-tests">
+     <mkdir dir="${testreportdir}">
+     </mkdir>
+-    <junit dir="./" failureproperty="test.failure" printSummary="yes" fork="true" haltonerror="true">
++    <junit dir="./" failureproperty="false" printSummary="yes" fork="true" haltonerror="false">
+       <sysproperty key="basedir" value=".">
+       </sysproperty>
+       <formatter type="xml">
+@@ -87,6 +89,7 @@
+       <formatter usefile="false" type="plain">
+       </formatter>
+       <classpath>
++        <pathelement location="/usr/share/java/jdom1.jar"/>
+         <path refid="build.classpath">
+         </path>
+         <pathelement path="${testclassesdir}">
+@@ -98,8 +101,9 @@
+         <fileset dir="src/java/test">
+           <include name="**/*Test.java">
+           </include>
+-          <exclude name="org/jaxen/jdom/XPathTest.java">
+-          </exclude>
++          <exclude name="org/jaxen/jdom/XPathTest.java"/>
++          <exclude name="org/jaxen/dom4j/*.java"/>
++          <exclude name="org/jaxen/xom/*.java"/>
+         </fileset>
+       </batchtest>
+     </junit>
+@@ -113,6 +117,8 @@
+     <mkdir dir="${testclassesdir}">
+     </mkdir>
+     <javac destdir="${testclassesdir}" deprecation="true" debug="true" optimize="false" excludes="**/package.html">
++      <exclude name="org/jaxen/dom4j/*"/>
++      <exclude name="org/jaxen/xom/*"/>
+       <src>
+         <pathelement location="src/java/test">
+         </pathelement>
+@@ -169,4 +175,4 @@
+     <unjar dest="${maven.home}" src="${user.home}/maven-install-latest.jar">
+     </unjar>
+   </target>
+-</project>
+\ Kein Zeilenumbruch am Dateiende.
++</project>
diff --git a/libjaxen-java/debian/patches/01_RemoveXomDom4jTests.patch b/libjaxen-java/debian/patches/01_RemoveXomDom4jTests.patch
new file mode 100644
index 0000000..21b3dac
--- /dev/null
+++ b/libjaxen-java/debian/patches/01_RemoveXomDom4jTests.patch
@@ -0,0 +1,38 @@
+--- src/java/test/org/jaxen/JaxenTests.java.orig	2006-02-12 15:33:02.000000000 +0100
++++ src/java/test/org/jaxen/JaxenTests.java	2006-02-12 15:48:10.000000000 +0100
+@@ -63,7 +63,7 @@
+ package org.jaxen;
+ 
+ import org.jaxen.dom.DOMTests;
+-import org.jaxen.dom4j.DOM4JTests;
++//import org.jaxen.dom4j.DOM4JTests;
+ import org.jaxen.expr.ExprTests;
+ import org.jaxen.function.FunctionTests;
+ import org.jaxen.javabean.JavaBeanTests;
+@@ -73,7 +73,7 @@
+ import org.jaxen.saxpath.base.BaseTests;
+ import org.jaxen.saxpath.helpers.HelpersTests;
+ import org.jaxen.util.UtilTests;
+-import org.jaxen.xom.XOMTests;
++//import org.jaxen.xom.XOMTests;
+ 
+ import junit.framework.Test;
+ import junit.framework.TestSuite;
+@@ -98,8 +98,8 @@
+         result.addTest(CoreTests.suite());
+         result.addTest(DOMTests.suite());
+         result.addTest(JDOMTests.suite());
+-        result.addTest(DOM4JTests.suite());
+-        result.addTest(XOMTests.suite());
++        //result.addTest(DOM4JTests.suite());
++        //result.addTest(XOMTests.suite());
+         result.addTest(JavaBeanTests.suite());
+         result.addTest(PatternTests.suite());
+         result.addTest(BaseTests.suite());
+@@ -111,4 +111,4 @@
+     }
+ 
+     
+-}
+\ Kein Zeilenumbruch am Dateiende.
++}
diff --git a/libjaxen-java/debian/rules b/libjaxen-java/debian/rules
new file mode 100755
index 0000000..6d6ad75
--- /dev/null
+++ b/libjaxen-java/debian/rules
@@ -0,0 +1,64 @@
+#!/usr/bin/make -f
+
+JAVA_HOME	:= /usr/lib/jvm/java-gcj
+DEB_JARS_BASE	:= /usr/share/java
+JAVACMD  	:= $(JAVA_HOME)/bin/java
+
+DEB_JARS  := ant ant-launcher jdom1 ant-junit junit xercesImpl
+
+DEB_CLASSPATH = $(shell for jar in $(DEB_JARS); do \
+		if [ -f "$$jar" ]; then echo -n "$${jar}:"; fi; \
+		if [ -f "$$jar".jar ]; then echo -n "$${jar}.jar:"; fi; \
+		if [ -f $(DEB_JARS_BASE)/"$$jar" ]; then echo -n "$(DEB_JARS_BASE)/$${jar}:"; fi; \
+		if [ -f $(DEB_JARS_BASE)/"$$jar".jar ]; then echo -n "$(DEB_JARS_BASE)/$${jar}.jar:"; fi; \
+		done; \
+		if [ -f "$(JAVA_HOME)/lib/tools.jar" ]; then echo -n "$(JAVA_HOME)/lib/tools.jar"; fi)
+
+DEB_ANT_ARGS	:= -propertyfile debian/ant.properties
+ANT_INVOKE	:= $(JAVACMD) -classpath $(DEB_CLASSPATH) \
+		org.apache.tools.ant.Main $(DEB_ANT_ARGS)
+
+PKGNAME		:= libjaxen-java
+INSTALLDIR	:= $(CURDIR)/debian/$(PKGNAME)
+JAVALIBDIR	:= $(INSTALLDIR)/usr/share/java
+
+VERSION  := $(shell head -1 debian/changelog | cut -f2 -d\( | cut -f1 -d\) | cut -f1 -d\- | cut -f1 -d\+)
+UVERSION := $(subst ~beta,-beta-,$(VERSION))
+
+build: build-stamp
+build-stamp:
+	dh_testdir
+	$(ANT_INVOKE) jar javadoc test
+	touch build-stamp
+
+clean:
+	dh_testdir
+	dh_testroot
+	rm -f build-stamp
+	$(ANT_INVOKE) clean
+	dh_clean
+
+install: build
+	dh_testdir
+	dh_testroot
+	dh_clean -k 
+	dh_installdirs
+	install -m 644 target/jaxen-$(UVERSION).jar $(JAVALIBDIR)/jaxen-$(VERSION).jar
+	ln -s jaxen-$(VERSION).jar $(JAVALIBDIR)/jaxen.jar
+
+binary-indep: build install
+	dh_testdir
+	dh_testroot
+	dh_installchangelogs
+	dh_installdocs
+	dh_compress
+	dh_fixperms
+	dh_installdeb
+	dh_gencontrol
+	dh_md5sums
+	dh_builddeb
+
+binary-arch: build install
+
+binary: binary-indep binary-arch
+.PHONY: build clean binary-indep binary-arch binary install
diff --git a/libjaxen-java/debian/svn-deblayout b/libjaxen-java/debian/svn-deblayout
new file mode 100644
index 0000000..3dc8c9c
--- /dev/null
+++ b/libjaxen-java/debian/svn-deblayout
@@ -0,0 +1,2 @@
+buildArea=../../build-area
+origDir=..
diff --git a/libjaxen-java/debian/watch b/libjaxen-java/debian/watch
new file mode 100644
index 0000000..018c8f0
--- /dev/null
+++ b/libjaxen-java/debian/watch
@@ -0,0 +1,3 @@
+version=3
+opts="dversionmangle=s/~beta/-beta-/" \
+  http://dist.codehaus.org/jaxen/distributions/jaxen-(.*)-src.tar.gz
diff --git a/libjaxen-java/maven.xml b/libjaxen-java/maven.xml
new file mode 100644
index 0000000..5d954cf
--- /dev/null
+++ b/libjaxen-java/maven.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns:ant="jelly:ant">
+
+    <preGoal name="dist:build-bin">
+      <attainGoal name="dist:build-src" />
+    </preGoal>
+
+    <postGoal name="dist:prepare-bin-filesystem">
+        <ant:copy todir="${maven.dist.bin.assembly.dir}">
+            <fileset dir=".">
+                <include name="xml/**" />
+            </fileset>
+        </ant:copy>
+    </postGoal>
+
+    <postGoal name="dist:prepare-src-filesystem">
+        <ant:copy todir="${maven.dist.src.assembly.dir}">
+            <fileset dir=".">
+                <include name="xml/**" />
+            </fileset>
+        </ant:copy>
+    </postGoal>
+
+</project>
+
+
diff --git a/libjaxen-java/project.properties b/libjaxen-java/project.properties
new file mode 100644
index 0000000..7e949e5
--- /dev/null
+++ b/libjaxen-java/project.properties
@@ -0,0 +1,77 @@
+# ------------------------------------------------------------
+#     project properties
+# ------------------------------------------------------------
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
+#     core
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
+
+maven.compile.debug = on
+maven.compile.optimize = on
+maven.compile.deprecation = on
+maven.compile.target = 1.2
+maven.compile.source = 1.3
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
+#     xdocs
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
+
+maven.ui.banner.background = white
+maven.ui.section.background = #BBBBBB
+maven.ui.subsection.background = #DDDDDD
+maven.ui.section.foreground = #990000
+maven.ui.subsection.foreground = #990000
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
+#     checkstyle
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
+
+#maven.checkstyle.properties = ${basedir}/project.properties
+
+checkstyle.lcurly.type = nl
+checkstyle.lcurly.method = nl
+checkstyle.lcurly.other = nl
+checkstyle.rcurly = alone
+
+checkstyle.paren.pad = ignore
+checkstyle.maxlinelen = 132
+
+checkstyle.ignore.whitespace = yes
+checkstyle.allow.tabs=false
+
+checkstyle.header.file = LICENSE.txt
+checkstyle.header.ignoreline = 1,2,3,4,5,6
+checkstyle.const.pattern = ^[a-zA-Z][a-zA-Z0-9_]*$
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
+#     pmd
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
+
+maven.jar.override=on
+maven.jar.pmd=3.2
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
+#     javadoc
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
+
+maven.javadoc.stylesheet = ./xdocs/stylesheets/javadoc-style.css
+# maven.javadoc.overview = ${basedir}/src/java/main/org/blissed/overview.html
+maven.javadoc.links = \
+	http://java.sun.com/j2se/1.4.2/docs/api/
+maven.javadoc.excludepackagenames = org.jaxen.saxpath.base,org.jaxen.saxpath.helpers
+
+maven.jarResources.basedir = src/java/main/
+
+maven.xdoc.date = left
+
+maven.docs.outputencoding = UTF-8
+
+maven.junit.fork=true
+
+#maven.latex.src.dir = ${basedir}/src/latex/
+#maven.latex.docs = intro-slides.tex
+
+maven.repo.remote=http://www.ibiblio.org/maven/,http://dist.codehaus.org/
+maven.repo.central=dist.codehaus.org
+maven.repo.central.directory=/dist
+maven.remote.group=jaxen
\ No newline at end of file
diff --git a/libjaxen-java/project.xml b/libjaxen-java/project.xml
new file mode 100644
index 0000000..e818d61
--- /dev/null
+++ b/libjaxen-java/project.xml
@@ -0,0 +1,339 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:noNamespaceSchemaLocation="http://maven.apache.org/xsd/maven-project-3.0.0.xsd">
+
+  <pomVersion>3</pomVersion>
+  <id>jaxen</id>
+  <name>jaxen</name>
+  <currentVersion>1.1-beta-11</currentVersion>
+
+  <organization>
+    <name>Codehaus</name>
+    <url>http://www.codehaus.org</url>
+    <logo>http://codehaus.org/codehaus-small.gif</logo>
+  </organization>
+  <inceptionYear>2001</inceptionYear>
+  <package>org.jaxen</package>
+
+
+  <logo>./jaxen.gif</logo>
+  <description>
+  Jaxen is a universal Java XPath engine.
+  </description>
+  <shortDescription>Universal Java XPath Engine</shortDescription>
+
+  <url>http://jaxen.codehaus.org/</url>
+
+  <issueTrackingUrl>http://jira.codehaus.org/BrowseProject.jspa?id=10022</issueTrackingUrl>
+  <siteAddress>jaxen.codehaus.org</siteAddress>
+  <siteDirectory>/home/projects/jaxen/public_html</siteDirectory>
+  <distributionDirectory>/dist</distributionDirectory>
+  
+  <repository>
+    <connection>scm:cvs:pserver:anonymous at cvs.jaxen.codehaus.org:/home/projects/jaxen/scm:jaxen</connection>
+    <url>http://cvs.jaxen.codehaus.org</url>
+  </repository>
+  
+    <!-- the archive URLs are broken ???? -->
+    <mailingLists>
+        <mailingList>
+            <name>Jaxen Users List</name>
+            <subscribe>user-subscribe at jaxen.codehaus.org</subscribe>
+            <unsubscribe>user-unsubscribe at jaxen.codehaus.org</unsubscribe>
+            <!--<archive>http://archive.jaxen.codehaus.org/user/</archive> -->
+        </mailingList>
+        <mailingList>
+            <name>Jaxen Developers List</name>
+            <subscribe>dev-subscribe at jaxen.codehaus.org</subscribe>
+            <unsubscribe>dev-unsubscribe at jaxen.codehaus.org</unsubscribe>
+         <!--   <archive>http://archive.jaxen.codehaus.org/dev/</archive> -->
+        </mailingList>
+        <mailingList>
+            <name>Jaxen CVS Commits List</name>
+            <subscribe>scm-subscribe at jaxen.codehaus.org</subscribe>
+            <unsubscribe>scm-unsubscribe at jaxen.codehaus.org</unsubscribe>
+       <!--     <archive>http://archive.jaxen.codehaus.org/scm/</archive> -->
+        </mailingList>
+        <mailingList>
+            <name>Jaxen Announcement List</name>
+            <subscribe>announce-subscribe at jaxen.codehaus.org</subscribe>
+            <unsubscribe>announce-unsubscribe at jaxen.codehaus.org</unsubscribe>
+       <!--     <archive>http://archive.jaxen.codehaus.org/announce/</archive> -->
+        </mailingList>
+    </mailingLists>
+
+
+  <developers>
+
+    <developer>
+      <name>Bob McWhirter</name>
+      <id>bob</id>
+      <email>bob at eng.werken.com</email>
+      <organization>The Werken Company</organization>
+    </developer>
+
+    <developer>
+      <name>James Strachan</name>
+      <id>jstrachan</id>
+      <email>james_strachan at yahoo.co.uk</email>
+      <organization>Spiritsoft</organization>
+    </developer>
+
+    <developer>
+      <name>David Megginson</name>
+      <id>dmegginson</id>
+      <email>contact at megginson.com</email>
+      <organization>Megginson Technologies</organization>
+    </developer>
+
+    <developer>
+      <name>Erwin Bolwidt</name> 
+      <id>eboldwidt</id>
+      <email>erwin at klomp.org</email>
+    </developer>
+
+    <developer>
+      <name>Mark A. Belonga</name>
+      <id>mbelonga</id>
+      <email>mbelonga at users.sourceforge.net</email>
+    </developer>
+
+    <developer>
+      <name>Christian Nentwich</name>
+      <!-- <id>xcut</id> -->
+      <id>cnentwich</id>
+      <email>xcut at users.sourceforge.net</email>
+    </developer>
+
+    <developer>
+      <name>Alexander Day Chaffee</name>
+      <id>purpletech</id>
+      <email>purpletech at users.sourceforge.net</email>
+      <organization>Purple Technologies</organization>
+    </developer>
+
+    <developer>
+      <name>Jan Dvorak</name>
+      <id>jdvorak</id>
+      <email>jdvorak at users.sourceforge.net</email>
+    </developer>
+
+    <developer>
+      <name>Attila Szegedi</name>
+      <id>szegedia</id>
+      <email>szegedia at users.sourceforge.net</email>
+    </developer>
+
+    <developer>
+      <name>Peter Royal</name>
+      <id>proyal</id>
+      <email>peter.royal at pobox.com</email>
+      <url>http://fotap.org/~osi</url>
+    </developer>
+
+    <developer>
+      <name>Scott Sanders</name>
+      <id>ssanders</id>
+      <email>scott at dotnot.org</email>
+      <organization>dotnot</organization>
+      <url>http://dotnot.org/blog</url>
+    </developer>
+
+    <developer>
+      <name>Brian Ewins</name>
+      <id>bewins</id>
+      <email>brian.ewins at gmail.com</email>
+    </developer>
+
+    <developer>
+      <name>Elliotte Rusty Harold</name>
+      <id>elharo</id>
+      <email>elharo at metalab.unc.edu</email>
+      <organization>Cafe au Lait</organization>
+      <url>http://www.elharo.com/</url>
+    </developer>
+
+  </developers>
+
+  <contributors>
+    <contributor>
+      <name>David Peterson</name> 
+      <email>david at randombits.org</email>
+    </contributor>
+
+    <contributor>
+      <name>Mark Wilson</name> 
+      <email>mark.wilson at wilsoncom.de</email>
+    </contributor>
+
+    <contributor>
+      <name>Jacob Kjome</name> 
+      <email>hoju at visi.com</email>
+    </contributor>
+
+    <contributor>
+      <name>Michael Brennan</name>
+      <email>mpbrennan at earthlink.net</email>
+    </contributor>
+
+    <contributor>
+      <name>Jason Hunter</name>
+      <email>jhunter at xquery.com</email>
+    </contributor>
+
+    <contributor>
+      <name>Brett Mclaughlin</name>
+      <email>brett.mclaughlin at lutris.com</email>
+    </contributor>
+
+    <contributor>
+      <name>Bradley S. Huffman</name>
+      <email>hip at cs.okstate.edu</email>
+    </contributor>
+
+    <!-- found him on sourceforge http://sourceforge.net/project/memberlist.php?group_id=26014 -->
+    <contributor>
+      <name>K. Ari Krupnikov</name>
+      <email>ari at lib.aero</email>
+    </contributor>
+
+    <!-- found him on sourceforge http://sourceforge.net/project/memberlist.php?group_id=31447 -->
+    <contributor>
+      <name>Paul R. Brown</name>
+      <email>prb at fivesight.com</email>
+    </contributor>
+
+
+    <!-- next two found on http://lists.debian.org/debian-mentors/2003/09/msg00217.html -->
+    <contributor>
+      <name>Guoliang Cao</name>
+      <email>cao at ispsoft.com</email>
+    </contributor>
+
+   <contributor>
+      <name>Jérôme Nègre</name>
+      <email>jerome.negre at e-xmlmedia.fr</email>
+    </contributor>
+
+    <!-- found next two in CVS-->
+    <contributor>
+      <name>Eddie McGreal</name>
+      <email>emcgreal at BlackPearl.com</email>
+    </contributor>
+
+    <contributor>
+      <name>Steen Lehmann</name>
+      <email>slehmann at users.sourceforge.net</email>
+    </contributor>
+
+  </contributors>
+
+  <reports>
+     <report>maven-jdepend-plugin</report>
+     <report>maven-checkstyle-plugin</report>
+     <report>maven-cobertura-plugin</report>
+     <report>maven-changelog-plugin</report>
+     <report>maven-developer-activity-plugin</report>
+     <report>maven-file-activity-plugin</report>
+     <report>maven-license-plugin</report>
+     <report>maven-javadoc-plugin</report>
+     <report>maven-jxr-plugin</report>
+     <report>maven-junit-report-plugin</report>
+     <report>maven-linkcheck-plugin</report>
+     <report>maven-tasklist-plugin</report>
+     <report>maven-pmd-plugin</report> 
+     <report>maven-findbugs-plugin</report> 
+   <!-- commenting out until they fix their repository  <report>jutils-lint4j-plugin</report> -->
+   <!--  <report>maven-hammurapi-plugin</report> -->
+  </reports>
+
+  <!-- Need to mark these as compile-time/run-time -->
+
+  <dependencies>
+
+    <dependency>
+      <groupId>dom4j</groupId>
+      <artifactId>dom4j</artifactId>
+      <version>1.6.1</version>
+    </dependency>
+
+    <dependency>
+      <groupId>jdom</groupId>
+      <artifactId>jdom</artifactId>
+      <version>1.0</version>
+      <url>http://jdom.org</url>
+    </dependency>
+
+    <dependency>
+      <groupId>xml-apis</groupId>
+      <artifactId>xml-apis</artifactId>
+      <version>1.3.02</version>
+    </dependency>
+
+    <dependency>
+      <groupId>xerces</groupId>
+      <artifactId>xercesImpl</artifactId>
+      <version>2.6.2</version>
+    </dependency>
+
+    <dependency>
+      <groupId>xom</groupId>
+      <artifactId>xom</artifactId>
+      <version>1.0b3</version>
+    </dependency>
+
+    <dependency>
+      <groupId>maven-plugins</groupId>
+      <artifactId>maven-cobertura-plugin</artifactId>
+      <version>1.1.1</version>
+      <type>plugin</type>
+    </dependency>
+    
+<!--    <dependency>
+      <groupId>maven-plugins</groupId>
+      <artifactId>maven-latex-plugin</artifactId>
+      <version>1.5</version>
+      <type>plugin</type>
+    </dependency> -->
+    
+    <dependency>
+      <groupId>maven-plugins</groupId>
+      <artifactId>maven-findbugs-plugin</artifactId>
+      <version>0.9.2</version>
+      <type>plugin</type>
+    </dependency>
+
+<!--    <dependency>
+      <groupId>lint4j</groupId>
+      <artifactId>jutils-lint4j-plugin</artifactId>
+      <version>1.1</version>
+      <type>plugin</type>
+    </dependency> -->
+
+ <!--   <dependency>
+      <groupId>org.hammurapi</groupId>
+      <artifactId>maven-hammurapi-plugin</artifactId>
+      <version>1.0</version>
+      <type>plugin</type>
+    </dependency> -->
+  </dependencies>
+
+  <build>
+
+    <nagEmailAddress>dev at jaxen.codehaus.org</nagEmailAddress>
+    <sourceDirectory>src/java/main</sourceDirectory>
+    <unitTestSourceDirectory>src/java/test</unitTestSourceDirectory>
+
+    <!-- Unit test classes -->
+
+    <unitTest>
+      <includes>
+        <include>**/*Test.java</include>
+      </includes>
+    </unitTest>
+
+  </build>
+
+</project>
+
+
diff --git a/libjaxen-java/src/conf/MANIFEST.MF b/libjaxen-java/src/conf/MANIFEST.MF
new file mode 100644
index 0000000..092f5ec
--- /dev/null
+++ b/libjaxen-java/src/conf/MANIFEST.MF
@@ -0,0 +1,9 @@
+Manifest-Version: 1.0
+Extension-Name: org.jaxen
+Specification-Title: jaxen
+Specification-Version: 1.0 FCS
+Specification-Vendor: bob mcwhirter & James Strachan.
+Created-By: Ant 1.4.1
+Implementation-Vendor:  bob mcwhirter & James Strachan.
+Implementation-Version: 1.0 FCS
+Implementation-Title: jaxen
diff --git a/libjaxen-java/src/doc/default.css b/libjaxen-java/src/doc/default.css
new file mode 100644
index 0000000..49d3b7c
--- /dev/null
+++ b/libjaxen-java/src/doc/default.css
@@ -0,0 +1,124 @@
+body {
+  margin: 2em 1em 2em 70px;
+  font-family: sans-serif;
+  color: black;
+  background: white;
+  background-position: top left;
+  background-attachment: fixed;
+  background-repeat: no-repeat;
+}
+
+th, td { /* ns 4 */
+  font-family: sans-serif;
+}
+
+h1, h2, h3, h4, h5, h6 { text-align: left }
+h1, h2, h3, h4, h5 { color: #005A9C }
+h1 { font: 170% sans-serif }
+h2 { font: 140% sans-serif }
+h3 { font: 120% sans-serif }
+h4 { font: bold 100% sans-serif }
+h5 { font: italic 100% sans-serif }
+h6 { font: small-caps 100% sans-serif }
+
+.hide { display: none }
+
+div.head { margin-bottom: 1em }
+div.head h1 { margin-top: 2em; clear: both }
+div.head table { margin-left: 2em; margin-top: 2em }
+div.head img { color: white; border: none } /* remove border from top image */
+
+p.copyright { font-size: small }
+p.copyright small { font-size: small }
+
+ at media screen {  /* hide from IE3 */
+a:hover { background: #ffa } 
+}
+
+dt, dd { margin-top: 0; margin-bottom: 0 } /* opera 3.50 */
+dt { font-weight: bold }
+
+pre, code { font-family: monospace } /* navigator 4 requires this */
+
+ul.toc {
+  list-style: disc;		/* Mac NS has problem with 'none' */
+  list-style: none;
+}
+
+ at media aural {  
+  h1, h2, h3 { stress: 20; richness: 90 }
+  .hide { speak: none }
+  p.copyright { volume: x-soft; speech-rate: x-fast }
+  dt { pause-before: 20% }
+  pre { speak-punctuation: code } 
+}
+
+/* Things (icons) that should only show up in projection mode */
+.projection { display: none }
+ at media projection { .projection { display: inline } }
+
+div.example {
+    width: 100%;
+    color: black;
+}
+div.dtd-example {
+    width: 100%;
+    color: black;
+}
+tt.example {
+    color: maroon;
+    margin-left: 1em;
+}
+pre {
+    color: maroon;
+}
+div.dtd-fragment {
+    width: 100%;
+    border: none;
+    background-color: #eee;
+}
+pre.dtd-fragment {
+    margin-left: 0;
+}
+pre.dtd {
+    color: black;
+    margin-left: 0;
+}
+div.illegal-example {
+    width: 100%;
+    color: red;
+    border: solid red;
+}
+div.illegal-example p {
+    color: black;
+}
+div.deprecated-example {
+    width: 100%;
+    color: red;
+    border: solid rgb(255,165,0); /* orange */
+}
+div.deprecated-example p {
+    color: black;
+}
+div.note {
+    color: green;
+    margin-left: 1em;
+}
+p.note {
+    color: green;
+    margin-left: 1em;
+}
+ul.toc {
+    list-style-type: none;
+}
+
+a.normref { 
+    color : red;
+}	
+
+a.informref {
+    color : green;
+}	
+
+DIV.subtoc {padding: 1em; border: solid thin; margin: 1em 0;
+    background: #ddd}
diff --git a/libjaxen-java/src/doc/download.xml b/libjaxen-java/src/doc/download.xml
new file mode 100644
index 0000000..6c5a44a
--- /dev/null
+++ b/libjaxen-java/src/doc/download.xml
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<document url="http://jaxen.org/download.xml">
+  <body>
+    <title>Download Jaxen</title>
+    
+    <section title="Download the current release">
+      <p>The current release is version $VERSION$.</p>
+      <p>It can be downloaded at
+        <a href="http://sourceforge.net/project/showfiles.php?group_id=31447">SourceForge</a>
+        or directly via one of the following links:-
+      </p>
+      <ul>
+          <li>
+            <a href="http://prdownloads.sourceforge.net/jaxen/jaxen-$VERSION$.zip">jaxen-$VERSION$.zip</a> for Windows platforms (ZIP)
+          </li>
+          <li>
+            <a href="http://prdownloads.sourceforge.net/jaxen/jaxen-$VERSION$.tar.gz">jaxen-$VERSION$.tar.gz</a> for all other platforms (Tarball)
+          </li>
+      </ul>
+    </section>
+
+<!--
+    <section title="Download a daily build">
+      <ul>
+        <li><a href="../../dist/jaxen-daily.zip">jaxen-daily.zip</a> 
+            for Windows platforms (ZIP)
+        </li>
+        <li><a href="../../dist/jaxen-daily.tar.gz">jaxen-daily.tar.gz</a>
+            for all other platforms (Tarball)
+        </li>
+      </ul>
+    </section>
+-->
+
+    <section title="Obtaining the latest CVS snapshot">
+      
+      <p>
+        You can browse the current CVS repository 
+        <a href="http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/jaxen/">here</a>
+      </p>
+
+      <p>To learn more about CVS go <a href="http://www.cvshome.org/">here</a>.
+      </p>
+
+      <section title="Anonymous CVS Access">
+        <p>
+        This project's SourceForge CVS repository can be checked out through anonymous 
+        (pserver) <a href="http://www.cvshome.org/">CVS</a> with the following instruction set. 
+        When prompted for a password for anonymous, simply press the Enter key. 
+        </p>
+        <pre>
+cvs -d:pserver:anonymous at cvs.jaxen.org:/cvsroot/jaxen login 
+
+cvs -d:pserver:anonymous at cvs.jaxen.org:/cvsroot/jaxen co jaxen
+        </pre>
+        <p>Updates from within the module's directory do not need the -d parameter.
+        </p>
+      </section>
+
+      <section title="Developer CVS Access via SSH">
+        <p>
+        Only project developers can access the CVS tree via this method. 
+        SSH1 must be installed on your client machine. 
+        Substitute developername with the proper values. 
+        Enter your site password when prompted.
+        </p>
+
+        <pre>
+export CVS_RSH=ssh 
+ 
+cvs -d:ext:developername at cvs.jaxen.org:/cvsroot/jaxen co jaxen
+        </pre>
+      </section>
+
+    </section>
+  </body>
+</document>
+
+
+
+
+
+
+
+
+
diff --git a/libjaxen-java/src/doc/faq.xml b/libjaxen-java/src/doc/faq.xml
new file mode 100644
index 0000000..6c9e8c8
--- /dev/null
+++ b/libjaxen-java/src/doc/faq.xml
@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<document url="http://jaxen.org/faq.xml">
+  <body>
+    <title>Frequently Asked Questions</title>
+    
+    <section title="What is Jaxen?">
+      <p>
+      The <i>Jaxen</i> project is a Java XPath Engine.
+      <i>Jaxen</i> is a universal object model walker, capable of evaluating
+      XPath expressions across multiple models.  Currently supported
+      are <a href="http://dom4j.org">dom4j</a> and <a href="http://jdom.org">JDOM</a>.
+      </p>
+    </section>
+
+    <section title="What is the Jaxen license?">
+      <p>We use an Apache-style open source license which is one of the least
+        restrictive licenses around, you can use <i>Jaxen</i> to create new products
+        without them having to be open source.
+      </p>
+    </section>
+
+    <section title="Why is Jaxen useful?">
+      <p>
+      After implementing an XPath engine for both <a href="http://dom4j.org">dom4j</a> and
+      <a href="http://jdom.org">JDOM</a>, and attempting to keep them both in sync, it was
+      decided that factoring out the commonality would be a Good Thing.  Thus, <i>Jaxen</i>
+      provides a single point for XPath expression evaluation, regardless of the target
+      object model, whether its <b>dom4j</b>, <b>JDOM</b>, <b>DOM</b>, <b>JavaBeans</b>,
+      or whatnot.
+      </p>
+    </section>
+
+    <section title="Why is Jaxen better than <some other xpath technology>">
+      <p>
+      <i>Jaxen</i> is better than <b>werken.xpath</b> specifically because it better
+      handles XPath expressions, and syntax error reporting.  Additionally, since
+      Jaxen is a unified code-base, developer effort isn't split between maintaining
+      the <b>dom4j</b> version and the <b>JDOM</b> version.  More hands working on
+      the same project reduces bug count.
+      </p>
+
+      <p>
+      <i>Jaxen</i> may be perceived to be better than other XPath technologies since it
+      provides a single cohesive API for evaluating XPaths against multiple object
+      models.  Learn the <i>Jaxen</i> API, and apply it to <b>dom4j</b>, <b>JDOM</b>,
+      <b>EXML</b> or <b>DOM</b> trees in exactly the same way.
+      </p>
+
+      <p>
+      Also, since <i>Jaxen</i> works against an adaptor which provides InfoSet access
+      to arbitrary object models, it should be possible to build even larger
+      tools in terms of <i>Jaxen</i>, to work with multiple models.  For example, an
+      <b>XQL</b> engine could be developed, which would automagically work with
+      all models already supported by <i>Jaxen</i>.
+      </p>
+    </section>
+
+    <section title="What are some related technologies?">
+      <p>
+      <i>Jaxen</i> currently has navigators defined for <a href="http://dom4j.org/">dom4j</a>
+      and <a href="http://jdom.org/">JDOM</a>, two popular and convenient object models
+      for representing XML documents.  Additionally, <a href="http://themindelectric.com/">The Mind Electric's</a>
+      EXML is supported, providing better XPath support within the GLUE platform.
+      Of course, <a href="http://w3c.org/">W3C DOM</a> is also supported.
+      </p>
+    </section>
+
+    <section title="How do I support a different object model?">
+      <p>
+      The only thing required is an implementation of the interface 
+      <code>org.jaxen.Navigator</code>.  Not all of the interface is required,
+      and a default implementation, in the form of <code>org.jaxen.DefaultNavigator</code>
+      is also provided.
+      </p>
+
+      <p>
+      Since many of the XPath axes can be defined in terms of each other (for example,
+      the <code>ancestor</code> axis is merely a the <code>parent</code> recursively
+      applied), only a few low-level axis iterators are required to initially get
+      started.  Of course, you may implement them directly, instead of relying upon
+      <i>Jaxen</i>'s composition ability.
+      </p>
+
+    </section>
+
+    <section title="Is Jaxen only good for XPath evaluation?">
+      <p>
+      No. 
+      </p>
+
+      <p>
+      The <i>DocumentNavigators</i> provided with <i>Jaxen</i> would be used
+      by themselves, without the XPath evaluation engine, to provide univeral
+      access to many object models for other technologies.
+      </p>
+    </section>
+
+    <section title="Who uses Jaxen?">
+      <p>
+      <i>Jaxen</i> has been embedded directly into <b>dom4j</b> to provide
+      easy XPath evaluation directly from your documents.  Additionally, it's
+      being integrated into David Megginson's 
+      <a href="http://sourceforge.net/projects/newsml-toolkit/">NewsML Framework</a>.
+      </p>
+    </section>
+
+  </body>
+</document>
+
+
+
+
+
+
+
+
+
diff --git a/libjaxen-java/src/doc/index.xml b/libjaxen-java/src/doc/index.xml
new file mode 100644
index 0000000..619bbea
--- /dev/null
+++ b/libjaxen-java/src/doc/index.xml
@@ -0,0 +1,73 @@
+<?xml version="1.0"?>
+<document url="http://jaxen.org/index.xml">
+  <body>
+    <title>Jaxen: Java XPath Engine</title>
+
+    <header>
+      <p>
+      <i>Jaxen</i> is a fast Java engine for <a href="http://www.w3.org/TR/xpath">XPath 1.0</a>
+      that works on all XML object models. The following models are currently supported out of the box
+      <ul>
+      <li><a href="http://www.w3.org/DOM/">DOM</a></li>
+      <li><a href="http://dom4j.org">dom4j</a></li>
+      <li><a href="http://www.xom.nu/">XOM</a></li>
+      <li><a href="http://jdom.org">JDOM</a></li>
+      </ul>
+      </p>
+    </header>
+    
+    <section title="News">
+      <ul>
+      <li>Check out these new <a href="http://dom4j.org/benchmarks/xpath/index.html">Performance Benchmarks</a> comparing dom4j and Jaxen against Xerces and Xalan. 
+      </li>
+      <li>Sun chooses Jaxen for the XPath engine 
+        <a href="http://jakarta.apache.org/taglibs/doc/standard-doc/intro.html">JSTL</a> and 
+        <a href="http://java.sun.com/webservices/webservicespack.html">Web Services pack</a>
+      </li>
+      <li>
+        Since the reference implementation of 
+        <a href="http://developer.java.sun.com/developer/earlyAccess/xml/jaxm/">JAXM</a>
+        is based on <a href="http://dom4j.org">dom4j</a> and Jaxen that means you can use
+        Jaxen to query SOAP messages on the Java platform too!
+      </li>
+      <li>Check out Elliotte Rusty Harolds book chapter on XPath and 
+        <a href="http://cafeconleche.org/books/xmljava/chapters/ch16s06.html">Jaxen</a>
+      </li>
+      <li>Alex Chaffee wrote 
+        <a href="http://www.purpletech.com/xpe/">XPath Explorer</a> 
+        to help visualize results of XPath expressions.
+      </li>
+      </ul>
+    </section>
+
+    <section title="Getting Started">
+      <p>You can download the current $VERSION$ release 
+        or a nightly build via the <a href="download.html">download page</a>.</p>
+
+      <p>You could try browsing the
+        <a href="faq.html">FAQ</a> or the online 
+        <a href="apidocs/index.html">JavaDoc</a>.
+      </p>      
+      
+      <p>Contributors are welcome to join this project. 
+        Once you've browsed the <a href="faq.html">FAQ</a> you could try
+        sending an email to one of the mailing lists below or check out the
+        <a href="http://sourceforge.net/projects/jaxen/">project page</a>.</p>
+
+    </section>
+
+    <section title="Mailing Lists">
+      <p>There is a
+        <a href="http://lists.sourceforge.net/lists/listinfo/jaxen-interest">
+          jaxen-interest
+        </a> 
+        email list where you can share ideas and experiences, ask for help, 
+        give us feedback or discuss your requirements.
+      </p>
+
+      <p>You can also browse the <a href="http://www.mail-archive.com/jaxen-interest%40lists.sourceforge.net/">archives</a>.
+      </p>
+    </section>
+
+  </body>
+</document>
diff --git a/libjaxen-java/src/doc/project.xml b/libjaxen-java/src/doc/project.xml
new file mode 100644
index 0000000..626c6df
--- /dev/null
+++ b/libjaxen-java/src/doc/project.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<project name="jaxen" repository="jaxen" href="http://jaxen.org">
+
+  <title>jaxen: Java XPath Engine</title>
+
+  <meta>
+    
+  </meta>
+
+  <links>
+    <table width="100%">
+      <tr>
+        <td align="left" valign="center">
+          <a href="index.html"><img src="style/images/logo.gif" border="0" alt="jaxen"/></a>
+        </td>
+        <td><br /></td>
+        <td align="right" valign="center">
+          <font size="2">
+            <a href="faq.html">FAQ</a> 
+            | <a href="apidocs/index.html">JavaDoc</a> 
+            | <a href="download.html">download</a>
+            | <a href="status.html">status</a> 
+            | <a href="http://sourceforge.net/projects/jaxen/">project page</a>
+          </font>
+        </td>
+      </tr>
+    </table>
+  </links>
+
+  <notice>
+    Copyright 2001 (C) bob mcwhirter & James Strachan. All rights reserved. Hosted by SourceForge <br/>
+    <table cellspacing="10" align="Center" valign="Center">
+    <tr>
+    <td valign="Center">
+    <a href="http://sourceforge.net/"><img src="http://sourceforge.net/sflogo.php?group_id=31477" width="88" height="31" border="0" alt="SourceForge Logo"/></a>
+    </td>
+    </tr>
+    </table>
+  </notice>
+
+</project>
diff --git a/libjaxen-java/src/doc/status.xml b/libjaxen-java/src/doc/status.xml
new file mode 100644
index 0000000..e9722c4
--- /dev/null
+++ b/libjaxen-java/src/doc/status.xml
@@ -0,0 +1,145 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<document url="http://jaxen.org/status.xml">
+  <body>
+    <title>Status</title>
+    
+    <section title="Change History">
+      <section title="Changes in CVS since last release">
+        <p>Applied Elliotte's suggestions and moved the document() function 
+          into the org.jaxen.function.xslt package
+          to better reflect the fact that it is an XSLT function rather than XPath 1.0
+          as well as adding the lang() function to the list of known problems.
+          </p>
+      </section>
+      
+      <section title="Jaxen 1.0 FCS">
+        <p>Applied patch submitted by Shawn Bayern to fix the booleanValueOf() method.
+        </p>
+        <p>Added licenses to each source file and a proper manifest to the build at last ;-).
+        </p>
+      </section>
+      
+      <section title="Jaxen 1.0 RC1">
+        <p>There is now an XPath interface in the org.jaxen package to represent any XPath implementation.
+          So this means that the XPath API of Jaxen is now polymorphic, the same interface can work with 
+          any model.
+        </p>
+        <p>
+           This now means that the org.jaxen.* package represents a purely interface based API to any XPath
+           engine. So it should be possible to implement XPath, FunctionContext, NamespaceContext, VariableContext
+           on any XPath engine if so desired.
+        </p>
+        <p>The XPath implementation for each model has now got a fully qualified class name. 
+          The following code describes how to instantiate an XPath object for each model.
+<pre>
+// for DOM
+XPath xpath = new DOMXPath( "//foo" );
+
+// for dom4j
+XPath xpath = new Dom4jXPath( "//foo" );
+
+// for Electric XML
+XPath xpath = new ElectricXPath( "//foo" );
+
+// for JDOM
+XPath xpath = new JDOMXPath( "//foo" );
+</pre>
+        </p>
+        <p>The XPath.valueOf() method is now deprecated, XPath.stringValueOf() should be used instead.
+        </p>
+        <p>Added new extension functions kindly provided by Mark Wilson. They are as follows...
+          <ul>
+            <li>upper-case() - converts the first argument to an upper case string using either the default Locale or the Locale specified by the second parameter</li>
+            <li>lower-case() - converts the first argument to a lower case string using either the default Locale or the Locale specified by the second parameter</li>
+            <li>ends-with() - evaluates true if the first string ends with the postfix</li>
+          </ul>
+          <p>Locales can be specified either using a variable which is a Locale object or using an xml:lang style string
+            which specifies the Locale via a language together with an optional country and variant such as 'fr', 'fr-CA' or 'es-ES-Traditional_WIN'.
+            e.g.
+          </p>
+<pre>
+upper-case( @foo, $myLocale )
+upper-case( /foo/bar, 'fr' )
+lower-case( foo, 'fr-CA' )
+upper-case( @foo, 'es-ES-Traditional_WIN' )
+</pre>
+        </p>
+        <p>The translate() function is now implemented - thanks to Jan for that!
+        </p>
+        <p>Some auxillary implementation detail changes, which shouldn't affect the public API in any way are as follows
+          <ul>
+            <li>The org.jaxen.JaXPath class has been removed. Now we have an org.jaxen.XPath interface its no longer required.</li>
+            <li>The org.jaxen.expr.XPath class has been renamed to org.jaxen.expr.XPathExpr to avoid confusion and to use a more consistent name.
+            Similarly the DefaultXPath class has been renamed to DefaultXPathExpr as well.</li>
+            <li>The very confusing jaSelect*() methods have gone from JaXPath and BaseXPath. All evaluation methods can take a Context object, null, a node or a node set.</li>
+          </ul>
+        </p>
+       </section>
+       
+      <section title="Jaxen 1.0 beta 8">
+        <p>
+          Initial beta development cycle.  Please see
+          CVS changelogs for up-to-date list of changes.
+        </p>
+       </section>
+    </section>
+
+    <section title="To Do List">
+      <ul>
+        <li>Implement a GenericXPath which could use reflection on the nodes passed into it to
+          choose the Navigator to use. So the same GenericXPath instance could be used
+          to evaluate XPaths on any object. This feature would be particularly useful
+          in <a href="http://jakarta.apache.org/taglibs/doc/standard-doc/intro.html">JSTL</a> 
+          since it would allow web developers to mix and match any
+          all XML models.
+        </li>
+        <li>The <code>format-number()</code> XSLT function is not yet implemented but would be useful. Any volunteers?
+        </li>
+        <li>While already Jaxen is pretty 
+        <a href="http://dom4j.org/benchmarks/xpath/index.html">fast</a>
+        but we are sure it could use some more tuning.
+        </li>
+        <li>selectSingleNode() and possibly the *ValueOf() methods should be return-fast
+          as a performance improvement.
+          For example selectSingleNode( "//foo" ) on a document with lots of <foo/>
+          elements would actually create a full nodeset of results then extract the first
+          element - rather than just returning as soon as the first one is found.
+        </li>
+        <li>Better user guides and examples!
+        </li>
+        <li>Any Locale sepecific functions, such as <code>upper-case()</code> 
+          and <code>lowercase-case()</code> could well follow the example of
+          <a href="http://www.w3.org/TR/xquery-operators/#func-upper-case">XSLT 2.0</a>
+          by using the <a href="http://www.unicode.org/unicode/reports/tr21/">Unicode case mappings</a>
+        </li>
+      </ul>
+    </section>
+
+    <section title="Known problems">    
+      <ul>
+        <li>The <code>lang()</code> XPath function is not yet implemented. Any volunteers?
+        </li>
+        <li><code>id()</code> function not implemented for most models, though it works fine for W3C DOM.</li>
+      </ul>
+    </section>
+
+    <section title="Contributors">    
+      <p>The following people have contributed to the Jaxen project. 
+      Many thanks to you all!</p>
+      <ul>
+        <li>Bob McWhirter (<a href="http://code.werken.com/">The Werken Company</a>)</li>
+        <li><a href="http://www.apache.org/~jstrachan/">James Strachan</a> (<a href="http://www.spiritsoft.com">SpiritSoft</a>)</li>
+        <li>David Megginson (<a href="http://megginson.com/">Megginson Technologies</a>)</li>
+        <li>Erwin Bolwidt</li>
+        <li>David Peterson</li>
+        <li>Mark A. Belonga</li>
+        <li>Christian Nentwich</li>
+        <li>Alexander Day Chaffee (<a href="http://www.purpletech.com">Purple Technology</a>)</li>
+        <li>Elliotte Rusty Harold (<a href="http://www.cafeconleche.org">Cafe con Leche</a>)</li>
+        <li>Mark Wilson (<a href="http://www.wilsoncom.de">WilsonCon</a>)</li>
+        <li>Jan Dvorak</li>
+        <li>J�r�me N�gre (<a href="http://e-xmlmedia.com">e-xmlmedia.com</a>)</li>
+      </ul>
+    </section>
+  </body>
+</document>
diff --git a/libjaxen-java/src/doc/style/document.xsl b/libjaxen-java/src/doc/style/document.xsl
new file mode 100644
index 0000000..a47faad
--- /dev/null
+++ b/libjaxen-java/src/doc/style/document.xsl
@@ -0,0 +1,202 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+
+  <xsl:template match="document">
+    <xsl:apply-templates/>
+  </xsl:template>
+
+  <xsl:template match="document/properties">
+
+    <table border="0" cellpadding="4" cellspacing="2">
+
+      <xsl:for-each select="author">
+
+        <tr>
+
+          <td valign="top"><b>Author:</b></td>
+
+          <td valign="top">
+
+            <xsl:value-of select="."/>&#xA0;
+
+            <xsl:if test="@email">
+
+              [ <a href="mailto:{@email}"><xsl:value-of select="@email"/></a> ]
+
+            </xsl:if>
+
+<!--
+
+            <xsl:if test="@ldap">
+
+              [ <a href="ldap://{@ldap}">LDAP</a> ]<br/>
+
+            </xsl:if>
+
+ -->
+
+          </td>
+
+        </tr>
+
+      </xsl:for-each>
+
+      <xsl:if test="abstract">
+
+        <tr>
+
+          <td valign="top"><b>Abstract:</b></td>
+
+          <td valign="top"><xsl:value-of select="abstract"/></td>
+
+        </tr>
+
+      </xsl:if>
+
+      <xsl:if test="status">
+
+        <tr>
+
+          <td valign="top"><b>Status:</b></td>
+
+          <td valign="top"><xsl:value-of select="status"/></td>
+
+        </tr>
+
+      </xsl:if>
+
+    </table><br/>
+
+  </xsl:template>
+  <!-- Process the document body -->
+
+  <xsl:template match="document/body">
+
+    <xsl:if test="/document/properties/title">
+
+      <br/>
+
+      <h1><xsl:value-of select="/document/properties/title"/></h1>
+
+    </xsl:if>
+
+    <xsl:if test="header">
+
+      <xsl:apply-templates select="header"/>
+
+    </xsl:if>
+    <xsl:for-each select=".//section">
+
+      <small>
+
+      <xsl:if test="@title">
+
+        <xsl:variable name="level" select="count(ancestor::*)"/>
+
+        <xsl:choose>
+
+          <xsl:when test='$level=2'>
+
+            <a href="#{@title}"><xsl:value-of select="@title"/></a><br/>
+
+          </xsl:when>
+
+          <xsl:when test='$level=3'>
+
+            &#xA0;&#xA0;&#xA0;&#xA0;<a href="#{@title}"><xsl:value-of select="@title"/></a><br/>
+
+          </xsl:when>
+
+        </xsl:choose>
+
+      </xsl:if>
+
+      </small>
+
+    </xsl:for-each>
+
+    <br/>
+    <xsl:apply-templates select="section"/>
+    <xsl:if test="footer">
+
+      <br/>
+
+      <xsl:apply-templates select="footer"/>
+
+    </xsl:if>
+
+  </xsl:template>
+  <!-- Process a section in the document. Nested sections are supported -->
+
+  <xsl:template match="document//section">
+
+    <xsl:variable name="level" select="count(ancestor::*)"/>
+
+    <xsl:choose>
+
+      <xsl:when test='$level=2'>
+
+        <a name="{@title}"><h2><xsl:value-of select="@title"/></h2></a>
+
+      </xsl:when>
+
+      <xsl:when test='$level=3'>
+
+        <a name="{@title}"><h3><xsl:value-of select="@title"/></h3></a>
+
+      </xsl:when>
+
+      <xsl:when test='$level=4'>
+
+        <a name="{@title}"><h4><xsl:value-of select="@title"/></h4></a>
+
+      </xsl:when>
+
+      <xsl:when test='$level>=5'>
+
+        <h5><xsl:copy-of select="@title"/></h5>
+
+      </xsl:when>
+
+    </xsl:choose>
+
+    <blockquote>
+
+      <xsl:apply-templates/>
+
+    </blockquote>
+
+  </xsl:template>
+  <!-- Paragraphs are separated with one empty line -->
+
+  <xsl:template match="p">
+
+    <p><xsl:apply-templates/><br/></p>
+
+  </xsl:template>
+  <!-- Paragraphs are separated with one empty line -->
+
+  <xsl:template match="body-note">
+
+    <blockquote><hr size="1" noshadow=""/><xsl:apply-templates/><hr size="1" noshadow=""/></blockquote>
+
+  </xsl:template>
+  <xsl:template match="nbsp">
+
+    &#xA0;
+
+  </xsl:template>
+
+  <xsl:template match="url">
+    <a href="{.}"><xsl:copy-of select="."/></a>
+  </xsl:template>
+
+  <xsl:template match="email">
+    <a href="mailto:{.}"><xsl:copy-of select="."/></a>
+  </xsl:template>
+
+
+</xsl:stylesheet>
+
+
diff --git a/libjaxen-java/src/doc/style/images/ball.gif b/libjaxen-java/src/doc/style/images/ball.gif
new file mode 100644
index 0000000..f64b12b
Binary files /dev/null and b/libjaxen-java/src/doc/style/images/ball.gif differ
diff --git a/libjaxen-java/src/doc/style/images/blank.gif b/libjaxen-java/src/doc/style/images/blank.gif
new file mode 100644
index 0000000..53c870f
Binary files /dev/null and b/libjaxen-java/src/doc/style/images/blank.gif differ
diff --git a/libjaxen-java/src/doc/style/images/blueball.gif b/libjaxen-java/src/doc/style/images/blueball.gif
new file mode 100644
index 0000000..f64b12b
Binary files /dev/null and b/libjaxen-java/src/doc/style/images/blueball.gif differ
diff --git a/libjaxen-java/src/doc/style/images/jars.gif b/libjaxen-java/src/doc/style/images/jars.gif
new file mode 100644
index 0000000..6edcf0e
Binary files /dev/null and b/libjaxen-java/src/doc/style/images/jars.gif differ
diff --git a/libjaxen-java/src/doc/style/images/logo.gif b/libjaxen-java/src/doc/style/images/logo.gif
new file mode 100644
index 0000000..5053b79
Binary files /dev/null and b/libjaxen-java/src/doc/style/images/logo.gif differ
diff --git a/libjaxen-java/src/doc/style/javadoc.css b/libjaxen-java/src/doc/style/javadoc.css
new file mode 100644
index 0000000..d6aad9d
--- /dev/null
+++ b/libjaxen-java/src/doc/style/javadoc.css
@@ -0,0 +1,27 @@
+/* Apache Javadoc style sheet */
+
+/* Page background color */
+body { background-color: #FFFFFF }
+
+/* Table colors */
+.TableHeadingColor     { background: #D0D0D0 }
+.TableSubHeadingColor  { background: #E0E0E0 }
+.TableRowColor         { background: #F9F9F9 }
+
+/* Navigation bar fonts and colors */
+.NavBarCell1    { background-color:#D0D0D0;}
+.NavBarCell1Rev { background-color:#A0A0A0;}
+.NavBarFont1    { font-family: Arial, Helvetica, sans-serif; color:#000000;}
+.NavBarFont1Rev { font-family: Arial, Helvetica, sans-serif; color:#FFFFFF;}
+.NavBarCell2    { font-family: Arial, Helvetica, sans-serif; background-color:#E0E0E0;}
+.NavBarCell3    { font-family: Arial, Helvetica, sans-serif; background-color:#F0F0F0;}
+
+/* Font used in left-hand frame lists */
+.FrameTitleFont   { font-size: normal; font-family: Helvetica, Arial, sans-serif }
+.FrameHeadingFont { font-size: normal; font-family: Helvetica, Arial, sans-serif }
+.FrameItemFont    { font-size: 10pt; font-family: Helvetica, Arial, sans-serif }
+
+/* Link colors styling */
+A:link { color: #0000A0 }          /* unvisited link */
+A:visited { color: #A00000 }       /* visited links */
+A:active { color: #00A000 }        /* active links */
diff --git a/libjaxen-java/src/doc/style/style.xsl b/libjaxen-java/src/doc/style/style.xsl
new file mode 100644
index 0000000..13c8299
--- /dev/null
+++ b/libjaxen-java/src/doc/style/style.xsl
@@ -0,0 +1,322 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+
+  <xsl:output method="html" indent="yes"/>
+
+  <xsl:template match="document">
+    <xsl:apply-templates/>
+  </xsl:template>
+
+  <xsl:template match="document/properties">
+
+    <table border="0" cellpadding="4" cellspacing="2">
+
+      <xsl:for-each select="author">
+
+        <tr>
+
+          <td valign="top"><b>Author:</b></td>
+
+          <td valign="top">
+
+            <xsl:value-of select="."/>&#xA0;
+
+            <xsl:if test="@email">
+
+              [ <a href="mailto:{@email}"><xsl:value-of select="@email"/></a> ]
+
+            </xsl:if>
+
+<!--
+
+            <xsl:if test="@ldap">
+
+              [ <a href="ldap://{@ldap}">LDAP</a> ]<br/>
+
+            </xsl:if>
+
+ -->
+
+          </td>
+
+        </tr>
+
+      </xsl:for-each>
+
+      <xsl:if test="abstract">
+
+        <tr>
+
+          <td valign="top"><b>Abstract:</b></td>
+
+          <td valign="top"><xsl:value-of select="abstract"/></td>
+
+        </tr>
+
+      </xsl:if>
+
+      <xsl:if test="status">
+
+        <tr>
+
+          <td valign="top"><b>Status:</b></td>
+
+          <td valign="top"><xsl:value-of select="status"/></td>
+
+        </tr>
+
+      </xsl:if>
+
+    </table><br/>
+
+  </xsl:template>
+  <!-- Process the document body -->
+
+  <xsl:template match="document/body">
+
+    <xsl:if test="/document/properties/title">
+
+      <br/>
+
+      <h1><xsl:value-of select="/document/properties/title"/></h1>
+
+    </xsl:if>
+
+    <xsl:if test="header">
+
+      <xsl:apply-templates select="header"/>
+
+    </xsl:if>
+    <xsl:for-each select=".//section">
+
+      <small>
+
+      <xsl:if test="@title">
+
+        <xsl:variable name="level" select="count(ancestor::*)"/>
+
+        <xsl:choose>
+
+          <xsl:when test='$level=2'>
+
+            <a href="#{@title}"><xsl:value-of select="@title"/></a><br/>
+
+          </xsl:when>
+
+          <xsl:when test='$level=3'>
+
+            &#xA0;&#xA0;&#xA0;&#xA0;<a href="#{@title}"><xsl:value-of select="@title"/></a><br/>
+
+          </xsl:when>
+
+        </xsl:choose>
+
+      </xsl:if>
+
+      </small>
+
+    </xsl:for-each>
+
+    <br/>
+    <xsl:apply-templates select="section"/>
+    <xsl:if test="footer">
+
+      <br/>
+
+      <xsl:apply-templates select="footer"/>
+
+    </xsl:if>
+
+  </xsl:template>
+
+
+  <!-- Process a section in the document. Nested sections are supported -->
+
+  <xsl:template match="document//section">
+
+    <xsl:variable name="level" select="count(ancestor::*)"/>
+
+    <xsl:choose>
+
+      <xsl:when test='$level=2'>
+
+        <a name="{@title}"><h2><xsl:value-of select="@title"/></h2></a>
+
+      </xsl:when>
+
+      <xsl:when test='$level=3'>
+
+        <a name="{@title}"><h3><xsl:value-of select="@title"/></h3></a>
+
+      </xsl:when>
+
+      <xsl:when test='$level=4'>
+
+        <a name="{@title}"><h4><xsl:value-of select="@title"/></h4></a>
+
+      </xsl:when>
+
+      <xsl:when test='$level>=5'>
+
+        <h5><xsl:copy-of select="@title"/></h5>
+
+      </xsl:when>
+
+    </xsl:choose>
+
+    <blockquote>
+
+      <xsl:apply-templates/>
+
+    </blockquote>
+
+  </xsl:template>
+  <!-- Paragraphs are separated with one empty line -->
+
+  <xsl:template match="p">
+
+    <p><xsl:apply-templates/><br/></p>
+
+  </xsl:template>
+  <!-- Paragraphs are separated with one empty line -->
+
+  <xsl:template match="body-note">
+
+    <blockquote><hr size="1" noshadow=""/><xsl:apply-templates/><hr size="1" noshadow=""/></blockquote>
+
+  </xsl:template>
+  <xsl:template match="nbsp">
+
+    &#xA0;
+
+  </xsl:template>
+
+  <xsl:template match="url">
+    <a href="{.}"><xsl:copy-of select="."/></a>
+  </xsl:template>
+
+  <xsl:template match="email">
+    <a href="mailto:{.}"><xsl:copy-of select="."/></a>
+  </xsl:template>
+
+  <xsl:template match="/">
+    <xsl:variable name="project" select="document('../project.xml')/project"/>
+    <html lang="en">
+    <head>
+      <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
+      <xsl:element name="META">
+        <xsl:attribute name="NAME">Keywords</xsl:attribute>
+        <xsl:attribute name="CONTENT">DOM4J, XML, Java, XML and Java, Open Source, 
+            XML software, Java software, XML API, Java API, XML parser, 
+            DOM, Document Object Model, SAX, XML Library, XPath, 
+            Java 2 Collections
+        </xsl:attribute>
+      </xsl:element>
+      <xsl:element name="META">
+        <xsl:attribute name="NAME">Description</xsl:attribute>
+        <xsl:attribute name="CONTENT">DOM4J is an Open Source XML framework 
+            for the Java Platform that combines the best of DOM and SAX 
+            together with integrated  XPath and Java 2 Collections support
+        </xsl:attribute>
+      </xsl:element>
+      <xsl:element name="META">
+        <xsl:attribute name="NAME">Copyright</xsl:attribute>
+        <xsl:attribute name="CONTENT">(c) 2001 MetaStuff Ltd.</xsl:attribute>
+      </xsl:element>
+
+      <xsl:choose>
+        <xsl:when test="/document/properties/title"><title><xsl:value-of select="/document/body/title"/></title></xsl:when>
+        <xsl:when test="/document/body/title"><title><xsl:value-of select="/document/body/title"/></title></xsl:when>
+        <xsl:otherwise><title><xsl:value-of select="$project/title"/></title></xsl:otherwise>
+      </xsl:choose>
+      <link rel="stylesheet" type="text/css" href="default.css"/>
+    </head>
+
+    <body>
+
+      <table border="0" cellpadding="0" cellspacing="0" width="100%">
+        <tr>
+          <td valign="top">          
+            <xsl:apply-templates select="$project/links"/>
+            <hr/>
+          </td>
+        </tr>
+
+        <tr>
+          <td>
+            <h1>
+              <xsl:choose>
+                <xsl:when test="/document/body/title"><xsl:value-of select="/document/body/title"/></xsl:when>
+                <xsl:otherwise><xsl:value-of select="$project/title"/></xsl:otherwise>
+              </xsl:choose>
+            </h1>
+           </td>
+        </tr>
+
+        <tr>
+          <td>
+             <xsl:apply-templates select="document/body"/>
+             <br/>
+             <hr/>
+          </td>
+        </tr>
+
+        <tr>
+          <td valign="top">
+            <xsl:apply-templates select="$project/links"/>
+            <hr/>
+          </td>
+        </tr>
+
+        <xsl:if test="$project/notice">
+          <tr>
+            <td align="center">
+              <xsl:for-each select="$project/notice">
+                <small><xsl:copy-of select="."/><br/>&#xA0;<br/></small>
+              </xsl:for-each>
+            </td>
+          </tr>
+        </xsl:if>
+
+      </table>
+
+    </body>
+    </html>
+  </xsl:template>
+
+
+  <!-- UL is processed into a table using graphical bullets -->
+  <xsl:template match="ul">
+    <table border="0" cellpadding="2" cellspacing="2">
+      <tr><td colspan="2" height="5"></td></tr>
+      <xsl:apply-templates/>
+    </table>
+  </xsl:template>
+
+  <xsl:template match="ul/li">
+    <tr>
+      <td align="left" valign="top">
+        <img src="style/images/blueball.gif" alt="*"/>
+     </td>
+      <td align="left" valign="top"><xsl:apply-templates/></td>
+    </tr>
+  </xsl:template>
+
+  <xsl:template match="section">
+    <br />
+  </xsl:template>
+
+  <xsl:template match="br">
+    <br />
+  </xsl:template>
+
+  <xsl:template match='@* | node()'>
+    <xsl:copy>
+      <xsl:apply-templates select='@* | node()'/>
+    </xsl:copy>
+  </xsl:template>
+
+
+</xsl:stylesheet>
+
+
diff --git a/libjaxen-java/src/java/main/org/jaxen/BaseXPath.java b/libjaxen-java/src/java/main/org/jaxen/BaseXPath.java
new file mode 100644
index 0000000..6ac43f9
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/BaseXPath.java
@@ -0,0 +1,708 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/BaseXPath.java,v 1.49 2006/02/05 21:47:41 elharo Exp $
+ * $Revision: 1.49 $
+ * $Date: 2006/02/05 21:47:41 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: BaseXPath.java,v 1.49 2006/02/05 21:47:41 elharo Exp $
+ */
+
+
+package org.jaxen;
+
+import java.io.Serializable;
+import java.util.List;
+
+import org.jaxen.expr.Expr;
+import org.jaxen.expr.XPathExpr;
+import org.jaxen.function.BooleanFunction;
+import org.jaxen.function.NumberFunction;
+import org.jaxen.function.StringFunction;
+import org.jaxen.saxpath.SAXPathException;
+import org.jaxen.saxpath.XPathReader;
+import org.jaxen.saxpath.helpers.XPathReaderFactory;
+import org.jaxen.util.SingletonList;
+
+/** Base functionality for all concrete, implementation-specific XPaths.
+ *
+ *  <p>
+ *  This class provides generic functionality for further-defined
+ *  implementation-specific XPaths.
+ *  </p>
+ *
+ *  <p>
+ *  If you want to adapt the Jaxen engine so that it can traverse your own
+ *  object model, then this is a good base class to derive from.
+ *  Typically you only really need to provide your own 
+ *  {@link org.jaxen.Navigator} implementation.
+ *  </p>
+ *
+ *  @see org.jaxen.dom4j.Dom4jXPath XPath for dom4j
+ *  @see org.jaxen.jdom.JDOMXPath   XPath for JDOM
+ *  @see org.jaxen.dom.DOMXPath     XPath for W3C DOM
+ *
+ *  @author <a href="mailto:bob at werken.com">bob mcwhirter</a>
+ *  @author <a href="mailto:jstrachan at apache.org">James Strachan</a>
+ */
+public class BaseXPath implements XPath, Serializable
+{
+    /** Original expression text. */
+    private String exprText;
+
+    /** the parsed form of the XPath expression */
+    private XPathExpr xpath;
+    
+    /** the support information and function, namespace and variable contexts */
+    private ContextSupport support;
+
+    /** the implementation-specific Navigator for retrieving XML nodes **/
+    private Navigator navigator;
+    
+    /** Construct given an XPath expression string. 
+     *
+     *  @param xpathExpr the XPath expression
+     *
+     *  @throws JaxenException if there is a syntax error while
+     *          parsing the expression
+     */
+    protected BaseXPath(String xpathExpr) throws JaxenException
+    {
+        try
+        {
+            XPathReader reader = XPathReaderFactory.createReader();
+            JaxenHandler handler = new JaxenHandler();
+            reader.setXPathHandler( handler );
+            reader.parse( xpathExpr );
+            this.xpath = handler.getXPathExpr();
+        }
+        catch (org.jaxen.saxpath.XPathSyntaxException e)
+        {
+            throw new org.jaxen.XPathSyntaxException( e );
+        }
+        catch (SAXPathException e)
+        {
+            throw new JaxenException( e );
+        }
+
+        this.exprText = xpathExpr;
+    }
+
+    /** Construct given an XPath expression string.
+     *
+     *  @param xpathExpr the XPath expression
+     *
+     *  @param navigator the XML navigator to use
+     *
+     *  @throws JaxenException if there is a syntax error while
+     *          parsing the expression
+     */
+    public BaseXPath(String xpathExpr, Navigator navigator) throws JaxenException
+    {
+        this( xpathExpr );
+        this.navigator = navigator;
+    }
+
+    /** Evaluate this XPath against a given context.
+     *  The context of evaluation may be any object type
+     *  the navigator recognizes as a node.
+     *  The return value is either a <code>String</code>,
+     *  <code>Double</code>, <code>Boolean</code>, or <code>List</code>
+     *  of nodes.
+     *
+     *  <p>
+     *  When using this method, one must be careful to
+     *  test the class of the returned object.  If the returned 
+     *  object is a list, then the items in this 
+     *  list will be the actual <code>Document</code>,
+     *  <code>Element</code>, <code>Attribute</code>, etc. objects
+     *  as defined by the concrete XML object-model implementation,
+     *  directly from the context document.  This method <strong>does
+     *  not return <em>copies</em> of anything</strong>, but merely 
+     *  returns references to objects within the source document.
+     *  </p>
+     *  
+     * @param context the node, node-set or Context object for evaluation. 
+     *      This value can be null.
+     *
+     * @return the result of evaluating the XPath expression
+     *          against the supplied context
+     * @throws JaxenException if an XPath error occurs during expression evaluation
+     * @throws ClassCastException if the context is not a node
+     */
+    public Object evaluate(Object context) throws JaxenException
+    {
+        List answer = selectNodes(context);
+
+        if ( answer != null
+             &&
+             answer.size() == 1 )
+        {
+            Object first = answer.get(0);
+
+            if ( first instanceof String
+                 ||
+                 first instanceof Number
+                 ||
+                 first instanceof Boolean ) 
+            {
+                return first;
+            }
+        }
+        return answer;
+    }
+    
+    /** Select all nodes that are selected by this XPath
+     *  expression. If multiple nodes match, multiple nodes
+     *  will be returned. Nodes will be returned
+     *  in document-order, as defined by the XPath
+     *  specification. If the expression selects a non-node-set
+     *  (i.e. a number, boolean, or string) then a List
+     *  containing just that one object is returned.
+     *  </p>
+     *
+     * @param node the node, node-set or Context object for evaluation. 
+     *     This value can be null.
+     *
+     * @return the node-set of all items selected
+     *          by this XPath expression
+     * @throws JaxenException if an XPath error occurs during expression evaluation
+     *
+     * @see #selectNodesForContext
+     */
+    public List selectNodes(Object node) throws JaxenException
+    {
+        Context context = getContext( node );
+        return selectNodesForContext( context );
+    }
+
+    /** Select only the first node selected by this XPath
+     *  expression.  If multiple nodes match, only one node will be
+     *  returned. The selected node will be the first
+     *  selected node in document-order, as defined by the XPath
+     *  specification.
+     *  </p>
+     *
+     * @param node the node, node-set or Context object for evaluation. 
+     *     This value can be null.
+     *
+     * @return the node-set of all items selected
+     *          by this XPath expression
+     * @throws JaxenException if an XPath error occurs during expression evaluation
+     *
+     * @see #selectNodes
+     */
+    public Object selectSingleNode(Object node) throws JaxenException
+    {
+        List results = selectNodes( node );
+
+        if ( results.isEmpty() )
+        {
+            return null;
+        }
+
+        return results.get( 0 );
+    }
+
+    /**
+     * Returns the XPath string-value of the argument node.
+     * 
+     * @param node the node whose value to take
+     * @return the XPath string value of this node
+     * @throws JaxenException if an XPath error occurs during expression evaluation
+     * @deprecated replaced by {@link #stringValueOf}
+     */
+    public String valueOf(Object node) throws JaxenException
+    {
+        return stringValueOf( node );
+    }
+
+    /** Retrieves the string-value of the result of
+     *  evaluating this XPath expression when evaluated 
+     *  against the specified context.
+     *
+     *  <p>
+     *  The string-value of the expression is determined per
+     *  the <code>string(..)</code> core function defined
+     *  in the XPath specification.  This means that an expression
+     *  that selects zero nodes will return the empty string,
+     *  while an expression that selects one-or-more nodes will
+     *  return the string-value of the first node.
+     *  </p>
+     *
+     * @param node the node, node-set or Context object for evaluation. This value can be null.
+     *
+     * @return the string-value of the result of evaluating this expression with the specified context node
+     * @throws JaxenException if an XPath error occurs during expression evaluation
+     */
+    public String stringValueOf(Object node) throws JaxenException
+    {
+        Context context = getContext( node );
+        
+        Object result = selectSingleNodeForContext( context );
+
+        if ( result == null )
+        {
+            return "";
+        }
+
+        return StringFunction.evaluate( result,
+                                        context.getNavigator() );
+    }
+
+    /** Retrieve a boolean-value interpretation of this XPath
+     *  expression when evaluated against a given context.
+     *
+     *  <p>
+     *  The boolean-value of the expression is determined per
+     *  the <code>boolean(..)</code> function defined
+     *  in the XPath specification.  This means that an expression
+     *  that selects zero nodes will return <code>false</code>,
+     *  while an expression that selects one or more nodes will
+     *  return <code>true</code>.
+     *  </p>
+     *
+     * @param node the node, node-set or Context object for evaluation. This value can be null.
+     *
+     * @return the boolean-value of the result of evaluating this expression with the specified context node
+     * @throws JaxenException if an XPath error occurs during expression evaluation
+     */
+    public boolean booleanValueOf(Object node) throws JaxenException
+    {
+        Context context = getContext( node );
+        List result = selectNodesForContext( context );
+        if ( result == null ) return false;
+        return BooleanFunction.evaluate( result, context.getNavigator() ).booleanValue();
+    }
+
+    /** Retrieve a number-value interpretation of this XPath
+     *  expression when evaluated against a given context.
+     *
+     *  <p>
+     *  The number-value of the expression is determined per
+     *  the <code>number(..)</code> core function as defined
+     *  in the XPath specification. This means that if this
+     *  expression selects multiple nodes, the number-value
+     *  of the first node is returned.
+     *  </p>
+     *
+     * @param node the node, node-set or Context object for evaluation. This value can be null.
+     *
+     * @return a <code>Double</code> indicating the numeric value of
+     *      evaluating this expression against the specified context
+     * @throws JaxenException if an XPath error occurs during expression evaluation
+     */
+    public Number numberValueOf(Object node) throws JaxenException
+    {
+        Context context = getContext( node );
+        Object result = selectSingleNodeForContext( context );
+        return NumberFunction.evaluate( result,
+                                        context.getNavigator() );
+    }
+
+    // Helpers
+
+    /** Add a namespace prefix-to-URI mapping for this XPath
+     *  expression.
+     *
+     *  <p>
+     *  Namespace prefix-to-URI mappings in an XPath are independent
+     *  of those used within any document.  Only the mapping explicitly
+     *  added to this XPath will be available for resolving the
+     *  XPath expression.
+     *  </p>
+     *
+     *  <p>
+     *  This is a convenience method for adding mappings to the
+     *  default {@link NamespaceContext} in place for this XPath.
+     *  If you have installed a custom <code>NamespaceContext</code>
+     *  that is not a <code>SimpleNamespaceContext</code>,
+     *  then this method will throw a <code>JaxenException</code>.
+     *  </p>
+     *
+     *  @param prefix the namespace prefix
+     *  @param uri the namespace URI
+     *
+     *  @throws JaxenException if the <code>NamespaceContext</code>
+     *          used by this XPath is not a <code>SimpleNamespaceContext</code>
+     */
+    public void addNamespace(String prefix,
+                             String uri) throws JaxenException
+    {
+        NamespaceContext nsContext = getNamespaceContext();
+        if ( nsContext instanceof SimpleNamespaceContext )
+        {
+            ((SimpleNamespaceContext)nsContext).addNamespace( prefix,
+                                                              uri );
+            return;
+        }
+
+        throw new JaxenException("Operation not permitted while using a non-simple namespace context.");
+    }
+
+
+    // ------------------------------------------------------------
+    // ------------------------------------------------------------
+    //     Properties
+    // ------------------------------------------------------------
+    // ------------------------------------------------------------
+
+    
+    /** Set a <code>NamespaceContext</code> for use with this
+     *  XPath expression.
+     *
+     *  <p>
+     *  A <code>NamespaceContext</code> is responsible for translating
+     *  namespace prefixes within the expression into namespace URIs.
+     *  </p>
+     *
+     *  @param namespaceContext the <code>NamespaceContext</code> to
+     *         install for this expression
+     *
+     *  @see NamespaceContext
+     *  @see NamespaceContext#translateNamespacePrefixToUri
+     */
+    public void setNamespaceContext(NamespaceContext namespaceContext)
+    {
+        getContextSupport().setNamespaceContext(namespaceContext);
+    }
+
+    /** Set a <code>FunctionContext</code> for use with this XPath
+     *  expression.
+     *
+     *  <p>
+     *  A <code>FunctionContext</code> is responsible for resolving
+     *  all function calls used within the expression.
+     *  </p>
+     *
+     *  @param functionContext the <code>FunctionContext</code> to
+     *         install for this expression
+     *
+     *  @see FunctionContext
+     *  @see FunctionContext#getFunction
+     */
+    public void setFunctionContext(FunctionContext functionContext)
+    {
+        getContextSupport().setFunctionContext(functionContext);
+    }
+
+    /** Set a <code>VariableContext</code> for use with this XPath
+     *  expression.
+     *
+     *  <p>
+     *  A <code>VariableContext</code> is responsible for resolving
+     *  all variables referenced within the expression.
+     *  </p>
+     *
+     *  @param variableContext The <code>VariableContext</code> to
+     *         install for this expression
+     *
+     *  @see VariableContext
+     *  @see VariableContext#getVariableValue
+     */
+    public void setVariableContext(VariableContext variableContext)
+    {
+        getContextSupport().setVariableContext(variableContext);
+    }
+
+    /** Retrieve the <code>NamespaceContext</code> used by this XPath
+     *  expression.
+     *
+     *  <p>
+     *  A <code>NamespaceContext</code> is responsible for mapping
+     *  prefixes used within the expression to namespace URIs.
+     *  </p>
+     *
+     *  <p>
+     *  If this XPath expression has not previously had a <code>NamespaceContext</code>
+     *  installed, a new default <code>NamespaceContext</code> will be created,
+     *  installed and returned.
+     *  </p>
+     *
+     *  @return the <code>NamespaceContext</code> used by this expression
+     *
+     *  @see NamespaceContext
+     */
+    public NamespaceContext getNamespaceContext()
+    {
+        return getContextSupport().getNamespaceContext();
+    }
+
+    /** Retrieve the <code>FunctionContext</code> used by this XPath
+     *  expression.
+     *
+     *  <p>
+     *  A <code>FunctionContext</code> is responsible for resolving
+     *  all function calls used within the expression.
+     *  </p>
+     *
+     *  <p>
+     *  If this XPath expression has not previously had a <code>FunctionContext</code>
+     *  installed, a new default <code>FunctionContext</code> will be created,
+     *  installed and returned.
+     *  </p>
+     *
+     *  @return the <code>FunctionContext</code> used by this expression
+     *
+     *  @see FunctionContext
+     */
+    public FunctionContext getFunctionContext()
+    {
+        return getContextSupport().getFunctionContext();
+    }
+
+    /** Retrieve the <code>VariableContext</code> used by this XPath
+     *  expression.
+     *
+     *  <p>
+     *  A <code>VariableContext</code> is responsible for resolving
+     *  all variables referenced within the expression.
+     *  </p>
+     *
+     *  <p>
+     *  If this XPath expression has not previously had a <code>VariableContext</code>
+     *  installed, a new default <code>VariableContext</code> will be created,
+     *  installed and returned.
+     *  </p>
+     *  
+     *  @return the <code>VariableContext</code> used by this expression
+     *
+     *  @see VariableContext
+     */
+    public VariableContext getVariableContext()
+    {
+        return getContextSupport().getVariableContext();
+    }
+    
+    
+    /** Retrieve the root expression of the internal
+     *  compiled form of this XPath expression.
+     *
+     *  <p>
+     *  Internally, Jaxen maintains a form of Abstract Syntax
+     *  Tree (AST) to represent the structure of the XPath expression.
+     *  This is normally not required during normal consumer-grade
+     *  usage of Jaxen.  This method is provided for hard-core users
+     *  who wish to manipulate or inspect a tree-based version of
+     *  the expression.
+     *  </p>
+     *
+     *  @return the root of the AST of this expression
+     */
+    public Expr getRootExpr() 
+    {
+        return xpath.getRootExpr();
+    }
+    
+    /** Return the original expression text.
+     *
+     *  @return the normalized XPath expression string
+     */
+    public String toString()
+    {
+        return this.exprText;
+    }
+
+    /** Returns a string representation of the parse tree.
+     *
+     *  @return a string representation of the parse tree.
+     */
+    public String debug()
+    {
+        return this.xpath.toString();
+    }
+    
+    // ------------------------------------------------------------
+    // ------------------------------------------------------------
+    //     Implementation methods
+    // ------------------------------------------------------------
+    // ------------------------------------------------------------
+
+    
+    /** Create a {@link Context} wrapper for the provided
+     *  implementation-specific object.
+     *
+     *  @param node the implementation-specific object 
+     *         to be used as the context
+     *
+     *  @return a <code>Context</code> wrapper around the object
+     */
+    protected Context getContext(Object node)
+    {
+        if ( node instanceof Context )
+        {
+            return (Context) node;
+        }
+
+        Context fullContext = new Context( getContextSupport() );
+
+        if ( node instanceof List )
+        {
+            fullContext.setNodeSet( (List) node );
+        }
+        else
+        {
+            List list = new SingletonList(node);
+            fullContext.setNodeSet( list );
+        }
+
+        return fullContext;
+    }
+
+    /** Retrieve the {@link ContextSupport} aggregation of
+     *  <code>NamespaceContext</code>, <code>FunctionContext</code>,
+     *  <code>VariableContext</code>, and {@link Navigator}.
+     *
+     *  @return aggregate <code>ContextSupport</code> for this
+     *          XPath expression
+     */
+    protected ContextSupport getContextSupport()
+    {
+        if ( support == null )
+        {
+            support = new ContextSupport( 
+                createNamespaceContext(),
+                createFunctionContext(),
+                createVariableContext(),
+                getNavigator() 
+            );
+        }
+
+        return support;
+    }
+
+    /** Retrieve the XML object-model-specific {@link Navigator} 
+     *  for us in evaluating this XPath expression.
+     *
+     *  @return the implementation-specific <code>Navigator</code>
+     */
+    public Navigator getNavigator()
+    {
+        return navigator;
+    }
+    
+    
+
+    // ------------------------------------------------------------
+    // ------------------------------------------------------------
+    //     Factory methods for default contexts
+    // ------------------------------------------------------------
+    // ------------------------------------------------------------
+
+    /** Create a default <code>FunctionContext</code>.
+     *
+     *  @return a default <code>FunctionContext</code>
+     */
+    protected FunctionContext createFunctionContext()
+    {
+        return XPathFunctionContext.getInstance();
+    }
+    
+    /** Create a default <code>NamespaceContext</code>.
+     *
+     *  @return a default <code>NamespaceContext</code> instance
+     */
+    protected NamespaceContext createNamespaceContext()
+    {
+        return new SimpleNamespaceContext();
+    }
+    
+    /** Create a default <code>VariableContext</code>.
+     *
+     *  @return a default <code>VariableContext</code> instance
+     */
+    protected VariableContext createVariableContext()
+    {
+        return new SimpleVariableContext();
+    }
+    
+    /** Select all nodes that match this XPath
+     *  expression on the given Context object. 
+     *  If multiple nodes match, multiple nodes
+     *  will be returned in document-order, as defined by the XPath
+     *  specification. If the expression selects a non-node-set
+     *  (i.e. a number, boolean, or string) then a List
+     *  containing just that one object is returned.
+     *  </p>
+     *
+     * @param context the Context which gets evaluated
+     *
+     * @return the node-set of all items selected
+     *          by this XPath expression
+     * @throws JaxenException if an XPath error occurs during expression evaluation
+     *
+     */
+    protected List selectNodesForContext(Context context) throws JaxenException
+    {
+        List list = this.xpath.asList( context );
+        return list;
+        
+    }
+ 
+
+    /** Return only the first node that is selected by this XPath
+     *  expression.  If multiple nodes match, only one node will be
+     *  returned. The selected node will be the first
+     *  selected node in document-order, as defined by the XPath
+     *  specification. If the XPath expression selects a double,
+     *  String, or boolean, then that object is returned.
+     *  </p>
+     *
+     * @param context the Context against which this expression is evaluated
+     *
+     * @return the first node in document order of all nodes selected
+     *          by this XPath expression
+     * @throws JaxenException if an XPath error occurs during expression evaluation
+     *
+     *  @see #selectNodesForContext
+     */
+    protected Object selectSingleNodeForContext(Context context) throws JaxenException
+    {
+        List results = selectNodesForContext( context );
+
+        if ( results.isEmpty() )
+        {
+            return null;
+        }
+
+        return results.get( 0 );
+    }
+    
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/Context.java b/libjaxen-java/src/java/main/org/jaxen/Context.java
new file mode 100644
index 0000000..76fafdd
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/Context.java
@@ -0,0 +1,274 @@
+package org.jaxen;
+
+/*
+ $Id: Context.java,v 1.17 2006/09/07 15:47:03 elharo Exp $
+
+ Copyright 2003 The Werken Company. All Rights Reserved.
+ 
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+  * Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+
+  * Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+
+  * Neither the name of the Jaxen Project nor the names of its
+    contributors may be used to endorse or promote products derived 
+    from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ */
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/** Wrapper around implementation-specific objects used
+ *  as the context of an expression evaluation.
+ *
+ *  <p>
+ *  <strong>NOTE:</strong> This class is not typically used directly,
+ *  but is exposed for writers of implementation-specific
+ *  XPath packages.
+ *  </p>
+ *
+ *  <p>
+ *  The <code>Context</code> bundles utilities together
+ *  for evaluation of the expression.  It wraps the provided
+ *  objects for ease-of-passage through the expression 
+ *  <acronym title="Abstract Syntax Tree">AST</acronym>.
+ *  </p>
+ *
+ *  @see ContextSupport
+ *  @see BaseXPath
+ *  @see org.jaxen.dom4j.Dom4jXPath XPath for dom4j
+ *  @see org.jaxen.jdom.JDOMXPath  XPath for JDOM
+ *  @see org.jaxen.dom.DOMXPath   XPath for W3C DOM
+ *
+ *  @author <a href="mailto:bob at werken.com">bob mcwhirter</a>
+ */
+public class Context
+    implements Serializable
+{
+    /**
+     * 
+     */
+    private static final long serialVersionUID = 2315979994685591055L;
+
+    // ----------------------------------------------------------------------
+    //     Instance members
+    // ----------------------------------------------------------------------
+
+    /** Context-support */
+    private ContextSupport contextSupport;
+
+    /** Context node-set */
+    private List nodeSet;
+
+    /** Current context size */
+    private int size;
+
+    /** Current context position */
+    private int position;
+
+    // ----------------------------------------------------------------------
+    //     Constructors
+    // ----------------------------------------------------------------------
+
+    /** Create a new context.
+     *
+     *  @param contextSupport the context-support
+     */
+    public Context(ContextSupport contextSupport)
+    {
+        this.contextSupport = contextSupport;
+        this.nodeSet        = Collections.EMPTY_LIST;
+        this.size = 0;
+        // XXX What should position be?
+    }
+    
+    // ----------------------------------------------------------------------
+    //     Instance methods
+    // ----------------------------------------------------------------------
+
+    /** Set the context node-set, and sets the current context size to the size 
+     * of this node-set. The actual list is stored in this object. A copy
+     * is not made.
+     *
+     *  @param nodeSet the context node-set
+     */
+    public void setNodeSet(List nodeSet)
+    {
+        this.nodeSet = nodeSet;
+        this.size    = nodeSet.size();
+        // XXX How should we set position?
+    }
+
+    /** Retrieve the context node-set. This is a live list. It is not a copy.
+     *
+     *  @return the context node-set
+     */
+    public List getNodeSet()
+    {
+        return this.nodeSet;
+    }
+
+    /** Set the <code>ContextSupport</code>.
+     *
+     *  @param contextSupport the context-support
+     */
+    public void setContextSupport(ContextSupport contextSupport)
+    {
+        this.contextSupport = contextSupport;
+    }
+
+    /** Retrieve the <code>ContextSupport</code>.
+     *
+     *  @return the context-support
+     */
+    public ContextSupport getContextSupport()
+    {
+        return this.contextSupport;
+    }
+
+    /** Retrieve the current <code>Navigator</code>.
+     *
+     *  @return the navigator
+     */
+    public Navigator getNavigator()
+    {
+        return getContextSupport().getNavigator();
+    }
+
+    /** Translate a namespace prefix to its URI.
+     *
+     *  @param prefix the prefix
+     *
+     *  @return the namespace URI mapped to the prefix
+     */
+    public String translateNamespacePrefixToUri(String prefix)
+    {
+        return getContextSupport().translateNamespacePrefixToUri( prefix );
+    }
+
+    /** Retrieve a variable value.
+     *
+     *  @param namespaceURI the function namespace URI
+     *  @param prefix the function prefix
+     *  @param localName the function name
+     *
+     *  @return the variable value
+     *
+     *  @throws UnresolvableException if unable to locate a bound variable
+     */
+    public Object getVariableValue(String namespaceURI,
+                                   String prefix,
+                                   String localName)
+        throws UnresolvableException
+    {
+        return getContextSupport().getVariableValue( namespaceURI,
+                                                     prefix,
+                                                     localName );
+    }
+
+    /** Retrieve a <code>Function</code>.
+     *
+     *  @param namespaceURI the function namespace URI
+     *  @param prefix the function prefix
+     *  @param localName the function name
+     *
+     *  @return the function object
+     *
+     *  @throws UnresolvableException if unable to locate a bound function
+     */
+    public Function getFunction(String namespaceURI,
+                                String prefix,
+                                String localName)
+        throws UnresolvableException
+    {
+        return getContextSupport().getFunction( namespaceURI,
+                                                prefix,
+                                                localName );
+    }
+
+    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
+    //     Properties
+    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
+
+    /** Set the current size in the context node-set.
+     *
+     *  @param size the size
+     */
+    public void setSize(int size)
+    {
+        this.size = size;
+    }
+
+    /** Retrieve the size of the current context node-set.
+     *
+     *  @return the size
+     */
+    public int getSize()
+    {
+        return this.size;
+    }
+
+    /** Set the current position in the context node-set.
+     *
+     *  @param position the position
+     */
+    public void setPosition(int position)
+    {
+        this.position = position;
+    }
+
+    /** Retrieve current position in the context node-set.
+     *
+     *  @return the current position
+     */
+    public int getPosition()
+    {
+        return this.position;
+    }
+
+    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
+    //     Helpers
+    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
+
+    /** Create a type-safe shallow copy.
+     *
+     *  @return the duplicate
+     */
+    public Context duplicate()
+    {
+        Context dupe = new Context( getContextSupport() );
+
+        List thisNodeSet = getNodeSet();
+
+        if ( thisNodeSet != null )
+        {
+            List dupeNodeSet = new ArrayList( thisNodeSet.size() );
+            dupeNodeSet.addAll( thisNodeSet );
+            dupe.setNodeSet( dupeNodeSet );
+            // XXX should set the size of the duplicate
+        }
+
+        return dupe;
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/ContextSupport.java b/libjaxen-java/src/java/main/org/jaxen/ContextSupport.java
new file mode 100644
index 0000000..efd3f01
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/ContextSupport.java
@@ -0,0 +1,250 @@
+package org.jaxen;
+
+/*
+ $Id: ContextSupport.java,v 1.13 2006/06/03 20:06:06 elharo Exp $
+
+ Copyright 2003 The Werken Company. All Rights Reserved.
+ 
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+  * Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+
+  * Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+
+  * Neither the name of the Jaxen Project nor the names of its
+    contributors may be used to endorse or promote products derived 
+    from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ */
+
+import java.io.Serializable;
+
+/** Supporting context information for resolving
+ *  namespace prefixes, functions, and variables.
+ * 
+ *  <p>
+ *  <strong>NOTE:</strong> This class is not typically used directly,
+ *  but is exposed for writers of implementation-specific
+ *  XPath packages.
+ *  </p>
+ *
+ *  @see org.jaxen.dom4j.Dom4jXPath XPath for dom4j
+ *  @see org.jaxen.jdom.JDOMXPath   XPath for JDOM
+ *  @see org.jaxen.dom.DOMXPath     XPath for W3C DOM
+ *
+ *  @author <a href="mailto:bob at eng.werken.com">bob mcwhirter</a>
+ *
+ *  @version $Id: ContextSupport.java,v 1.13 2006/06/03 20:06:06 elharo Exp $
+ */
+public class ContextSupport implements Serializable {
+
+    /**
+     * 
+     */
+    private static final long serialVersionUID = 4494082174713652559L;
+
+    /** Function context. */
+    private transient FunctionContext functionContext;
+    
+    /** Namespace context. */
+    private NamespaceContext namespaceContext;
+
+    /** Variable context. */
+    private VariableContext variableContext;
+    
+    /** Model navigator. */
+    private Navigator navigator;
+
+    // ----------------------------------------------------------------------
+    //     Constructors
+    // ----------------------------------------------------------------------
+    
+    /** Construct an empty <code>ContextSupport</code>.
+     */
+    public ContextSupport()
+    {
+        // intentionally left blank
+    }
+
+    /** Create a new ContextSupport object.
+     *
+     *  @param namespaceContext the NamespaceContext
+     *  @param functionContext the FunctionContext
+     *  @param variableContext the VariableContext
+     *  @param navigator the model navigator
+     */
+    public ContextSupport(NamespaceContext namespaceContext,
+                          FunctionContext functionContext,
+                          VariableContext variableContext,
+                          Navigator navigator)
+    {
+        setNamespaceContext( namespaceContext );
+        setFunctionContext( functionContext );
+        setVariableContext( variableContext );
+
+        this.navigator = navigator;
+    }
+
+    // ----------------------------------------------------------------------
+    //     Instance methods
+    // ----------------------------------------------------------------------
+
+    /** Set the <code>NamespaceContext</code>.
+     *
+     *  @param namespaceContext the namespace context
+     */
+    public void setNamespaceContext(NamespaceContext namespaceContext)
+    {
+        this.namespaceContext = namespaceContext;
+    }
+
+    /** Retrieve the <code>NamespaceContext</code>.
+     *
+     *  @return the namespace context
+     */
+    public NamespaceContext getNamespaceContext()
+    {
+        return this.namespaceContext;
+    }
+
+    /** Set the <code>FunctionContext</code>.
+     *
+     *  @param functionContext the function context
+     */
+    public void setFunctionContext(FunctionContext functionContext)
+    {
+        this.functionContext  = functionContext;
+    }
+
+    /** Retrieve the <code>FunctionContext</code>.
+     *
+     *  @return the function context
+     */
+    public FunctionContext getFunctionContext()
+    {
+        return this.functionContext;
+    }
+
+    /** Set the <code>VariableContext</code>.
+     *
+     *  @param variableContext the variable context
+     */
+    public void setVariableContext(VariableContext variableContext)
+    {
+        this.variableContext  = variableContext;
+    }
+
+    /** Retrieve the <code>VariableContext</code>.
+     *
+     *  @return the variable context
+     */
+    public VariableContext getVariableContext()
+    {
+        return this.variableContext;
+    }
+
+    /** Retrieve the <code>Navigator</code>.
+     *
+     *  @return the navigator
+     */
+    public Navigator getNavigator()
+    {
+        return this.navigator;
+    }
+
+    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
+
+    /** Translate a namespace prefix to its URI.
+     *
+     *  @param prefix The prefix
+     *
+     *  @return the namespace URI mapped to the prefix
+     */
+    public String translateNamespacePrefixToUri(String prefix)
+    {
+        
+        if ("xml".equals(prefix)) {
+            return "http://www.w3.org/XML/1998/namespace";
+        }
+        NamespaceContext context = getNamespaceContext();
+
+        if ( context != null )
+        {
+            return context.translateNamespacePrefixToUri( prefix );
+        }
+
+        return null;
+    }
+
+    /** Retrieve a variable value.
+     *
+     *  @param namespaceURI the function namespace URI
+     *  @param prefix the function prefix
+     *  @param localName the function name
+     *
+     *  @return the variable value.
+     *
+     *  @throws UnresolvableException if unable to locate a bound variable.
+     */
+    public Object getVariableValue( String namespaceURI,
+                                    String prefix,
+                                    String localName )
+        throws UnresolvableException
+    {
+        VariableContext context = getVariableContext();
+
+        if ( context != null )
+        {
+            return context.getVariableValue( namespaceURI, prefix, localName );
+        }
+        else
+        {
+            throw new UnresolvableException( "No variable context installed" );
+        }
+    }
+
+    /** Retrieve a <code>Function</code>.
+     *
+     *  @param namespaceURI the function namespace URI
+     *  @param prefix the function prefix
+     *  @param localName the function name
+     *
+     *  @return the function object
+     *
+     *  @throws UnresolvableException if unable to locate a bound function
+     */
+    public Function getFunction( String namespaceURI,
+                                 String prefix,
+                                 String localName )
+        throws UnresolvableException
+    {
+        FunctionContext context = getFunctionContext();
+
+        if ( context != null )
+        {
+            return context.getFunction( namespaceURI, prefix, localName );
+        }
+        else
+        {
+            throw new UnresolvableException( "No function context installed" );
+        }
+    }
+    
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/DefaultNavigator.java b/libjaxen-java/src/java/main/org/jaxen/DefaultNavigator.java
new file mode 100644
index 0000000..b8781c1
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/DefaultNavigator.java
@@ -0,0 +1,299 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/DefaultNavigator.java,v 1.19 2006/02/05 21:47:41 elharo Exp $
+ * $Revision: 1.19 $
+ * $Date: 2006/02/05 21:47:41 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: DefaultNavigator.java,v 1.19 2006/02/05 21:47:41 elharo Exp $
+ */
+
+
+
+package org.jaxen;
+
+import java.util.Iterator;
+
+import org.jaxen.pattern.Pattern;
+import org.jaxen.util.AncestorAxisIterator;
+import org.jaxen.util.AncestorOrSelfAxisIterator;
+import org.jaxen.util.DescendantAxisIterator;
+import org.jaxen.util.DescendantOrSelfAxisIterator;
+import org.jaxen.util.FollowingAxisIterator;
+import org.jaxen.util.FollowingSiblingAxisIterator;
+import org.jaxen.util.PrecedingAxisIterator;
+import org.jaxen.util.PrecedingSiblingAxisIterator;
+import org.jaxen.util.SelfAxisIterator;
+
+/** Default implementation of {@link Navigator}.
+ *
+ *  <p>
+ *  This implementation is an abstract class, since
+ *  some required operations cannot be implemented without
+ *  additional knowledge of the object model.
+ *  </p>
+ *
+ *  <p>
+ *  When possible, default method implementations build
+ *  upon each other, to reduce the number of methods required
+ *  to be implemented for each object model.  All methods,
+ *  of course, may be overridden, to provide more-efficient
+ *  implementations.
+ *  </p>
+ *
+ *  @author bob mcwhirter (bob at werken.com)
+ *  @author Erwin Bolwidt (ejb at klomp.org)
+ */
+public abstract class DefaultNavigator implements Navigator
+{
+
+    /** Throws <code>UnsupportedAxisException</code>
+     * 
+     * @param contextNode
+     * @return never returns
+     * @throws UnsupportedAxisException always
+     */
+    public Iterator getChildAxisIterator(Object contextNode) throws UnsupportedAxisException
+    {
+        throw new UnsupportedAxisException("child");
+    }
+
+    /* (non-Javadoc)
+     * @see org.jaxen.Navigator#getDescendantAxisIterator(java.lang.Object)
+     */
+    public Iterator getDescendantAxisIterator(Object contextNode) throws UnsupportedAxisException
+    {
+        return new DescendantAxisIterator( contextNode,
+                                           this );
+    }
+
+    /** Throws <code>UnsupportedAxisException</code>
+     * 
+     * @param  contextNode
+     * @return never returns
+     * @throws UnsupportedAxisException
+     */
+    public Iterator getParentAxisIterator(Object contextNode) throws UnsupportedAxisException
+    {
+        throw new UnsupportedAxisException("parent");
+    }
+
+    public Iterator getAncestorAxisIterator(Object contextNode) throws UnsupportedAxisException
+    {
+        return new AncestorAxisIterator( contextNode,
+                                         this );
+    }
+
+
+    public Iterator getFollowingSiblingAxisIterator(Object contextNode) throws UnsupportedAxisException
+    {
+        return new FollowingSiblingAxisIterator( contextNode,
+                                                 this );
+    }
+
+
+    public Iterator getPrecedingSiblingAxisIterator(Object contextNode) throws UnsupportedAxisException
+    {
+        return new PrecedingSiblingAxisIterator( contextNode,
+                                                 this );
+    }
+
+    public Iterator getFollowingAxisIterator(Object contextNode) throws UnsupportedAxisException
+    {
+        return new FollowingAxisIterator( contextNode,
+                                          this );
+
+        // throw new UnsupportedAxisException("following");
+    }
+
+
+    public Iterator getPrecedingAxisIterator(Object contextNode) throws UnsupportedAxisException
+    {
+        return new PrecedingAxisIterator( contextNode,
+                                         this );
+
+        // throw new UnsupportedAxisException("preceding");
+    }
+
+    /** Throws <code>UnsupportedAxisException</code>. Subclasses that 
+     * support the attribute axis must override this method.
+     * 
+     * @param contextNode
+     * @return never returns
+     * @throws UnsupportedAxisException
+     */
+    public Iterator getAttributeAxisIterator(Object contextNode) throws UnsupportedAxisException
+    {
+        throw new UnsupportedAxisException("attribute");
+    }
+
+    /** Throws <code>UnsupportedAxisException</code>. Subclasses that 
+     * support the namespace axis must override this method.
+     * 
+     * @param contextNode
+     * @return never returns
+     * @throws UnsupportedAxisException
+     */
+    public Iterator getNamespaceAxisIterator(Object contextNode) throws UnsupportedAxisException
+    {
+        throw new UnsupportedAxisException("namespace");
+    }
+
+    public Iterator getSelfAxisIterator(Object contextNode) throws UnsupportedAxisException
+    {
+        return new SelfAxisIterator( contextNode );
+    }
+
+    public Iterator getDescendantOrSelfAxisIterator(Object contextNode) throws UnsupportedAxisException
+    {
+        return new DescendantOrSelfAxisIterator( contextNode,
+                                                 this );
+    }
+
+    public Iterator getAncestorOrSelfAxisIterator(Object contextNode) throws UnsupportedAxisException
+    {
+        return new AncestorOrSelfAxisIterator( contextNode,
+                                               this );
+    }
+
+    public Object getDocumentNode(Object contextNode)
+    {
+        return null;
+    }
+    
+    public String translateNamespacePrefixToUri(String prefix, Object element)
+    {
+        return null;
+    }
+
+    public String getProcessingInstructionTarget(Object obj)
+    {
+        return null;
+    }
+
+    public String getProcessingInstructionData(Object obj)
+    {
+        return null;
+    }
+
+    public short getNodeType(Object node)
+    {
+        if ( isElement(node) ) 
+        {
+            return Pattern.ELEMENT_NODE;
+        }
+        else if ( isAttribute(node) ) 
+        {
+            return Pattern.ATTRIBUTE_NODE;
+        }
+        else if ( isText(node) ) 
+        {
+            return Pattern.TEXT_NODE;
+        }
+        else if ( isComment(node) ) 
+        {
+            return Pattern.COMMENT_NODE;
+        }
+        else if ( isDocument(node) ) 
+        {
+            return Pattern.DOCUMENT_NODE;
+        }
+        else if ( isProcessingInstruction(node) ) 
+        {
+            return Pattern.PROCESSING_INSTRUCTION_NODE;
+        }
+        else if ( isNamespace(node) ) 
+        {
+            return Pattern.NAMESPACE_NODE;
+        }
+        else {
+            return Pattern.UNKNOWN_NODE;
+        }
+    }
+    
+    /**
+     * Default inefficient implementation. Subclasses 
+     * should override this method.
+     *
+     * @param contextNode   the node whose parent to return
+     * @return the parent node
+     * @throws UnsupportedAxisException if the parent axis is not supported
+     */
+    public Object getParentNode(Object contextNode) throws UnsupportedAxisException
+    {
+        Iterator iter = getParentAxisIterator( contextNode );
+        if ( iter != null && iter.hasNext() )
+        {
+            return iter.next();
+        }
+        return null;
+    }
+
+    /**
+     *  Default implementation that always returns null. Override in subclass
+     *  if the subclass can load documents. 
+     *
+     * @param url the URL of the document to load
+     *
+     * @return null
+     * @throws FunctionCallException if an error occurs while loading the
+     *    URL; e.g. an I/O error or the document is malformed
+     */
+    public Object getDocument(String url) throws FunctionCallException
+    {
+        return null;
+    }
+
+    /**
+     *  Default implementation that cannot find elements. Override in subclass
+     *  if subclass does know about attribute types.
+     *
+     *  @param contextNode   a node from the document in which to look for the
+     *                       id
+     *  @param elementId   id to look for
+     *
+     *  @return   null
+     */
+    public Object getElementById(Object contextNode, String elementId)
+    {
+        return null;
+    }
+    
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/Function.java b/libjaxen-java/src/java/main/org/jaxen/Function.java
new file mode 100644
index 0000000..f39038b
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/Function.java
@@ -0,0 +1,87 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/Function.java,v 1.8 2006/02/05 21:47:41 elharo Exp $
+ * $Revision: 1.8 $
+ * $Date: 2006/02/05 21:47:41 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: Function.java,v 1.8 2006/02/05 21:47:41 elharo Exp $
+ */
+
+
+package org.jaxen;
+
+import java.util.List;
+
+/** Interface for the extensible function framework.
+ *
+ *  <p>
+ *  <strong>NOTE:</strong> This class is not typically used directly,
+ *  but is exposed for writers of extended XPath packages.
+ *  </p>
+ *
+ *  <p>
+ *  Implementations of <code>Function</code> are functors
+ *  which are used to evaluate a function-call within an
+ *  XPath expression.  
+ *  </p>
+ *
+ *  @see FunctionContext
+ *
+ *  @author <a href="mailto:bob at werken.com">bob mcwhirter</a>
+ */
+public interface Function
+{
+    /** Evaluate this function.
+     *
+     * @param context the context at the point in the
+     *         expression when the function is called
+     * @param args arguments provided to the function
+     * 
+     * @return the result of evaluating the function; a <code>List</code>
+     *    (node-set), <code>Double</code>, <code>Boolean</code>, or
+     *    <code>String</code>
+     * 
+     * @throws FunctionCallException if an XPath error occurs during evaluation;
+     *     for instance, if the number or type of the arguments is incorrect
+     */
+    Object call(Context context,
+                List args) throws FunctionCallException;
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/FunctionCallException.java b/libjaxen-java/src/java/main/org/jaxen/FunctionCallException.java
new file mode 100644
index 0000000..65c949b
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/FunctionCallException.java
@@ -0,0 +1,111 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/FunctionCallException.java,v 1.13 2006/07/16 11:07:25 elharo Exp $
+ * $Revision: 1.13 $
+ * $Date: 2006/07/16 11:07:25 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: FunctionCallException.java,v 1.13 2006/07/16 11:07:25 elharo Exp $
+ */
+
+
+package org.jaxen;
+
+/** 
+ * Thrown if an exception occurs during the evaluation of a function.
+ * This exception may include a root exception--for instance an 
+ * <code>IOException</code> if the real problem was failure to 
+ * load an XML document via the XSLT <code>document()</code> function.
+ *
+ * @author bob mcwhirter (bob @ werken.com)
+ * @author <a href="mailto:jstrachan at apache.org">James Strachan</a>
+ */
+public class FunctionCallException extends JaxenException
+{
+
+    /**
+     * 
+     */
+    private static final long serialVersionUID = 7908649612495640943L;
+
+    /**
+     * Create a new FunctionCallException with the specified detail message.
+     * 
+     * @param message the detail message
+     */
+    public FunctionCallException(String message) {
+        super( message );
+    }
+
+    /**
+     * Create a new FunctionCallException with the specified root cause.
+     * 
+     * @param nestedException the cause of this exception
+     */
+    public FunctionCallException(Throwable nestedException) {
+        super( nestedException );
+    }
+
+    /**
+     * Create a new FunctionCallException with the specified detail message
+     * and root cause.
+     * 
+     * @param message the detail message
+     * @param nestedException the cause of this exception
+     */
+    public FunctionCallException(String message, Exception nestedException) {
+        super( message, nestedException );
+    }
+       
+    /**
+     * <p>
+     * Returns the exception that caused this function call to fail.
+     * Use <code>getCause</code> instead.
+     * </p>
+     * 
+     * @return the exception that caused this function call to fail
+     * 
+     * @deprecated replaced by {@link #getCause()}
+     */
+    public Throwable getNestedException() {
+        return getCause();
+    }
+    
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/FunctionContext.java b/libjaxen-java/src/java/main/org/jaxen/FunctionContext.java
new file mode 100644
index 0000000..a2daf0a
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/FunctionContext.java
@@ -0,0 +1,92 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/FunctionContext.java,v 1.10 2006/02/05 21:47:41 elharo Exp $
+ * $Revision: 1.10 $
+ * $Date: 2006/02/05 21:47:41 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: FunctionContext.java,v 1.10 2006/02/05 21:47:41 elharo Exp $
+ */
+
+
+package org.jaxen;
+
+/** Implemented by classes that know how to resolve XPath function names and
+ *  namespaces to implementations of these functions.
+ *
+ *  <p>
+ *  By using a custom <code>FunctionContext</code>, new or different
+ *  functions may be installed and available to XPath expression writers.
+ *  </p>
+ *
+ *  @see XPathFunctionContext
+ *
+ *  @author <a href="mailto:bob at werken.com">bob mcwhirter</a>
+ */
+public interface FunctionContext
+{
+    /** An implementation should return a <code>Function</code> implementation object
+     *  based on the namespace URI and local name of the function-call
+     *  expression.
+     *
+     *  <p>
+     *  It must not use the prefix parameter to select an implementation,
+     *  because a prefix could be bound to any namespace; the prefix parameter
+     *  could be used in debugging output or other generated information.
+     *  The prefix may otherwise be completely ignored.
+     *  </p>
+     *
+     *  @param namespaceURI  the namespace URI to which the prefix parameter
+     *                       is bound in the XPath expression. If the function
+     *                       call expression had no prefix, the namespace URI
+     *                       is <code>null</code>.
+     *  @param prefix        the prefix that was used in the function call
+     *                       expression
+     *  @param localName     the local name of the function-call expression.
+     *                       If there is no prefix, then this is the whole
+     *                       name of the function.
+     *
+     *  @return  a Function implementation object.
+     *  @throws UnresolvableException  when the function cannot be resolved
+     */
+    Function getFunction( String namespaceURI,
+                          String prefix,
+                          String localName ) throws UnresolvableException;
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/JaxenConstants.java b/libjaxen-java/src/java/main/org/jaxen/JaxenConstants.java
new file mode 100644
index 0000000..004003f
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/JaxenConstants.java
@@ -0,0 +1,76 @@
+package org.jaxen;
+
+/*
+ * $Header: $
+ * $Revision: $
+ * $Date: $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2005 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Jaxen Project and was originally
+ * created by bob mcwhirter <bob at werken.com> and
+ * James Strachan <jstrachan at apache.org>.  For more information on the
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ *
+ * $Id: $
+*/
+
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.ListIterator;
+
+/**
+ * Thread-safe constant iterators used to avoid the overhead of creating 
+ * empty lists.
+ */
+public class JaxenConstants
+{
+    
+    private JaxenConstants() {}
+
+    /**
+     * An iterator with no elements. <code>hasNext()</code> always
+     * returns false. This is thread-safe. 
+     */
+    public static final Iterator EMPTY_ITERATOR = Collections.EMPTY_LIST.iterator();
+    
+    /**
+     * A list iterator with no elements. <code>hasNext()</code> always
+     * returns false. This is thread-safe. 
+     */
+    public static final ListIterator EMPTY_LIST_ITERATOR = Collections.EMPTY_LIST.listIterator();
+    
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/JaxenException.java b/libjaxen-java/src/java/main/org/jaxen/JaxenException.java
new file mode 100644
index 0000000..4467c21
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/JaxenException.java
@@ -0,0 +1,111 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/JaxenException.java,v 1.17 2006/06/03 20:27:21 elharo Exp $
+ * $Revision: 1.17 $
+ * $Date: 2006/06/03 20:27:21 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: JaxenException.java,v 1.17 2006/06/03 20:27:21 elharo Exp $
+ */
+
+
+package org.jaxen;
+
+
+/**
+ * Generic Jaxen exception.
+ *
+ * <p> This is the root of all Jaxen exceptions. It may wrap other exceptions.
+ *
+ * @author <a href="mailto:bob at werken.com">bob mcwhirter</a>
+ */
+public class JaxenException extends org.jaxen.saxpath.SAXPathException
+{
+    
+    /**
+     * 
+     */
+    private static final long serialVersionUID = 7132891439526672639L;
+    static double javaVersion = 1.4;
+    
+    static {
+        try {
+            String versionString = System.getProperty("java.version");
+            versionString = versionString.substring(0, 3);
+            javaVersion = Double.valueOf(versionString).doubleValue();
+        }
+        catch (RuntimeException ex) {
+            // The version string format changed so presumably it's
+            // 1.4 or later.
+        }
+    }
+    
+    /**
+     * Create an exception with a detail message.
+     *
+     * @param message the error message
+     */
+    public JaxenException( String message )
+    {
+        super( message );
+    }
+
+    /**
+     * Create an exception caused by another exception.
+     *
+     * @param rootCause the root cause of this exception
+     */
+    public JaxenException( Throwable rootCause )
+    {
+        super( rootCause );
+    }
+    
+    /**
+     * Create a new JaxenException with the specified detail message
+     * and root cause.
+     * 
+     * @param message the detail message
+     * @param nestedException the cause of this exception
+     */
+    public JaxenException(String message, Throwable nestedException) {
+        super( message, nestedException );
+    }
+    
+}
\ No newline at end of file
diff --git a/libjaxen-java/src/java/main/org/jaxen/JaxenHandler.java b/libjaxen-java/src/java/main/org/jaxen/JaxenHandler.java
new file mode 100644
index 0000000..d94ad69
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/JaxenHandler.java
@@ -0,0 +1,616 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/JaxenHandler.java,v 1.15 2006/03/30 13:53:11 elharo Exp $
+ * $Revision: 1.15 $
+ * $Date: 2006/03/30 13:53:11 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: JaxenHandler.java,v 1.15 2006/03/30 13:53:11 elharo Exp $
+ */
+
+
+
+package org.jaxen;
+
+import java.util.Iterator;
+import java.util.LinkedList;
+
+import org.jaxen.expr.DefaultXPathFactory;
+import org.jaxen.expr.Expr;
+import org.jaxen.expr.FilterExpr;
+import org.jaxen.expr.FunctionCallExpr;
+import org.jaxen.expr.LocationPath;
+import org.jaxen.expr.Predicate;
+import org.jaxen.expr.Predicated;
+import org.jaxen.expr.Step;
+import org.jaxen.expr.XPathExpr;
+import org.jaxen.expr.XPathFactory;
+import org.jaxen.saxpath.Operator;
+import org.jaxen.saxpath.XPathHandler;
+
+/** SAXPath <code>XPathHandler</code> implementation capable
+ *  of building Jaxen expression trees which can walk various
+ *  different object models.
+ *
+ *  @author bob mcwhirter (bob at werken.com)
+ */
+public class JaxenHandler implements XPathHandler
+{
+    private XPathFactory xpathFactory;
+    private XPathExpr    xpath;
+    
+    /**
+     * ????
+     */
+    protected boolean simplified;
+
+    /**
+     * This may be changed to an ArrayList in the future (i.e. version >= 1.2). 
+     * You really shouldn't be accessing this field directly, but
+     * if you are please try to use it as a generic List. Don't use the 
+     * methods that are only available in LinkedList.
+     */
+    protected LinkedList stack;
+
+    /** Constructor
+     */
+    public JaxenHandler()
+    {
+        this.stack        = new LinkedList();
+        this.xpathFactory = new DefaultXPathFactory();
+    }
+    
+    /** Set the Jaxen <code>XPathFactory</code> that constructs
+     *  the XPath expression tree during the parse.
+     *
+     *  @param xpathFactory the factory to use during the parse
+     */
+    public void setXPathFactory(XPathFactory xpathFactory)
+    {
+        this.xpathFactory = xpathFactory;
+    }
+
+    /** Retrieve the Jaxen <code>XPathFactory</code> used
+     *  during the parse to construct the XPath expression tree.
+     *
+     *  @return the <code>XPathFactory</code> used during the parse.
+     */
+    public XPathFactory getXPathFactory()
+    {
+        return this.xpathFactory;
+    }
+
+    /** Retrieve the simplified Jaxen XPath expression tree.
+     *
+     *  <p>
+     *  This method is only valid once <code>XPathReader.parse(...)</code>
+     *  successfully returned.
+     *  </p>
+     *
+     *  @return the XPath expression tree
+     */
+    public XPathExpr getXPathExpr()
+    {
+        return getXPathExpr( true );
+    }
+
+    /** Retrieve the Jaxen XPath expression tree, optionally
+     *  simplified.
+     *
+     *  <p>
+     *  This method is only valid once <code>XPathReader.parse(...)</code>
+     *  successfully returned.
+     *  </p>
+     *  
+     *  @param shouldSimplify ????
+     *
+     *  @return the XPath expression tree
+     */
+    public XPathExpr getXPathExpr(boolean shouldSimplify)
+    {
+        if ( shouldSimplify && ! this.simplified )
+        {
+            this.xpath.simplify();
+            this.simplified = true;
+        }
+
+        return this.xpath;
+    }
+
+    public void startXPath()
+    {
+        this.simplified = false;
+        pushFrame();
+    }
+    
+    public void endXPath() throws JaxenException
+    {
+        this.xpath = getXPathFactory().createXPath( (Expr) pop() );
+        popFrame();
+    }
+
+    public void startPathExpr()
+    {
+        pushFrame();
+    }
+
+    public void endPathExpr() throws JaxenException
+    {
+
+        // PathExpr ::=   LocationPath
+        //              | FilterExpr
+        //              | FilterExpr / RelativeLocationPath
+        //              | FilterExpr // RelativeLocationPath
+        //
+        // If the current stack-frame has two items, it's a
+        // FilterExpr and a LocationPath (of some flavor).
+        //
+        // If the current stack-frame has one item, it's simply
+        // a FilterExpr, and more than likely boils down to a
+        // primary expr of some flavor.  But that's for another
+        // method...
+
+        FilterExpr   filterExpr;
+        LocationPath locationPath;
+
+        Object       popped;
+
+        if ( stackSize() == 2 )
+        {
+            locationPath = (LocationPath) pop();
+            filterExpr   = (FilterExpr) pop();
+        }
+        else
+        {
+            popped = pop();
+
+            if ( popped instanceof LocationPath )
+            {
+                locationPath = (LocationPath) popped;
+                filterExpr   = null;
+            }
+            else
+            {
+                locationPath = null;
+                filterExpr   = (FilterExpr) popped;
+            }
+        }
+        popFrame();
+
+        push( getXPathFactory().createPathExpr( filterExpr,
+                                               locationPath ) );
+    }
+
+    public void startAbsoluteLocationPath() throws JaxenException
+    {
+        pushFrame();
+
+        push( getXPathFactory().createAbsoluteLocationPath() );
+    }
+
+    public void endAbsoluteLocationPath() throws JaxenException
+    {
+        endLocationPath();
+    }
+
+    public void startRelativeLocationPath() throws JaxenException
+    {
+        pushFrame();
+
+        push( getXPathFactory().createRelativeLocationPath() );
+    }
+
+    public void endRelativeLocationPath() throws JaxenException
+    {
+        endLocationPath();
+    }
+
+    protected void endLocationPath() throws JaxenException 
+    {
+        LocationPath path = (LocationPath) peekFrame().removeFirst();
+
+        addSteps( path,
+                  popFrame().iterator() );
+
+        push( path );
+    }
+
+    protected void addSteps(LocationPath locationPath,
+                          Iterator stepIter)
+    {
+        while ( stepIter.hasNext() )
+        {
+            locationPath.addStep( (Step) stepIter.next() );
+        }
+    }
+
+    public void startNameStep(int axis,
+                              String prefix,
+                              String localName) throws JaxenException
+    {
+        pushFrame();
+
+        push( getXPathFactory().createNameStep( axis,
+                                               prefix,
+                                               localName ) );
+    }
+
+    public void endNameStep() 
+    {
+        endStep();
+    }
+    
+    public void startTextNodeStep(int axis) throws JaxenException
+    {
+        //System.err.println("startTextNodeStep()");
+        pushFrame();
+        
+        push( getXPathFactory().createTextNodeStep( axis ) );
+    }
+    
+    public void endTextNodeStep()
+    {
+        endStep();
+    }
+
+    public void startCommentNodeStep(int axis) throws JaxenException
+    {
+        pushFrame();
+
+        push( getXPathFactory().createCommentNodeStep( axis ) );
+    }
+
+    public void endCommentNodeStep()
+    {
+        endStep();
+    }
+        
+    public void startAllNodeStep(int axis) throws JaxenException
+    {
+        pushFrame();
+
+        push( getXPathFactory().createAllNodeStep( axis ) );
+    }
+
+    public void endAllNodeStep()
+    {
+        endStep();
+    }
+
+    public void startProcessingInstructionNodeStep(int axis,
+                                                   String name) throws JaxenException
+    {
+        pushFrame();
+
+        push( getXPathFactory().createProcessingInstructionNodeStep( axis,
+                                                                    name ) );
+    }
+    
+    public void endProcessingInstructionNodeStep()
+    {
+        endStep();
+    }
+
+    protected void endStep()
+    {
+        Step step = (Step) peekFrame().removeFirst();
+
+        addPredicates( step,
+                       popFrame().iterator() );
+
+        push( step );
+    }
+    
+    public void startPredicate()
+    {
+        pushFrame();
+    }
+    
+    public void endPredicate() throws JaxenException
+    {
+        Predicate predicate = getXPathFactory().createPredicate( (Expr) pop() );
+
+        popFrame();
+
+        push( predicate );
+    }
+
+    public void startFilterExpr() 
+    {
+        pushFrame();
+    }
+
+    public void endFilterExpr() throws JaxenException
+    {
+        Expr expr = (Expr) peekFrame().removeFirst();
+        
+        FilterExpr filter = getXPathFactory().createFilterExpr( expr );
+
+        Iterator predIter = popFrame().iterator();
+
+        addPredicates( filter,
+                       predIter );
+
+        push( filter );
+    }
+
+    protected void addPredicates(Predicated obj,
+                               Iterator predIter)
+    {
+        while ( predIter.hasNext() )
+        {
+            obj.addPredicate( (Predicate) predIter.next() );
+        }
+    }
+
+    protected void returnExpr()
+    {
+        Expr expr = (Expr) pop();
+        popFrame();
+        push( expr );
+    }
+
+    public void startOrExpr()
+    {
+    }
+
+    public void endOrExpr(boolean create) throws JaxenException
+    {
+
+        if ( create )
+        {
+            Expr rhs = (Expr) pop();
+            Expr lhs = (Expr) pop();
+
+            push( getXPathFactory().createOrExpr( lhs,
+                                                 rhs ) );
+        }
+    }
+
+    public void startAndExpr()
+    {
+    }
+
+    public void endAndExpr(boolean create) throws JaxenException
+    {
+
+        if ( create )
+        {
+
+            Expr rhs = (Expr) pop();
+            Expr lhs = (Expr) pop();
+
+            push( getXPathFactory().createAndExpr( lhs,
+                                                  rhs ) );
+        }
+    }
+
+    public void startEqualityExpr()
+    {
+    }
+
+    public void endEqualityExpr(int operator) throws JaxenException
+    {
+
+        if ( operator != Operator.NO_OP )
+        {
+            
+            Expr rhs = (Expr) pop();
+            Expr lhs = (Expr) pop();
+            
+            push( getXPathFactory().createEqualityExpr( lhs,
+                                                        rhs,
+                                                        operator ) );
+        }
+    }
+
+    public void startRelationalExpr()
+    {
+    }
+
+    public void endRelationalExpr(int operator) throws JaxenException
+    {
+
+        if ( operator != Operator.NO_OP )
+        {
+
+            Expr rhs = (Expr) pop();
+            Expr lhs = (Expr) pop();
+
+            push( getXPathFactory().createRelationalExpr( lhs,
+                                                         rhs,
+                                                         operator ) );
+        }
+    }
+
+    public void startAdditiveExpr()
+    {
+    }
+
+    public void endAdditiveExpr(int operator) throws JaxenException
+    {
+
+        if ( operator != Operator.NO_OP )
+        {
+            
+            Expr rhs = (Expr) pop();
+            Expr lhs = (Expr) pop();
+            
+            push( getXPathFactory().createAdditiveExpr( lhs,
+                                                        rhs,
+                                                        operator ) );
+        }
+    }
+
+    public void startMultiplicativeExpr()
+    {
+    }
+
+    public void endMultiplicativeExpr(int operator) throws JaxenException
+    {
+
+        if ( operator != Operator.NO_OP )
+        {
+
+            Expr rhs = (Expr) pop();
+            Expr lhs = (Expr) pop();
+            
+            push( getXPathFactory().createMultiplicativeExpr( lhs,
+                                                             rhs,
+                                                             operator ) );
+        }
+    }
+
+    public void startUnaryExpr()
+    {
+     }
+
+    public void endUnaryExpr(int operator) throws JaxenException
+    {
+
+        if ( operator != Operator.NO_OP )
+        {
+            push( getXPathFactory().createUnaryExpr( (Expr) pop(),
+                                                    operator ) );
+        }
+    }
+
+    public void startUnionExpr() 
+    {
+    }
+
+    public void endUnionExpr(boolean create) throws JaxenException
+    {
+
+        if ( create )
+        {
+
+            Expr rhs = (Expr) pop();
+            Expr lhs = (Expr) pop();
+
+            push( getXPathFactory().createUnionExpr( lhs,
+                                                    rhs ) );
+        }
+    }
+
+    public void number(int number) throws JaxenException
+    {
+        push( getXPathFactory().createNumberExpr( number ) );
+    }
+
+    public void number(double number) throws JaxenException
+    {
+        push( getXPathFactory().createNumberExpr( number ) );
+    }
+
+    public void literal(String literal) throws JaxenException
+    {
+        push( getXPathFactory().createLiteralExpr( literal ) );
+    }
+
+    public void variableReference(String prefix,
+                                  String variableName) throws JaxenException
+    {
+        push( getXPathFactory().createVariableReferenceExpr( prefix,
+                                                             variableName ) );
+    }
+
+    public void startFunction(String prefix,
+                              String functionName) throws JaxenException
+    {
+        pushFrame();
+        push( getXPathFactory().createFunctionCallExpr( prefix,
+                                                        functionName ) );
+    }
+
+    public void endFunction()
+    {
+        FunctionCallExpr function = (FunctionCallExpr) peekFrame().removeFirst();
+
+        addParameters( function,
+                       popFrame().iterator() );
+
+        push( function );
+    }
+
+    protected void addParameters(FunctionCallExpr function,
+                               Iterator paramIter)
+    {
+        while ( paramIter.hasNext() )
+        {
+            function.addParameter( (Expr) paramIter.next() );
+        }
+    }
+
+    protected int stackSize()
+    {
+        return peekFrame().size();
+    }
+
+    protected void push(Object obj)
+    {
+        peekFrame().addLast( obj );
+    }
+
+    protected Object pop()
+    {
+        return peekFrame().removeLast();
+    }
+
+    protected boolean canPop()
+    {
+        return ( peekFrame().size() > 0 );
+    }
+
+    protected void pushFrame()
+    {
+        this.stack.addLast( new LinkedList() );
+    }
+
+    protected LinkedList popFrame()
+    {
+        return (LinkedList) this.stack.removeLast();
+    }
+
+    protected LinkedList peekFrame()
+    {
+        return (LinkedList) this.stack.getLast();
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/JaxenRuntimeException.java b/libjaxen-java/src/java/main/org/jaxen/JaxenRuntimeException.java
new file mode 100644
index 0000000..9604cab
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/JaxenRuntimeException.java
@@ -0,0 +1,146 @@
+package org.jaxen;
+
+import java.io.PrintStream;
+import java.io.PrintWriter;
+
+/*
+ * $Header: $
+ * $Revision: $
+ * $Date: $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2005 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Jaxen Project and was originally
+ * created by bob mcwhirter <bob at werken.com> and
+ * James Strachan <jstrachan at apache.org>.  For more information on the
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ *
+ * $Id: $
+*/
+
+/**
+ * This class exists to wrap Jaxen exceptions that otherwise wouldn't be propagated
+ * up through the axis iterators.
+ */
+public class JaxenRuntimeException extends RuntimeException
+{
+    /**
+     * 
+     */
+    private static final long serialVersionUID = -930309761511911193L;
+    
+    private Throwable cause;
+    private boolean causeSet = false;
+
+    /**
+     * Create a new JaxenRuntimeException.
+     * 
+     * @param cause the nested exception that's wrapped 
+     *     inside this exception
+     */
+    public JaxenRuntimeException(Throwable cause)
+    {
+        super(cause.getMessage());
+        initCause(cause);
+    }
+
+    /**
+     * Create a new JaxenRuntimeException.
+     * 
+     * @param message the detail message
+     */
+    public JaxenRuntimeException(String message) {
+        super(message);
+    }
+
+    /**
+     * Returns the exception that caused this exception.
+     * This is necessary to implement Java 1.4 chained exception 
+     * functionality in a Java 1.3-compatible way.
+     * 
+     * @return the exception that caused this exception
+     */
+    public Throwable getCause() {
+        return cause;
+    }
+    
+
+    /**
+     * Sets the exception that caused this exception.
+     * This is necessary to implement Java 1.4 chained exception 
+     * functionality in a Java 1.3-compatible way.
+     * 
+     * @param cause the exception wrapped in this runtime exception
+     * 
+     * @return this exception
+     */
+    public Throwable initCause(Throwable cause) {
+        if (causeSet) throw new IllegalStateException("Cause cannot be reset");
+        if (cause == this) throw new IllegalArgumentException("Exception cannot be its own cause");
+        causeSet = true;
+        this.cause = cause;
+        return this;
+    }
+
+    /** Print this exception's stack trace, followed by the
+     *  source exception's trace, if any.
+     *
+     * @param s the stream on which to print the stack trace
+     */
+    public void printStackTrace ( PrintStream s )
+    {
+        super.printStackTrace ( s );
+        if (JaxenException.javaVersion < 1.4 && getCause() != null) {
+            s.print( "Caused by: " );
+            getCause().printStackTrace( s );
+        }
+    }
+
+    /** Print this exception's stack trace, followed by the
+     *  source exception's stack trace, if any.
+     *
+     * @param s the writer on which to print the stack trace
+     */
+    public void printStackTrace ( PrintWriter s )
+    {
+        super.printStackTrace( s );
+        if (JaxenException.javaVersion < 1.4 && getCause() != null) {
+            s.print( "Caused by: " );
+            getCause().printStackTrace( s );
+        }
+    }
+    
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/NamedAccessNavigator.java b/libjaxen-java/src/java/main/org/jaxen/NamedAccessNavigator.java
new file mode 100644
index 0000000..04ab4fc
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/NamedAccessNavigator.java
@@ -0,0 +1,99 @@
+/*
+ $Id: NamedAccessNavigator.java,v 1.4 2006/02/05 21:47:41 elharo Exp $
+
+ Copyright 2003 The Werken Company. All Rights Reserved.
+ 
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+  * Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+
+  * Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+
+  * Neither the name of the Jaxen Project nor the names of its
+    contributors may be used to endorse or promote products derived 
+    from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ */
+package org.jaxen;
+
+import java.util.Iterator;
+
+/** 
+ * Interface for navigating around an arbitrary object model
+ * accessing certain parts by name for performance.
+ * <p>
+ * This interface must only be implemented by those models that
+ * can support this named access behavior.
+ *
+ * @author Stephen Colebourne
+ */
+public interface NamedAccessNavigator extends Navigator {
+
+    /**
+     * Retrieve an <code>Iterator</code> that returns the <code>child</code>
+     * XPath axis where the names of the children match the supplied name
+     * and optional namespace.
+     * <p>
+     * This method must only return element nodes with the correct name.
+     * <p>
+     * If the namespaceURI is null, no namespace should be used.
+     * The prefix will never be null.
+     *
+     * @param contextNode  the origin context node
+     * @param localName  the local name of the children to return, always present
+     * @param namespacePrefix  the prefix of the namespace of the children to return
+     * @param namespaceURI  the namespace URI of the children to return
+     *
+     * @return an Iterator capable of traversing the named children, or null if none
+     *
+     * @throws UnsupportedAxisException if the child axis is
+     *         not supported by this object model
+     */
+    Iterator getChildAxisIterator(
+        Object contextNode, 
+        String localName, String namespacePrefix, String namespaceURI)
+            throws UnsupportedAxisException;
+
+    /**
+     * Retrieve an <code>Iterator</code> that returns the <code>attribute</code>
+     * XPath axis where the names of the attributes match the supplied name
+     * and optional namespace.
+     * <p>
+     * This method must only return attribute nodes with the correct name.
+     * <p>
+     * If the namespaceURI is null, no namespace should be used.
+     * The prefix will never be null.
+     *
+     * @param contextNode  the origin context node
+     * @param localName  the local name of the attributes to return, always present
+     * @param namespacePrefix  the prefix of the namespace of the attributes to return
+     * @param namespaceURI  the URI of the namespace of the attributes to return
+     *
+     * @return an Iterator capable of traversing the named attributes, or null if none
+     *
+     * @throws UnsupportedAxisException if the attribute axis is
+     *         not supported by this object model
+     */
+    Iterator getAttributeAxisIterator(
+        Object contextNode, 
+        String localName, String namespacePrefix, String namespaceURI)
+            throws UnsupportedAxisException;
+
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/NamespaceContext.java b/libjaxen-java/src/java/main/org/jaxen/NamespaceContext.java
new file mode 100644
index 0000000..ff60bac
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/NamespaceContext.java
@@ -0,0 +1,99 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/NamespaceContext.java,v 1.10 2006/07/03 11:58:06 elharo Exp $
+ * $Revision: 1.10 $
+ * $Date: 2006/07/03 11:58:06 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: NamespaceContext.java,v 1.10 2006/07/03 11:58:06 elharo Exp $
+ */
+
+
+package org.jaxen;
+
+/** Resolves namespace prefixes to namespace URIs.
+ *
+ *  <p>
+ *  The prefixes used within an XPath expression are
+ *  independent of those used within any target document.
+ *  When evaluating an XPath against a document, only
+ *  the resolved namespace URIs are compared, not their
+ *  prefixes.
+ *  </p>
+ *
+ *  <p>
+ *  A <code>NamespaceContext</code> is responsible for
+ *  translating prefixes as they appear in XPath expressions
+ *  into URIs for comparison.  A document's prefixes are
+ *  resolved internal to the document based upon its own
+ *  namespace nodes.
+ *  </p>
+ *  
+ *  <p>
+ *  Implementations of this interface should implement <code>Serializable</code>.
+ *  </p>
+ *
+ *  @see BaseXPath
+ *  @see Navigator#getElementNamespaceUri
+ *  @see Navigator#getAttributeNamespaceUri
+ *
+ *  @author <a href="mailto:bob at werken.com">bob mcwhirter</a>
+ */
+public interface NamespaceContext
+{
+    /** Translate the provided namespace prefix into 
+     *  the matching bound namespace URI.
+     *
+     *  <p>
+     *  In XPath, there is no such thing as a 'default namespace'.
+     *  The empty prefix <strong>always</strong> resolves to the empty
+     *  namespace URI. This method should return null for the
+     *  empty prefix.
+     *  Similarly, the prefix "xml" always resolves to
+     *  the URI "http://www.w3.org/XML/1998/namespace".
+     *  </p>
+     *
+     *  @param prefix the namespace prefix to resolve
+     *
+     *  @return the namespace URI bound to the prefix; or null if there
+     *     is no such namespace 
+     */
+    String translateNamespacePrefixToUri(String prefix);
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/Navigator.java b/libjaxen-java/src/java/main/org/jaxen/Navigator.java
new file mode 100644
index 0000000..733c93d
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/Navigator.java
@@ -0,0 +1,549 @@
+package org.jaxen;
+
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/Navigator.java,v 1.30 2006/06/03 20:07:19 elharo Exp $
+ * $Revision: 1.30 $
+ * $Date: 2006/06/03 20:07:19 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2005 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Jaxen Project and was originally
+ * created by bob mcwhirter <bob at werken.com> and
+ * James Strachan <jstrachan at apache.org>.  For more information on the
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ *
+ * $Id: Navigator.java,v 1.30 2006/06/03 20:07:19 elharo Exp $
+*/
+
+import java.io.Serializable;
+import java.util.Iterator;
+
+import org.jaxen.saxpath.SAXPathException;
+
+/** Interface for navigating around an arbitrary object
+ *  model, using XPath semantics.
+ *
+ *  <p>
+ *  There is a method to obtain a <code>java.util.Iterator</code>,
+ *  for each axis specified by XPath.  If the target object model
+ *  does not support the semantics of a particular axis, an
+ *  {@link UnsupportedAxisException} is to be thrown. If there are
+ *  no nodes on that axis, an empty iterator should be returned.
+ *  </p>
+ *
+ *  @author <a href="mailto:bob at eng.werken.com">bob mcwhirter</a>
+ *  @author <a href="mailto:jstrachan at apache.org">James Strachan</a>
+ *
+ *  @version $Id: Navigator.java,v 1.30 2006/06/03 20:07:19 elharo Exp $
+ */
+public interface Navigator extends Serializable
+{
+    // ----------------------------------------------------------------------
+    //     Axis Iterators
+    // ----------------------------------------------------------------------
+
+    /** Retrieve an <code>Iterator</code> matching the <code>child</code>
+     *  XPath axis.
+     *
+     *  @param contextNode the original context node
+     *
+     *  @return an Iterator capable of traversing the axis, not null
+     *
+     *  @throws UnsupportedAxisException if the semantics of the child axis are
+     *          not supported by this object model
+     */
+    Iterator getChildAxisIterator(Object contextNode)
+        throws UnsupportedAxisException;
+
+    /** Retrieve an <code>Iterator</code> matching the <code>descendant</code>
+     *  XPath axis.
+     *
+     *  @param contextNode the original context node
+     *
+     *  @return an Iterator capable of traversing the axis, not null
+     *
+     *  @throws UnsupportedAxisException if the semantics of the desscendant axis are
+     *          not supported by this object model
+     */
+    Iterator getDescendantAxisIterator(Object contextNode)
+        throws UnsupportedAxisException;
+
+    /** Retrieve an <code>Iterator</code> matching the <code>parent</code> XPath axis.
+     *
+     *  @param contextNode the original context node
+     *
+     *  @return an Iterator capable of traversing the axis, not null
+     *
+     *  @throws UnsupportedAxisException if the semantics of the parent axis are
+     *          not supported by this object model
+     */
+    Iterator getParentAxisIterator(Object contextNode)
+        throws UnsupportedAxisException;
+
+    /** Retrieve an <code>Iterator</code> matching the <code>ancestor</code>
+     *  XPath axis.
+     *
+     *  @param contextNode the original context node
+     *
+     *  @return an Iterator capable of traversing the axis, not null
+     *
+     *  @throws UnsupportedAxisException if the semantics of the ancestor axis are
+     *          not supported by this object model
+     */
+    Iterator getAncestorAxisIterator(Object contextNode)
+        throws UnsupportedAxisException;
+
+    /** Retrieve an <code>Iterator</code> matching the
+     *  <code>following-sibling</code> XPath axis.
+     *
+     *  @param contextNode the original context node
+     *
+     *  @return an Iterator capable of traversing the axis, not null
+     *
+     *  @throws UnsupportedAxisException if the semantics of the following-sibling axis are
+     *          not supported by this object model
+     */
+    Iterator getFollowingSiblingAxisIterator(Object contextNode)
+        throws UnsupportedAxisException;
+
+    /** Retrieve an <code>Iterator</code> matching the
+     *  <code>preceding-sibling</code> XPath axis.
+     *
+     *  @param contextNode the original context node
+     *
+     *  @return an Iterator capable of traversing the axis, not null
+     *
+     *  @throws UnsupportedAxisException if the semantics of the preceding-sibling axis are
+     *          not supported by this object model
+     */
+    Iterator getPrecedingSiblingAxisIterator(Object contextNode)
+        throws UnsupportedAxisException;
+
+    /** Retrieve an <code>Iterator</code> matching the <code>following</code>
+     *  XPath axis.
+     *
+     *  @param contextNode the original context node
+     *
+     *  @return an Iterator capable of traversing the axis, not null
+     *
+     *  @throws UnsupportedAxisException if the semantics of the following axis are
+     *          not supported by this object model
+     */
+    Iterator getFollowingAxisIterator(Object contextNode)
+        throws UnsupportedAxisException;
+
+    /** Retrieve an <code>Iterator</code> matching the <code>preceding</code> XPath axis.
+     *
+     *  @param contextNode the original context node
+     *
+     *  @return an Iterator capable of traversing the axis, not null
+     *
+     *  @throws UnsupportedAxisException if the semantics of the preceding axis are
+     *          not supported by this object model
+     */
+    Iterator getPrecedingAxisIterator(Object contextNode)
+        throws UnsupportedAxisException;
+
+    /** Retrieve an <code>Iterator</code> matching the <code>attribute</code>
+     *  XPath axis.
+     *
+     *  @param contextNode the original context node
+     *
+     *  @return an Iterator capable of traversing the axis, not null
+     *
+     *  @throws UnsupportedAxisException if the semantics of the attribute axis are
+     *          not supported by this object model
+     */
+    Iterator getAttributeAxisIterator(Object contextNode)
+        throws UnsupportedAxisException;
+
+    /** Retrieve an <code>Iterator</code> matching the <code>namespace</code>
+     *  XPath axis.
+     *
+     *  @param contextNode the original context node
+     *
+     *  @return an Iterator capable of traversing the axis, not null
+     *
+     *  @throws UnsupportedAxisException if the semantics of the namespace axis are
+     *          not supported by this object model
+     */
+    Iterator getNamespaceAxisIterator(Object contextNode)
+        throws UnsupportedAxisException;
+
+    /** Retrieve an <code>Iterator</code> matching the <code>self</code> XPath
+     *  axis.
+     *
+     *  @param contextNode the original context node
+     *
+     *  @return an Iterator capable of traversing the axis, not null
+     *
+     *  @throws UnsupportedAxisException if the semantics of the self axis are
+     *          not supported by this object model
+     */
+    Iterator getSelfAxisIterator(Object contextNode)
+        throws UnsupportedAxisException;
+
+    /** Retrieve an <code>Iterator</code> matching the
+     *  <code>descendant-or-self</code> XPath axis.
+     *
+     *  @param contextNode the original context node
+     *
+     *  @return an Iterator capable of traversing the axis, not null
+     *
+     *  @throws UnsupportedAxisException if the semantics of the descendant-or-self axis are
+     *          not supported by this object model
+     */
+    Iterator getDescendantOrSelfAxisIterator(Object contextNode)
+        throws UnsupportedAxisException;
+
+    /** Retrieve an <code>Iterator</code> matching the
+     *  <code>ancestor-or-self</code> XPath axis.
+     *
+     *  @param contextNode the original context node
+     *
+     *  @return an Iterator capable of traversing the axis, not null
+     *
+     *  @throws UnsupportedAxisException if the semantics of the ancestor-or-self axis are
+     *          not supported by this object model
+     */
+    Iterator getAncestorOrSelfAxisIterator(Object contextNode)
+        throws UnsupportedAxisException;
+
+    // ----------------------------------------------------------------------
+    //     Extractors
+    // ----------------------------------------------------------------------
+
+    /** Loads a document from the given URI
+     *
+     *  @param uri the URI of the document to load
+     *
+     *  @return the document
+     *
+      * @throws FunctionCallException if the document could not be loaded
+     */
+    Object getDocument(String uri)
+        throws FunctionCallException;
+
+    /** Returns the document node that contains the given context node.
+     *
+     *  @see #isDocument(Object)
+     *
+     *  @param contextNode the context node
+     *
+     *  @return the document of the context node
+     */
+    Object getDocumentNode(Object contextNode);
+    
+    /** Returns the parent of the given context node.
+     *
+     *  <p>
+     *  The parent of any node must either be a document
+     *  node or an element node.
+     *  </p>
+     *
+     *  @see #isDocument
+     *  @see #isElement
+     *
+     *  @param contextNode the context node
+     *
+     *  @return the parent of the context node, or null if this is a document node.
+     *
+     *  @throws UnsupportedAxisException if the parent axis is not
+     *          supported by the model
+     */
+    Object getParentNode(Object contextNode)
+        throws UnsupportedAxisException;
+    
+    /** Retrieve the namespace URI of the given element node.
+     *
+     *  @param element the context element node
+     *
+     *  @return the namespace URI of the element node
+     */
+    String getElementNamespaceUri(Object element);    
+
+    /** Retrieve the local name of the given element node.
+     *
+     *  @param element the context element node
+     *
+     *  @return the local name of the element node
+     */
+    String getElementName(Object element);    
+
+    /** Retrieve the qualified name of the given element node.
+     *
+     *  @param element the context element node
+     *
+     *  @return the qualified name of the element node
+     */
+    String getElementQName(Object element);
+
+    /** Retrieve the namespace URI of the given attribute node.
+     *
+     *  @param attr the context attribute node
+     *
+     *  @return the namespace URI of the attribute node
+     */
+    String getAttributeNamespaceUri(Object attr);    
+
+    /** Retrieve the local name of the given attribute node.
+     *
+     *  @param attr the context attribute node
+     *
+     *  @return the local name of the attribute node
+     */
+    String getAttributeName(Object attr);
+
+    /** Retrieve the qualified name of the given attribute node.
+     *
+     *  @param attr the context attribute node
+     *
+     *  @return the qualified name of the attribute node
+     */
+    String getAttributeQName(Object attr);
+
+    /** Retrieve the target of a processing-instruction.
+     *
+     *  @param pi the context processing-instruction node
+     *
+     *  @return the target of the processing-instruction node
+     */
+    String getProcessingInstructionTarget(Object pi);
+
+    /** Retrieve the data of a processing-instruction.
+     *
+     *  @param pi the context processing-instruction node
+     *
+     *  @return the data of the processing-instruction node
+     */
+    String getProcessingInstructionData(Object pi);
+
+    // ----------------------------------------------------------------------
+    //     isXXX testers
+    // ----------------------------------------------------------------------
+
+    /** Returns whether the given object is a document node. A document node
+     *  is the node that is selected by the XPath expression <code>/</code>.
+     *
+     *  @param object the object to test
+     *
+     *  @return <code>true</code> if the object is a document node,
+     *          else <code>false</code>
+     */
+    boolean isDocument(Object object);
+
+    /** Returns whether the given object is an element node.
+     *
+     *  @param object the object to test
+     *
+     *  @return <code>true</code> if the object is an element node,
+     *          else <code>false</code>
+     */
+    boolean isElement(Object object);
+
+    /** Returns whether the given object is an attribute node. 
+     *
+     *  @param object the object to test
+     *
+     *  @return <code>true</code> if the object is an attribute node,
+     *          else <code>false</code>
+     */
+    boolean isAttribute(Object object);
+
+    /** Returns whether the given object is a namespace node. 
+     *
+     *  @param object the object to test
+     *
+     *  @return <code>true</code> if the object is a namespace node,
+     *          else <code>false</code>
+     */
+    boolean isNamespace(Object object);
+
+    /** Returns whether the given object is a comment node. 
+     *
+     *  @param object the object to test
+     *
+     *  @return <code>true</code> if the object is a comment node,
+     *          else <code>false</code>
+     */
+    boolean isComment(Object object);
+
+    /** Returns whether the given object is a text node. 
+     *
+     *  @param object the object to test
+     *
+     *  @return <code>true</code> if the object is a text node,
+     *          else <code>false</code>
+     */
+    boolean isText(Object object);
+
+    /** Returns whether the given object is a processing-instruction node.
+     *
+     *  @param object the object to test
+     *
+     *  @return <code>true</code> if the object is a processing-instruction node,
+     *          else <code>false</code>
+     */
+    boolean isProcessingInstruction(Object object);
+
+    // ----------------------------------------------------------------------
+    //     String-Value extractors
+    // ----------------------------------------------------------------------
+
+    /** Retrieve the string-value of a comment node.
+     * This may be the empty string if the comment is empty,
+     * but must not be null.
+     *
+     *  @param comment the comment node
+     *
+     *  @return the string-value of the node
+     */
+    String getCommentStringValue(Object comment);
+
+    /** Retrieve the string-value of an element node.
+     * This may be the empty string if the element is empty,
+     * but must not be null.
+     *
+     *  @param element the comment node.
+     *
+     *  @return the string-value of the node.
+     */
+    String getElementStringValue(Object element);
+
+    /** Retrieve the string-value of an attribute node. 
+     *  This should be the XML 1.0 normalized attribute value.
+     *  This may be the empty string but must not be null. 
+     *
+     *  @param attr the attribute node
+     *
+     *  @return the string-value of the node
+     */
+    String getAttributeStringValue(Object attr);
+
+    /** Retrieve the string-value of a namespace node.
+     * This is generally the namespace URI.
+     * This may be the empty string but must not be null.
+     *
+     *  @param ns the namespace node
+     *
+     *  @return the string-value of the node
+     */
+    String getNamespaceStringValue(Object ns);
+
+    /** Retrieve the string-value of a text node.
+     * This must not be null and should not be the empty string.
+     * The XPath data model does not allow empty text nodes.
+     *
+     *  @param text the text node
+     *
+     *  @return the string-value of the node
+     */
+    String getTextStringValue(Object text);
+
+    // ----------------------------------------------------------------------
+    //     General utilities
+    // ----------------------------------------------------------------------
+
+    /** Retrieve the namespace prefix of a namespace node.
+     *
+     *  @param ns the namespace node
+     *
+     *  @return the prefix associated with the node
+     */
+    String getNamespacePrefix(Object ns);
+
+    
+    /** Translate a namespace prefix to a namespace URI, <strong>possibly</strong>
+     *  considering a particular element node.
+     *
+     *  <p>
+     *  Strictly speaking, prefix-to-URI translation should occur
+     *  irrespective of any element in the document.  This method
+     *  is provided to allow a non-conforming ease-of-use enhancement.
+     *  </p>
+     *
+     *  @see NamespaceContext
+     *
+     *  @param prefix the prefix to translate
+     *  @param element the element to consider during translation
+     *
+     *  @return the namespace URI associated with the prefix
+     */
+    String translateNamespacePrefixToUri(String prefix,
+                                         Object element);
+
+    /** Returns a parsed form of the given XPath string, which will be suitable
+     *  for queries on documents that use the same navigator as this one.
+     *
+     *  @see XPath
+     *
+     *  @param xpath the XPath expression
+     *
+     *  @return a new XPath expression object
+     *
+     *  @throws SAXPathException if the string is not a syntactically 
+     *      correct XPath expression
+     */
+    XPath parseXPath(String xpath) throws SAXPathException;
+
+    /**
+     *  Returns the element whose ID is given by elementId.
+     *  If no such element exists, returns null.
+     *  Attributes with the name "ID" are not of type ID unless so defined.
+     *  Implementations that do not know whether attributes are of type ID or
+     *  not are expected to return null.
+     *
+     *  @param contextNode   a node from the document in which to look for the
+     *                       id
+     *  @param elementId   id to look for
+     *
+     *  @return   element whose ID is given by elementId, or null if no such
+     *            element exists in the document or if the implementation
+     *            does not know about attribute types
+     */
+    Object getElementById(Object contextNode,
+                          String elementId);
+
+    /** Returns a number that identifies the type of node that the given
+     *  object represents in this navigator.
+     * 
+     * @param node ????
+     * @return ????
+     *
+     *  @see org.jaxen.pattern.Pattern
+     */
+    short getNodeType(Object node);
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/QualifiedName.java b/libjaxen-java/src/java/main/org/jaxen/QualifiedName.java
new file mode 100644
index 0000000..1f7953f
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/QualifiedName.java
@@ -0,0 +1,104 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/QualifiedName.java,v 1.12 2006/06/01 13:19:30 elharo Exp $
+ * $Revision: 1.12 $
+ * $Date: 2006/06/01 13:19:30 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: QualifiedName.java,v 1.12 2006/06/01 13:19:30 elharo Exp $
+ */
+
+package org.jaxen;
+
+import java.io.Serializable;
+
+/** A local name (that matches the XML NCName production) and a namespace URI
+ *  with which the local name is qualified.
+ *
+ *  @author Erwin Bolwidt ( ejb at klomp.org )
+ */
+class QualifiedName implements Serializable
+{
+
+    private static final long serialVersionUID = 2734958615642751535L;
+    
+    private String namespaceURI;
+    private String localName;
+
+    /** Constructs a QualifiedName object.
+     *
+     *  @param namespaceURI namespace URI that qualifies the name, or
+     *                      <code>null</code> for default namespace
+     *  @param localName    local name that is qualified by the namespace uri;
+     *                      must not be <code>null</code>
+     */
+    QualifiedName( String namespaceURI, String localName )
+    {
+        if (namespaceURI == null) namespaceURI = "";
+        this.namespaceURI = namespaceURI;
+        this.localName = localName;
+    }
+
+    public int hashCode()
+    {
+        return ( localName.hashCode() ^ namespaceURI.hashCode() );
+    }
+
+    public boolean equals( Object o )
+    {
+        // Because this class is package protected and used in only
+        // two other classes, it's never actually compared to anything 
+        // other than another QualifiedName. No instanceof test is
+        // necessary here.
+        QualifiedName other = (QualifiedName) o;
+        return ( namespaceURI.equals(other.namespaceURI) &&
+                 other.localName.equals(localName) );
+    }
+    
+    /**
+     * @return James Clark's namespace form
+     */
+    String getClarkForm() {
+        if ("".equals(namespaceURI)) return localName;
+        else return "{" + namespaceURI + "}" + ":" + localName;
+    }
+    
+}
+
diff --git a/libjaxen-java/src/java/main/org/jaxen/SimpleFunctionContext.java b/libjaxen-java/src/java/main/org/jaxen/SimpleFunctionContext.java
new file mode 100644
index 0000000..6d05eeb
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/SimpleFunctionContext.java
@@ -0,0 +1,130 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/SimpleFunctionContext.java,v 1.14 2006/02/05 21:47:41 elharo Exp $
+ * $Revision: 1.14 $
+ * $Date: 2006/02/05 21:47:41 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: SimpleFunctionContext.java,v 1.14 2006/02/05 21:47:41 elharo Exp $
+ */
+
+
+package org.jaxen;
+
+import java.util.HashMap;
+
+/** Simple default implementation of <code>FunctionContext</code>.
+ *
+ *  <p>
+ *  This is a simple table-based key-lookup implementation
+ *  for <code>FunctionContext</code> which can be programmatically
+ *  extended by registering additional functions.
+ *  </p>
+ *
+ *  @see XPathFunctionContext
+ *
+ *  @author <a href="mailto:bob at werken.com">bob mcwhirter</a>
+ */
+public class SimpleFunctionContext implements FunctionContext
+{
+    /** Table of functions. */
+    private HashMap functions;
+
+    /** 
+     *  <p>
+     *  Construct an empty function context.
+     *  </p>
+     */
+    public SimpleFunctionContext()
+    {
+        this.functions = new HashMap();
+    }
+
+    /** Register a new function.
+     *
+     *  <p>
+     *  By registering a new function, any XPath expression
+     *  that utilizes this <code>FunctionContext</code> may
+     *  refer to and use the new function.
+     *  </p>
+     *
+     *  <p>
+     *  Functions may exist either in a namespace or not.
+     *  Namespace prefix-to-URI resolution is the responsibility
+     *  of a {@link NamespaceContext}.  Within this <code>FunctionContext</code>
+     *  functions are only referenced using the URI, <strong>not</strong>
+     *  the prefix.
+     *  </p>
+     *
+     *  <p>
+     *  The namespace URI of a function may be <code>null</code>
+     *  to indicate that it exists without a namespace.
+     *  </p>
+     *
+     *  @param namespaceURI the namespace URI of the function to
+     *         be registered with this context
+     *  @param localName the non-prefixed local portion of the
+     *         function to be registered with this context
+     *  @param function a {@link Function} implementation object
+     *         to be used when evaluating the function
+     */
+    public void registerFunction(String namespaceURI,
+                                 String localName,
+                                 Function function )
+    {
+        this.functions.put( new QualifiedName(namespaceURI, localName),
+                            function );
+    }
+
+    public Function getFunction(String namespaceURI,
+                                String prefix,
+                                String localName )
+        throws UnresolvableException
+    {
+        QualifiedName key = new QualifiedName( namespaceURI, localName );
+
+        if ( this.functions.containsKey(key) ) {
+            return (Function) this.functions.get( key );
+        }
+        else {
+            throw new UnresolvableException( "No Such Function " + key.getClarkForm() );
+        }
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/SimpleNamespaceContext.java b/libjaxen-java/src/java/main/org/jaxen/SimpleNamespaceContext.java
new file mode 100644
index 0000000..30ae2f3
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/SimpleNamespaceContext.java
@@ -0,0 +1,149 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/SimpleNamespaceContext.java,v 1.18 2006/06/03 20:19:26 elharo Exp $
+ * $Revision: 1.18 $
+ * $Date: 2006/06/03 20:19:26 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: SimpleNamespaceContext.java,v 1.18 2006/06/03 20:19:26 elharo Exp $
+ */
+
+
+package org.jaxen;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ *  Provides mappings from namespace prefix to namespace URI to the XPath
+ *  engine.
+ */
+public class SimpleNamespaceContext implements NamespaceContext, Serializable
+{
+    
+    /**
+     * 
+     */
+    private static final long serialVersionUID = -808928409643497762L;
+    // XXX should this prebind the xml prefix?
+    private Map namespaces;
+
+    /**
+     * Creates a new empty namespace context.
+     */
+    public SimpleNamespaceContext()
+    {
+        this.namespaces = new HashMap();
+    }
+
+    /**
+     * Creates a new namespace context pre-populated with the specified bindings. 
+     * 
+     * @param namespaces the initial namespace bindings in scope. The keys in this
+     *     must be strings containing the prefixes and the values are strings
+     *     containing the namespace URIs.
+     *     
+     * @throws NullPointerException if the argument is null   
+     * @throws ClassCastException if any keys or values in the map are not strings   
+     */
+    public SimpleNamespaceContext(Map namespaces)
+    {
+        Iterator entries = namespaces.entrySet().iterator();
+        while (entries.hasNext()) {
+            Map.Entry entry = (Map.Entry) entries.next();
+            if (! (entry.getKey() instanceof String)
+              || ! (entry.getValue() instanceof String)) {
+                throw new ClassCastException("Non-string namespace binding");
+            }
+        }
+        this.namespaces = new HashMap(namespaces);
+    }
+
+    /**
+     *  Adds all the namespace declarations that are in scope on the given
+     *  element. In the case of an XSLT stylesheet, this would be the element
+     *  that has the XPath expression in one of its attributes; e.g.
+     *  <code><xsl:if test="condition/xpath/expression"></code>.
+     *
+     *  @param nav  the navigator for use in conjunction with
+     *              <code>element</code>
+     *  @param element the element to copy the namespaces from
+     *  @throws UnsupportedAxisException if the navigator does not support the 
+     *     namespace axis
+     */
+    public void addElementNamespaces( Navigator nav, Object element )
+        throws UnsupportedAxisException
+    {
+        Iterator namespaceAxis = nav.getNamespaceAxisIterator( element );
+
+        while ( namespaceAxis.hasNext() ) {
+            Object namespace = namespaceAxis.next();
+            String prefix = nav.getNamespacePrefix( namespace );
+            String uri = nav.getNamespaceStringValue( namespace );
+            if ( translateNamespacePrefixToUri(prefix) == null ) {
+                addNamespace( prefix, uri );
+            }
+        }
+    }    
+
+    // ???? What if prefix or URI is null, or both?
+    /**
+     * Binds a prefix to a URI in this context.
+     * 
+     * @param prefix the namespace prefix
+     * @param URI    the namespace URI
+     */
+    public void addNamespace(String prefix, String URI)
+    {
+        this.namespaces.put( prefix, URI );
+    }
+
+    public String translateNamespacePrefixToUri(String prefix)
+    {
+        if ( this.namespaces.containsKey( prefix ) )
+        {
+            return (String) this.namespaces.get( prefix );
+        }
+
+        return null;
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/SimpleVariableContext.java b/libjaxen-java/src/java/main/org/jaxen/SimpleVariableContext.java
new file mode 100644
index 0000000..a15a050
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/SimpleVariableContext.java
@@ -0,0 +1,144 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/SimpleVariableContext.java,v 1.19 2006/06/03 20:19:54 elharo Exp $
+ * $Revision: 1.19 $
+ * $Date: 2006/06/03 20:19:54 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: SimpleVariableContext.java,v 1.19 2006/06/03 20:19:54 elharo Exp $
+ */
+
+
+package org.jaxen;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+
+/** Simple default implementation for <code>VariableContext</code>.
+ *
+ *  <p>
+ *  This is a simple table-based key-lookup implementation
+ *  for <code>VariableContext</code> which can be programmatically
+ *  extended by setting additional variables.
+ *  </p>
+ *
+ *  @author <a href="mailto:bob at werken.com">bob mcwhirter</a>
+ */
+public class SimpleVariableContext implements VariableContext, Serializable
+{
+    /**
+     * 
+     */
+    private static final long serialVersionUID = 961322093794516518L;
+    /** Table of variable bindings. */
+    private Map variables;
+
+    /** Construct.
+     *
+     *  <p>
+     *  Create a new empty variable context.
+     *  </p>
+     */
+    public SimpleVariableContext()
+    {
+        variables = new HashMap();
+    }
+
+    /** Set the value associated with a variable.
+     *
+     *  <p>
+     *  This method sets a variable that is 
+     *  associated with a particular namespace.
+     *  These variables appear such as <code>$prefix:foo</code>
+     *  in an XPath expression.  Prefix to URI resolution
+     *  is the responsibility of a <code>NamespaceContext</code>.
+     *  Variables within a <code>VariableContext</code> are
+     *  referred to purely based upon their namespace URI,
+     *  if any.
+     *  </p>
+     *
+     *  @param namespaceURI the namespace URI of the variable
+     *  @param localName the local name of the variable
+     *  @param value The value to be bound to the variable
+     */
+    public void setVariableValue( String namespaceURI,
+                                  String localName,
+                                  Object value )
+    {
+        this.variables.put( new QualifiedName(namespaceURI, localName),
+                            value );
+    }
+
+    /** Set the value associated with a variable.
+     *
+     *  <p>
+     *  This method sets a variable that is <strong>not</strong>
+     *  associated with any particular namespace.
+     *  These variables look like <code>$foo</code>
+     *  in an XPath expression.
+     *  </p>
+     *
+     *  @param localName the local name of the variable
+     *  @param value the value to be bound to the variable
+     */
+    public void setVariableValue( String localName,
+                                  Object value )
+    {
+        this.variables.put( new QualifiedName(null, localName), value );
+    }
+
+    public Object getVariableValue( String namespaceURI,
+                                    String prefix,
+                                    String localName )
+        throws UnresolvableException
+    {
+        QualifiedName key = new QualifiedName( namespaceURI, localName );
+
+        if ( this.variables.containsKey(key) )
+        {
+            return this.variables.get( key );
+        }
+        else
+        {
+            throw new UnresolvableException( "Variable " + key.getClarkForm() );
+        }
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/UnresolvableException.java b/libjaxen-java/src/java/main/org/jaxen/UnresolvableException.java
new file mode 100644
index 0000000..1ae87cf
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/UnresolvableException.java
@@ -0,0 +1,74 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/UnresolvableException.java,v 1.7 2006/06/03 20:21:05 elharo Exp $
+ * $Revision: 1.7 $
+ * $Date: 2006/06/03 20:21:05 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: UnresolvableException.java,v 1.7 2006/06/03 20:21:05 elharo Exp $
+ */
+
+
+package org.jaxen;
+
+/** Thrown when a function-call or variable-reference, or any other lookup
+ *  based on namespace and local name, couldn't be resolved.
+ *
+ *  @author Erwin Bolwidt (ejb @ klomp.org)
+ */
+public class UnresolvableException extends JaxenException
+{
+    
+    /**
+     * 
+     */
+    private static final long serialVersionUID = 953578478331961473L;
+
+    /**
+     * Create a new UnresolvableException.
+     * 
+     * @param message the detail message
+     */
+    public UnresolvableException(String message)
+    {
+        super( message );
+    }
+}
+
diff --git a/libjaxen-java/src/java/main/org/jaxen/UnsupportedAxisException.java b/libjaxen-java/src/java/main/org/jaxen/UnsupportedAxisException.java
new file mode 100644
index 0000000..0f3d6e2
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/UnsupportedAxisException.java
@@ -0,0 +1,77 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/UnsupportedAxisException.java,v 1.11 2006/06/03 20:26:02 elharo Exp $
+ * $Revision: 1.11 $
+ * $Date: 2006/06/03 20:26:02 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: UnsupportedAxisException.java,v 1.11 2006/06/03 20:26:02 elharo Exp $
+ */
+
+
+
+package org.jaxen;
+
+/** 
+ * Indicates attempt to evaluate an XPath axis that
+ * is unsupported by the current object-model. If this is thrown
+ * the XPath expressions cannot be evaluated correctly, unless there is a fallback
+ * evaluation path. Hence you should <em>not</em> just catch this
+ * and ignore it, nor should navigators throw it to indicate that
+ * an axis is exhausted: instead return an empty iterator.
+ *
+ *  @author <a href="mailto:bob at werken.com">bob mcwhirter</a>
+ */
+public class UnsupportedAxisException extends JaxenException
+{
+    /**
+     * 
+     */
+    private static final long serialVersionUID = 3385500112257420949L;
+
+    /** Create a new UnsupportedAxisException.
+     *
+     *  @param message the error message
+     */
+    public UnsupportedAxisException(String message)
+    {
+        super( message );
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/VariableContext.java b/libjaxen-java/src/java/main/org/jaxen/VariableContext.java
new file mode 100644
index 0000000..674d5a5
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/VariableContext.java
@@ -0,0 +1,114 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/VariableContext.java,v 1.11 2006/07/03 11:58:31 elharo Exp $
+ * $Revision: 1.11 $
+ * $Date: 2006/07/03 11:58:31 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: VariableContext.java,v 1.11 2006/07/03 11:58:31 elharo Exp $
+ */
+
+
+package org.jaxen;
+
+/** Resolves variable bindings within an XPath expression.
+ *
+ *  <p>
+ *  Variables within an XPath expression are denoted using
+ *  notation such as <code>$varName</code> or 
+ *  <code>$nsPrefix:varName</code>, and may
+ *  refer to a <code>Boolean</code>, <code>Double</code>, <code>String</code>,
+ *  node-set (<code>List</code>) or individual XML node.
+ *  </p>
+ *
+ *  <p>
+ *  When a variable is bound to a node-set, the
+ *  actual Java object returned should be a <code>java.util.List</code>
+ *  containing XML nodes from the object-model (e.g. dom4j, JDOM, DOM, etc.)
+ *  being used with the XPath.
+ *  </p>
+ *
+ *  <p>
+ *  A variable may validly be assigned the <code>null</code> value,
+ *  but an unbound variable (one that this context does not know about)
+ *  should cause an {@link UnresolvableException} to be thrown.
+ *  </p>
+ *  
+ *  <p>
+ *  Implementations of this interface should implement <code>Serializable</code>.
+ *  </p>
+ *
+ *  @see SimpleVariableContext
+ *  @see NamespaceContext
+ *
+ *  @author <a href="mailto:bob at werken.com">bob mcwhirter</a>
+ *  @author <a href="mailto:jstrachan at apache.org">James Strachan</a>
+ */
+public interface VariableContext
+{
+    /** An implementation should return the value of an XPath variable
+     *  based on the namespace URI and local name of the variable-reference
+     *  expression.
+     *
+     *  <p>
+     *  It must not use the prefix parameter to select a variable,
+     *  because a prefix could be bound to any namespace; the prefix parameter
+     *  could be used in debugging output or other generated information.
+     *  The prefix may otherwise be ignored.
+     *  </p>
+     *
+     *  @param namespaceURI  the namespace URI to which the prefix parameter
+     *                       is bound in the XPath expression. If the variable
+     *                       reference expression had no prefix, the namespace
+     *                       URI is <code>null</code>.
+     *  @param prefix        the prefix that was used in the variable reference
+     *                       expression; this value is ignored and has no effect
+     *  @param localName     the local name of the variable-reference
+     *                       expression. If there is no prefix, then this is
+     *                       the whole name of the variable.
+     *
+     *  @return  the variable's value (which can be <code>null</code>)
+     *  @throws UnresolvableException  when the variable cannot be resolved
+     */
+    public Object getVariableValue( String namespaceURI,
+                                    String prefix,
+                                    String localName )
+        throws UnresolvableException;
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/XPath.java b/libjaxen-java/src/java/main/org/jaxen/XPath.java
new file mode 100644
index 0000000..dd5d4bf
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/XPath.java
@@ -0,0 +1,399 @@
+package org.jaxen;
+
+/*
+ $Id: XPath.java,v 1.12 2006/06/03 20:07:37 elharo Exp $
+
+ Copyright 2003 The Werken Company. All Rights Reserved.
+ 
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+  * Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+
+  * Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+
+  * Neither the name of the Jaxen Project nor the names of its
+    contributors may be used to endorse or promote products derived 
+    from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ */
+
+import java.util.List;
+
+/** Defines the interface to an object which represents an XPath 1.0 expression which
+ *  can be evaluated against a variety of different XML object models.
+ *
+ *  <p>
+ *  Most of the evaluation methods take a context object. This is typically a
+ *  node or node-set object (which is typically a <code>List</code>
+ *  of node objects) or a Jaxen <code>Context</code> object.
+ *  A null context is allowed, meaning that 
+ *  there are no XML nodes on which to evaluate.
+ *  </p>
+ *
+ *  @see org.jaxen.dom4j.Dom4jXPath XPath for dom4j
+ *  @see org.jaxen.jdom.JDOMXPath  XPath for JDOM
+ *  @see org.jaxen.dom.DOMXPath   XPath for W3C DOM
+ *
+ *  @author <a href="mailto:bob at eng.werken.com">bob mcwhirter</a>
+ *  @author <a href="mailto:jstrachan at apache.org">James Strachan</a>
+ */
+public interface XPath
+{
+    // ----------------------------------------------------------------------
+    //     Basic Evaluation
+    // ----------------------------------------------------------------------
+
+    /** Evaluate this XPath against the given context.
+     *
+     *  <p>
+     *  The context of evaluation my be a <em>document</em>,
+     *  an <em>element</em>, or a set of <em>elements</em>.
+     *  </p>
+     *
+     *  <p>
+     *  If the expression evaluates to an XPath string, number, or boolean
+     *  type, then the equivalent Java object type is returned.  
+     *  Otherwise, if the result is a node-set, then the returned value is a
+     *  <code>List</code>.
+     *  </p>
+     *
+     *  <p>
+     *  When using this method, one must be careful to
+     *  test the class of the returned objects, and of 
+     *  each of the composite members if a <code>List</code>
+     *  is returned.  If the returned members are XML nodes,
+     *  they will be the actual <code>Document</code>,
+     *  <code>Element</code> or <code>Attribute</code> objects
+     *  as defined by the concrete XML object-model implementation,
+     *  directly from the context document.  This method <strong>does not
+     *  return <em>copies</em> of anything</strong>. It merely returns
+     *  references to nodes within the source document.
+     *  </p>
+     *  
+     *  @param context the node, node-set or Context object for evaluation. 
+     *         This value can be null.
+     *
+     *  @return the result of evaluating the XPath expression
+     *          against the supplied context
+     *
+     *  @throws JaxenException if an error occurs while attempting
+     *          to evaluate the expression
+     */
+    Object evaluate(Object context) throws JaxenException;
+    
+    // ----------------------------------------------------------------------
+    //     Advanced Evaluation
+    // ----------------------------------------------------------------------
+    
+    /** Retrieve a string-value interpretation of this XPath
+     *  expression when evaluated against the given context.
+     *
+     *  <p>
+     *  The string-value of the expression is determined per
+     *  the <code>string(..)</code> core function as defined
+     *  in the XPath specification.  This means that an expression
+     *  that selects more than one nodes will return the string value
+     *  of the first node in the node set..
+     *  </p>
+     *
+     *  @deprecated use {@link #stringValueOf(Object)} instead
+     *
+     *  @param context the node, node-set or Context object for evaluation. 
+     *         This value can be null.
+     *
+     *  @return the string-value of this expression
+     *
+     *  @throws JaxenException if an error occurs while attempting
+     *          to evaluate the expression
+     */
+    String valueOf(Object context)
+        throws JaxenException;
+
+    /** Retrieve a string-value interpretation of this XPath
+     *  expression when evaluated against the given context.
+     *
+     *  <p>
+     *  The string-value of the expression is determined per
+     *  the <code>string(..)</code> core function as defined
+     *  in the XPath specification.  This means that an expression
+     *  that selects more than one nodes will return the string value
+     *  of the first node in the node set..
+     *  </p>
+     *
+     *  @param context the node, node-set or Context object for evaluation. 
+     *     This value can be null
+     *
+     *  @return the string-value interpretation of this expression
+     *
+     *  @throws JaxenException if an error occurs while attempting
+     *          to evaluate the expression
+     */
+     String stringValueOf(Object context)
+        throws JaxenException;
+    
+    /** Retrieve the boolean value of the first node in document order
+     *  returned by this XPath expression when evaluated in 
+     *  the given context.
+     *
+     *  <p>
+     *  The boolean-value of the expression is determined per
+     *  the <code>boolean()</code> function defined
+     *  in the XPath specification.  This means that an expression
+     *  that selects zero nodes will return <code>false</code>,
+     *  while an expression that selects one or more nodes will
+     *  return <code>true</code>. An expression that returns a string
+     *  returns false for empty strings and true for all other strings.
+     *  An expression that returns a number
+     *  returns false for zero and true for non-zero numbers.
+     *  </p>
+     *
+     *  @param context the node, node-set or Context object for evaluation. This value can be null.
+     *
+     *  @return the boolean-value of this expression
+     *
+     *  @throws JaxenException if an error occurs while attempting
+     *          to evaluate the expression
+     */
+    boolean booleanValueOf(Object context)
+        throws JaxenException;
+    
+
+    /** Retrieve the number-value of the first node in document order
+     *  returned by this XPath expression when evaluated in 
+     *  the given context.
+     *
+     *  <p>
+     *  The number-value of the expression is determined per
+     *  the <code>number(..)</code> core function as defined
+     *  in the XPath specification. This means that if this
+     *  expression selects multiple nodes, the number-value
+     *  of the first node is returned.
+     *  </p>
+     *
+     *  @param context the node, node-set or Context object for evaluation. This value can be null.
+     *
+     *  @return the number-value interpretation of this expression
+     *
+     *  @throws JaxenException if an error occurs while attempting
+     *          to evaluate the expression
+     */
+    Number numberValueOf(Object context)
+        throws JaxenException;
+
+    // ----------------------------------------------------------------------
+    //     Selection
+    // ----------------------------------------------------------------------
+
+    /** Select all nodes that are selectable by this XPath
+     *  expression. If multiple nodes match, multiple nodes
+     *  will be returned.
+     *
+     *  <p>
+     *  <strong>NOTE:</strong> In most cases, nodes will be returned
+     *  in document-order, as defined by the XML Canonicalization
+     *  specification.  The exception occurs when using XPath
+     *  expressions involving the <code>union</code> operator
+     *  (denoted with the pipe '|' character).
+     *  </p>
+     *
+     *  @see #selectSingleNode
+     *
+     *  @param context the node, node-set or Context object for evaluation. 
+     *     This value can be null.
+     *
+     *  @return the node-set of all items selected
+     *          by this XPath expression.
+     *
+     *  @throws JaxenException if an error occurs while attempting
+     *          to evaluate the expression
+     */
+    List selectNodes(Object context)
+        throws JaxenException;
+
+    /** 
+     *  <p>
+     *  Return the first node in document order that is selected by this 
+     *  XPath expression.
+     *  </p>
+     *
+     *  @see #selectNodes
+     *
+     *  @param context the node, node-set or Context object for evaluation. 
+     *     This value can be null.
+     *
+     *  @return the first node in document order selected by this XPath expression
+     *
+     *  @throws JaxenException if an error occurs while attempting
+     *          to evaluate the expression
+     */
+    Object selectSingleNode(Object context)
+        throws JaxenException;
+    
+    // ----------------------------------------------------------------------
+    //     Helpers
+    // ----------------------------------------------------------------------
+
+    /** Add a namespace prefix-to-URI mapping for this XPath
+     *  expression.
+     *
+     *  <p>
+     *  Namespace prefix-to-URI mappings in an XPath are independent
+     *  of those used within any document.  Only the mapping explicitly
+     *  added to this XPath will be available for resolving the
+     *  XPath expression.
+     *  </p>
+     *
+     *  <p>
+     *  This is a convenience method for adding mappings to the
+     *  default {@link NamespaceContext} in place for this XPath.
+     *  If you have installed a specific custom <code>NamespaceContext</code>,
+     *  then this method will throw a <code>JaxenException</code>.
+     *  </p>
+     *
+     *  @param prefix the namespace prefix
+     *  @param uri the namespace URI
+     *
+     *  @throws JaxenException if a <code>NamespaceContext</code>
+     *          used by this XPath has been explicitly installed
+     */
+    void addNamespace(String prefix,
+                      String uri)
+        throws JaxenException;
+
+    // ----------------------------------------------------------------------
+    //     Properties
+    // ----------------------------------------------------------------------
+    
+    /** Set a <code>NamespaceContext</code> for  this
+     *  XPath expression.
+     *
+     *  <p>
+     *  A <code>NamespaceContext</code> is responsible for translating
+     *  namespace prefixes within the expression into namespace URIs.
+     *  </p>
+     *
+     *  @see NamespaceContext
+     *  @see NamespaceContext#translateNamespacePrefixToUri
+     *
+     *  @param namespaceContext the <code>NamespaceContext</code> to
+     *         install for this expression
+     */
+    void setNamespaceContext(NamespaceContext namespaceContext);
+
+    /** Set a <code>FunctionContext</code> for  this XPath
+     *  expression.
+     *
+     *  <p>
+     *  A <code>FunctionContext</code> is responsible for resolving
+     *  all function calls used within the expression.
+     *  </p>
+     *
+     *  @see FunctionContext
+     *  @see FunctionContext#getFunction
+     *
+     *  @param functionContext the <code>FunctionContext</code> to
+     *         install for this expression
+     */
+    void setFunctionContext(FunctionContext functionContext);
+
+    /** Set a <code>VariableContext</code> for this XPath
+     *  expression.
+     *
+     *  <p>
+     *  A <code>VariableContext</code> is responsible for resolving
+     *  all variables referenced within the expression.
+     *  </p>
+     *
+     *  @see VariableContext
+     *  @see VariableContext#getVariableValue
+     *
+     *  @param variableContext the <code>VariableContext</code> to
+     *         install for this expression.
+     */
+    void setVariableContext(VariableContext variableContext);
+
+    /** Retrieve the <code>NamespaceContext</code> used by this XPath
+     *  expression.
+     *
+     *  <p>
+     *  A <code>FunctionContext</code> is responsible for resolving
+     *  all function calls used within the expression.
+     *  </p>
+     *
+     *  <p>
+     *  If this XPath expression has not previously had a <code>NamespaceContext</code>
+     *  installed, a new default <code>NamespaceContext</code> will be created,
+     *  installed and returned.
+     *  </p>
+     *
+     *  @see NamespaceContext
+     *
+     *  @return the <code>NamespaceContext</code> used by this expression
+     */
+    NamespaceContext getNamespaceContext();
+
+    /** Retrieve the <code>FunctionContext</code> used by this XPath
+     *  expression.
+     *
+     *  <p>
+     *  A <code>FunctionContext</code> is responsible for resolving
+     *  all function calls used within the expression.
+     *  </p>
+     *
+     *  <p>
+     *  If this XPath expression has not previously had a <code>FunctionContext</code>
+     *  installed, a new default <code>FunctionContext</code> will be created,
+     *  installed and returned.
+     *  </p>
+     *
+     *  @see FunctionContext
+     *
+     *  @return the <code>FunctionContext</code> used by this expression
+     */
+    FunctionContext getFunctionContext();
+
+    /** Retrieve the <code>VariableContext</code> used by this XPath
+     *  expression.
+     *
+     *  <p>
+     *  A <code>VariableContext</code> is responsible for resolving
+     *  all variables referenced within the expression.
+     *  </p>
+     *
+     *  <p>
+     *  If this XPath expression has not previously had a <code>VariableContext</code>
+     *  installed, a new default <code>VariableContext</code> will be created,
+     *  installed and returned.
+     *  </p>
+     *
+     *  @see VariableContext
+     *  
+     *  @return the <code>VariableContext</code> used by this expression
+     */
+    VariableContext getVariableContext();
+    
+
+    /** Retrieve the XML object-model-specific {@link Navigator} 
+     *  used to evaluate this XPath expression.
+     *
+     *  @return the implementation-specific <code>Navigator</code>
+     */
+    Navigator getNavigator();
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/XPathFunctionContext.java b/libjaxen-java/src/java/main/org/jaxen/XPathFunctionContext.java
new file mode 100644
index 0000000..a32759d
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/XPathFunctionContext.java
@@ -0,0 +1,303 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/XPathFunctionContext.java,v 1.28 2006/02/05 21:47:41 elharo Exp $
+ * $Revision: 1.28 $
+ * $Date: 2006/02/05 21:47:41 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: XPathFunctionContext.java,v 1.28 2006/02/05 21:47:41 elharo Exp $
+ */
+
+
+package org.jaxen;
+
+import org.jaxen.function.BooleanFunction;
+import org.jaxen.function.CeilingFunction;
+import org.jaxen.function.ConcatFunction;
+import org.jaxen.function.ContainsFunction;
+import org.jaxen.function.CountFunction;
+import org.jaxen.function.FalseFunction;
+import org.jaxen.function.FloorFunction;
+import org.jaxen.function.IdFunction;
+import org.jaxen.function.LangFunction;
+import org.jaxen.function.LastFunction;
+import org.jaxen.function.LocalNameFunction;
+import org.jaxen.function.NameFunction;
+import org.jaxen.function.NamespaceUriFunction;
+import org.jaxen.function.NormalizeSpaceFunction;
+import org.jaxen.function.NotFunction;
+import org.jaxen.function.NumberFunction;
+import org.jaxen.function.PositionFunction;
+import org.jaxen.function.RoundFunction;
+import org.jaxen.function.StartsWithFunction;
+import org.jaxen.function.StringFunction;
+import org.jaxen.function.StringLengthFunction;
+import org.jaxen.function.SubstringAfterFunction;
+import org.jaxen.function.SubstringBeforeFunction;
+import org.jaxen.function.SubstringFunction;
+import org.jaxen.function.SumFunction;
+import org.jaxen.function.TranslateFunction;
+import org.jaxen.function.TrueFunction;
+import org.jaxen.function.ext.EndsWithFunction;
+import org.jaxen.function.ext.EvaluateFunction;
+import org.jaxen.function.ext.LowerFunction;
+import org.jaxen.function.ext.MatrixConcatFunction;
+import org.jaxen.function.ext.UpperFunction;
+import org.jaxen.function.xslt.DocumentFunction;
+
+/** A <code>FunctionContext</code> implementing the core XPath
+ *  function library, plus Jaxen extensions.
+ *
+ *  <p>
+ *  The core XPath function library is provided through this
+ *  implementation of <code>FunctionContext</code>.  Additionally,
+ *  extension functions have been provided, as enumerated below.
+ *  </p>
+ *
+ *  <p>
+ *  This class is re-entrant and thread-safe.  If using the
+ *  default instance, it is inadvisable to call 
+ *  {@link #registerFunction(String, String, Function)}
+ *  as that will extend the global function context, affecting other
+ *  users.  But that's your call, really, now isn't
+ *  it?  That may be what you really want to do.
+ *  </p>
+ *
+ *  <p>
+ *  Extension functions:
+ *  </p>
+ *
+ *  <ul>
+ *     <li>matrix-concat(..)</li>
+ *     <li>evaluate(..)</li>
+ *     <li>upper-case(..)</li>
+ *     <li>lower-case(..)</li>
+ *     <li>ends-with(..)</li>
+ *  </ul>
+ *
+ *  @see FunctionContext
+ *  @see org.jaxen.function
+ *  @see org.jaxen.function.xslt
+ *  @see org.jaxen.function.ext
+ *
+ *  @author <a href="mailto:bob at werken.com">bob mcwhirter</a>
+ */
+public class XPathFunctionContext extends SimpleFunctionContext
+{
+    private static XPathFunctionContext instance = new XPathFunctionContext();
+
+    /** Retrieve the default function context
+     *
+     *  @return the default function context
+     */
+    public static FunctionContext getInstance()
+    {
+        return instance;
+    }
+
+    /** Create a new XPath function context.
+     *  All core XPath and Jaxen extension functions are registered.
+     */
+    public XPathFunctionContext()
+    {
+        this(true);
+    }
+
+    /** Create a new XPath function context.
+     *  All core XPath functions are registered.
+     *  
+     * @param includeExtensionFunctions if true extension functions are included;
+     *     if false, they aren't.
+     */
+    public XPathFunctionContext(boolean includeExtensionFunctions)
+    {
+        registerXPathFunctions();
+        if (includeExtensionFunctions) {
+            registerXSLTFunctions();
+            registerExtensionFunctions();
+        }
+    }
+
+    private void registerXPathFunctions() {
+
+        registerFunction( null,  // namespace URI
+                          "boolean",
+                          new BooleanFunction() );
+
+        registerFunction( null,  // namespace URI
+                          "ceiling",
+                          new CeilingFunction() );
+
+        registerFunction( null,  // namespace URI
+                          "concat",
+                          new ConcatFunction() );
+
+        registerFunction( null,  // namespace URI
+                          "contains",
+                          new ContainsFunction() );
+        
+        registerFunction( null,  // namespace URI
+                          "count",
+                          new CountFunction() );
+
+        registerFunction( null,  // namespace URI
+                          "false",
+                          new FalseFunction() );
+
+        registerFunction( null,  // namespace URI
+                          "floor",
+                          new FloorFunction() );
+
+        registerFunction( null,  // namespace URI
+                          "id",
+                          new IdFunction() );
+
+        registerFunction( null,  // namespace URI
+                          "lang",
+                          new LangFunction() );
+
+        registerFunction( null,  // namespace URI
+                          "last",
+                          new LastFunction() );
+
+        registerFunction( null,  // namespace URI
+                          "local-name",
+                          new LocalNameFunction() );
+
+        registerFunction( null,  // namespace URI
+                          "name",
+                          new NameFunction() );
+
+        registerFunction( null,  // namespace URI
+                          "namespace-uri",
+                          new NamespaceUriFunction() );
+
+        registerFunction( null,  // namespace URI
+                          "normalize-space",
+                          new NormalizeSpaceFunction() );
+
+        registerFunction( null,  // namespace URI
+                          "not",
+                          new NotFunction() );
+
+        registerFunction( null,  // namespace URI
+                          "number",
+                          new NumberFunction() );
+
+        registerFunction( null,  // namespace URI
+                          "position",
+                          new PositionFunction() );
+
+        registerFunction( null,  // namespace URI
+                          "round",
+                          new RoundFunction() );
+
+        registerFunction( null,  // namespace URI
+                          "starts-with",
+                          new StartsWithFunction() );
+
+        registerFunction( null,  // namespace URI
+                          "string",
+                          new StringFunction() );
+
+        registerFunction( null,  // namespace URI
+                          "string-length",
+                          new StringLengthFunction() );
+
+        registerFunction( null,  // namespace URI
+                          "substring-after",
+                          new SubstringAfterFunction() );
+
+        registerFunction( null,  // namespace URI
+                          "substring-before",
+                          new SubstringBeforeFunction() );
+
+        registerFunction( null,  // namespace URI
+                          "substring",
+                          new SubstringFunction() );
+
+        registerFunction( null,  // namespace URI
+                          "sum",
+                          new SumFunction() );
+
+        registerFunction( null,  // namespace URI
+                          "true",
+                          new TrueFunction() );
+        
+        registerFunction( null,  // namespace URI
+                          "translate",
+                          new TranslateFunction() );
+    }
+
+    private void registerXSLTFunctions() {
+
+        // extension functions defined in XSLT
+        registerFunction( null,  // namespace URI
+                          "document",
+                          new DocumentFunction() );
+    }
+
+    private void registerExtensionFunctions() {
+        // extension functions should go into a namespace, but which one?
+        // for now, keep them in default namespace to not break any code
+
+        registerFunction( null,  // namespace URI
+                          "matrix-concat",
+                          new MatrixConcatFunction() );
+
+        registerFunction( null,  // namespace URI
+                          "evaluate",
+                          new EvaluateFunction() );
+        
+        registerFunction( null,  // namespace URI
+                          "lower-case",
+                          new LowerFunction() );
+        
+        registerFunction( null,  // namespace URI
+                          "upper-case",
+                          new UpperFunction() );
+        
+        registerFunction( null,  // namespace URI
+                          "ends-with",
+                          new EndsWithFunction() );
+    }
+
+    
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/XPathSyntaxException.java b/libjaxen-java/src/java/main/org/jaxen/XPathSyntaxException.java
new file mode 100644
index 0000000..416f0f7
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/XPathSyntaxException.java
@@ -0,0 +1,168 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/XPathSyntaxException.java,v 1.12 2006/06/03 20:26:36 elharo Exp $
+ * $Revision: 1.12 $
+ * $Date: 2006/06/03 20:26:36 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: XPathSyntaxException.java,v 1.12 2006/06/03 20:26:36 elharo Exp $
+ */
+
+
+package org.jaxen;
+
+/** Indicates an error during parsing of an XPath expression.
+ *
+ *  @author <a href="mailto:bob at werken.com">bob mcwhirter</a>
+ *  @author <a href="mailto:jstrachan at apache.org">James Strachan</a>
+ */
+public class XPathSyntaxException extends JaxenException
+{
+    /**
+     * 
+     */
+    private static final long serialVersionUID = 1980601567207604059L;
+
+    /** The textual XPath expression */
+    private String xpath;
+
+    /** The position of the error */
+    private int    position;
+
+    /**
+     * Create a new XPathSyntaxException wrapping an existing
+     * <code>org.jaxen.saxpath.XPathSyntaxException</code>.
+     * 
+     * @param e the exception that caused this exception
+     */
+    public XPathSyntaxException(org.jaxen.saxpath.XPathSyntaxException e)
+    {
+        super( e );
+
+        this.xpath    = e.getXPath();
+        this.position = e.getPosition();
+    }
+
+    /** Constructor
+     *
+     *  @param xpath the erroneous XPath expression
+     *  @param position the position of the error
+     *  @param message the error message
+     */
+    public XPathSyntaxException(String xpath,
+                                int position,
+                                String message)
+    {
+        super( message );
+
+        this.xpath    = xpath;
+        this.position = position;
+    }
+
+    /** Retrieve the position of the error.
+     *
+     *  @return the position of the error
+     */
+    public int getPosition()
+    {
+        return this.position;
+    }
+
+    /** Retrieve the expression containing the error.
+     *
+     *  @return the erroneous expression
+     */
+    public String getXPath()
+    {
+        return this.xpath;
+    }
+
+    /** Retrieve a string useful for denoting where
+     *  the error occurred.
+     *
+     *  <p>
+     *  This is a string composed of whitespace and
+     *  a marker at the position (see {@link #getPosition})
+     *  of the error.  This is useful for creating
+     *  friendly multi-line error displays.
+     *  </p>
+     *
+     *  @return the error position marker
+     */
+    public String getPositionMarker()
+    {
+        StringBuffer buf = new StringBuffer();
+
+        int pos = getPosition();
+
+        for ( int i = 0 ; i < pos ; ++i )
+        {
+            buf.append(" ");
+        }
+
+        buf.append("^");
+
+        return buf.toString();
+        
+    }
+
+    /** Retrieve the friendly multi-line error message.
+     *
+     *  <p>
+     *  This returns a multi-line string that contains
+     *  the original erroneous XPath expression with a
+     *  marker underneath indicating exactly where the
+     *  error occurred.
+     *  </p>
+     *
+     *  @return the multi-line error message
+     */
+    public String getMultilineMessage()
+    {
+        StringBuffer buf = new StringBuffer(getMessage());
+        buf.append( "\n" );
+        buf.append( getXPath() );
+        buf.append( "\n" );
+
+        buf.append( getPositionMarker() );
+
+        return buf.toString();
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/dom/DOMXPath.java b/libjaxen-java/src/java/main/org/jaxen/dom/DOMXPath.java
new file mode 100644
index 0000000..62318ce
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/dom/DOMXPath.java
@@ -0,0 +1,90 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/dom/DOMXPath.java,v 1.10 2006/06/03 20:44:16 elharo Exp $
+ * $Revision: 1.10 $
+ * $Date: 2006/06/03 20:44:16 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: DOMXPath.java,v 1.10 2006/06/03 20:44:16 elharo Exp $
+ */
+
+// XPath.java - top-level entry point for DOM XPath matching.
+
+package org.jaxen.dom;
+
+import org.jaxen.BaseXPath;
+import org.jaxen.JaxenException;
+
+/** An XPath implementation for the W3C DOM.
+ *
+ * <p>This is the main entry point for matching an XPath against a DOM
+ * tree.  You create a compiled XPath object, then match it against
+ * one or more context nodes using the {@link #selectNodes(Object)}
+ * method, as in the following example:</p>
+ *
+ * <pre> XPath path = new DOMXPath("a/b/c");
+ * List results = path.selectNodes(domNode);</pre>
+ *
+ * @see BaseXPath
+ *
+ * @author <a href="mailto:jstrachan at apache.org">James Strachan</a>
+ * @author <a href="mailto:bob at werken.com">bob mcwhirter</a>
+ *
+ * @version $Revision: 1.10 $
+ */
+public class DOMXPath extends BaseXPath
+{
+    /**
+     * 
+     */
+    private static final long serialVersionUID = 5551221776001439091L;
+
+    /** Create a new <code>DOMXPath</code> from an XPath expression string.
+     *
+     *  @param xpathExpr the XPath expression
+     *
+     *  @throws JaxenException if there is a syntax error in the expression
+     */
+    public DOMXPath(String xpathExpr) throws JaxenException
+    {
+        super( xpathExpr, DocumentNavigator.getInstance() );
+    }
+
+} 
diff --git a/libjaxen-java/src/java/main/org/jaxen/dom/DocumentNavigator.java b/libjaxen-java/src/java/main/org/jaxen/dom/DocumentNavigator.java
new file mode 100644
index 0000000..dbadd12
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/dom/DocumentNavigator.java
@@ -0,0 +1,1064 @@
+package org.jaxen.dom;
+
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/dom/DocumentNavigator.java,v 1.56 2006/07/03 13:08:43 elharo Exp $
+ * $Revision: 1.56 $
+ * $Date: 2006/07/03 13:08:43 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2005 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Jaxen Project and was originally
+ * created by bob mcwhirter <bob at werken.com> and
+ * James Strachan <jstrachan at apache.org>.  For more information on the
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ *
+ * $Id: DocumentNavigator.java,v 1.56 2006/07/03 13:08:43 elharo Exp $
+*/
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+import org.jaxen.DefaultNavigator;
+import org.jaxen.FunctionCallException;
+import org.jaxen.Navigator;
+import org.jaxen.XPath;
+import org.jaxen.JaxenConstants;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.ProcessingInstruction;
+import org.xml.sax.SAXException;
+
+/** Interface for navigating around the W3C DOM Level 2 object model.
+ *
+ *  <p>
+ *  This class is not intended for direct usage, but is
+ *  used by the Jaxen engine during evaluation.
+ *  </p>
+ *
+ *  <p>This class implements the {@link org.jaxen.DefaultNavigator} interface
+ *  for the Jaxen XPath library.  This adapter allows the Jaxen
+ *  library to be used to execute XPath queries against any object tree
+ *  that implements the DOM level 2 interfaces.</p>
+ *
+ *  <p>Note: DOM level 2 does not include a node representing an XPath
+ *  namespace node.  This navigator will return namespace nodes
+ *  as instances of the custom {@link NamespaceNode} class, and
+ *  users will have to check result sets to locate and isolate
+ *  these.</p>
+ *
+ *  @author David Megginson
+ *  @author James Strachan
+ *
+ *  @see XPath
+ *  @see NamespaceNode
+ */
+public class DocumentNavigator extends DefaultNavigator
+{
+
+    

+    ////////////////////////////////////////////////////////////////////
+    // Constants.
+    ////////////////////////////////////////////////////////////////////
+
+    /**
+     * 
+     */
+    private static final long serialVersionUID = 8460943068889528115L; 
+    
+    private final static DocumentNavigator SINGLETON = new DocumentNavigator();
+
+
+    

+    ////////////////////////////////////////////////////////////////////
+    // Constructor.
+    ////////////////////////////////////////////////////////////////////
+
+
+    /**
+     * Default constructor.
+     */
+    public DocumentNavigator ()
+    {
+    }
+
+
+    /**
+     * Get a constant DocumentNavigator for efficiency.
+     *
+     * @return a constant instance of a DocumentNavigator.
+     */
+    public static Navigator getInstance ()
+    {
+        return SINGLETON;
+    }
+
+
+    

+    ////////////////////////////////////////////////////////////////////
+    // Implementation of org.jaxen.DefaultNavigator.
+    ////////////////////////////////////////////////////////////////////
+
+
+    /**
+     * Get an iterator over all of this node's children.
+     *
+     * @param contextNode the context node for the child axis.
+     * @return a possibly-empty iterator (not null)
+     */
+    public Iterator getChildAxisIterator (Object contextNode)
+    {
+        return new NodeIterator ((Node)contextNode) {
+                protected Node getFirstNode (Node node)
+                {
+                    return node.getFirstChild();
+                }
+                protected Node getNextNode (Node node)
+                {
+                    return node.getNextSibling();
+                }
+            };
+    }
+
+
+    /**
+     * Get a (single-member) iterator over this node's parent.
+     *
+     * @param contextNode the context node for the parent axis
+     * @return a possibly-empty iterator (not null)
+     */
+    public Iterator getParentAxisIterator (Object contextNode)
+    {
+        Node node = (Node)contextNode;
+
+        if (node.getNodeType() == Node.ATTRIBUTE_NODE) {
+            return new NodeIterator (node) {
+                    protected Node getFirstNode (Node n)
+                    {
+                        // We can assume castability here because we've already
+                        // tested the node type.
+                        return ((Attr)n).getOwnerElement();
+                    }
+                    protected Node getNextNode (Node n) {
+                        return null;
+                    }
+                };
+        } else {
+            return new NodeIterator (node) {
+                    protected Node getFirstNode (Node n)
+                    {
+                        return n.getParentNode();
+                    }
+                    protected Node getNextNode (Node n) {
+                        return null;
+                    }
+                };
+        }
+    }
+    
+    
+    /** 
+     * Return the XPath parent of this DOM node.
+     * XPath has slightly different definition of parent than DOM does.
+     * In particular, the parent of an attribute is not null.
+     * 
+     * @param o 
+     * 
+     * @return the parent of the specified node; or null if
+     *     the node does not have a parent
+     */
+    public Object getParentNode(Object o) {
+        Node node = (Node) o;
+        if (node.getNodeType() == Node.ATTRIBUTE_NODE) {
+            return ((Attr) node).getOwnerElement();
+        }
+        return node.getParentNode();
+    }
+
+
+    /**
+     * Get an iterator over all following siblings.
+     *
+     * @param contextNode the context node for the sibling iterator
+     * @return a possibly-empty iterator (not null)
+     */
+    public Iterator getFollowingSiblingAxisIterator (Object contextNode)
+    {
+        return new NodeIterator ((Node)contextNode) {
+                protected Node getFirstNode (Node node)
+                {
+                    return getNextNode(node);
+                }
+                protected Node getNextNode (Node node) {
+                    return node.getNextSibling();
+                }
+            };
+    }
+
+
+    /**
+     * Get an iterator over all preceding siblings.
+     *
+     * @param contextNode the context node for the preceding sibling axis
+     * @return a possibly-empty iterator (not null)
+     */
+    public Iterator getPrecedingSiblingAxisIterator (Object contextNode)
+    {
+        return new NodeIterator ((Node)contextNode) {
+                protected Node getFirstNode (Node node)
+                {
+                    return getNextNode(node);
+                }
+                protected Node getNextNode (Node node) {
+                    return node.getPreviousSibling();
+                }
+            };
+    }
+
+
+    /**
+     * Get an iterator over all following nodes, depth-first.
+     *
+     * @param contextNode the context node for the following axis
+     * @return a possibly-empty iterator (not null)
+     */
+    public Iterator getFollowingAxisIterator (Object contextNode)
+    {
+        return new NodeIterator ((Node)contextNode) {
+                protected Node getFirstNode (Node node)
+                {
+                    if (node == null) {
+                        return null;
+                    }
+                    else {
+                        Node sibling = node.getNextSibling();
+                        if (sibling == null) {
+                            return getFirstNode(node.getParentNode());
+                        }
+                        else {
+                            return sibling;
+                        }
+                    }
+                }
+                protected Node getNextNode (Node node) {
+                    if (node == null) {
+                        return null;
+                    }
+                    else {
+                        Node n = node.getFirstChild();
+                        if (n == null) n = node.getNextSibling();
+                        if (n == null) return getFirstNode(node.getParentNode());
+                        else return n;
+                    }
+                }
+            };
+    }
+
+
+    /**
+     * Get an iterator over all attributes.
+     *
+     * @param contextNode the context node for the attribute axis
+     * @return a possibly-empty iterator (not null)
+     */
+    public Iterator getAttributeAxisIterator (Object contextNode)
+    {
+        if (isElement(contextNode)) {
+            return new AttributeIterator((Node)contextNode);
+        } 
+        else {
+            return JaxenConstants.EMPTY_ITERATOR;
+        }
+    }
+
+
+    /**
+     * Get an iterator over all declared namespaces.
+     *
+     * <p>Note: this iterator is not live: it takes a snapshot
+     * and that snapshot remains static during the life of
+     * the iterator (i.e. it won't reflect subsequent changes
+     * to the DOM).</p>
+     * 
+     * <p>
+     * In the event that the DOM is inconsistent; for instance a 
+     * <code>pre:foo</code> element is declared by DOM to be in the 
+     * http://www.a.com/ namespace but also has an 
+     * <code>xmlns:pre="http://www.b.com"</code> attribute; then only 
+     * one of the namespaces will be counted. This will be the intrinsic
+     * namespace of the <code>Element</code> or <code>Attr</code> object
+     * rather than the one provide by the contradictory namespace 
+     * declaration attribute. In the event of a contradiction between two
+     * attributes on the same element--e.g. <code>pre:foo</code> in the
+     * http://www.a.com/ namespace and <code>pre:bar</code> in the 
+     * http://www.b.com/ namespace--it is undefined which namespace
+     * will be returned. 
+     * </p>
+     *
+     * @param contextNode the context node for the namespace axis
+     * @return a possibly-empty iterator (not null)
+     */
+    public Iterator getNamespaceAxisIterator (Object contextNode)
+    {
+        // Only elements have namespace nodes
+        if (isElement(contextNode)) {
+
+            HashMap nsMap = new HashMap();
+
+            // Starting at the current node, walk
+            // up to the root, noting the namespace
+            // declarations in scope.
+            for (Node n = (Node) contextNode;
+                 n != null;
+                 n = n.getParentNode()) {
+                
+                // 1. Look for the namespace of the element itself
+                String myNamespace = n.getNamespaceURI();
+                if (myNamespace != null && ! "".equals(myNamespace)) {
+                    String myPrefix = n.getPrefix();
+                    if (!nsMap.containsKey(myPrefix)) {
+                        NamespaceNode ns = new NamespaceNode((Node) contextNode, myPrefix, myNamespace);
+                        nsMap.put(myPrefix, ns);
+                    }
+                }
+
+                if (n.hasAttributes()) {
+                    NamedNodeMap atts = n.getAttributes();
+                    int length = atts.getLength();
+                    // 2. Look for namespaces of attributes
+                    for (int i = 0; i < length; i++) {
+                        Attr att = (Attr) atts.item(i);
+                        // Work around Crimson bug by testing URI rather than name
+                        String attributeNamespace = att.getNamespaceURI();
+                        if ("http://www.w3.org/2000/xmlns/".equals(attributeNamespace)) {
+                        }
+                        else if (attributeNamespace != null) {
+                            String prefix = att.getPrefix();
+                            NamespaceNode ns =
+                                new NamespaceNode((Node)contextNode, prefix, attributeNamespace);
+                            // Add only if there's not a closer declaration in force.
+                            if (!nsMap.containsKey(prefix)) nsMap.put(prefix, ns);
+                            
+                        }
+                    }
+                    
+                    // 3. Look for namespace declaration attributes
+                    for (int i = 0; i < length; i++) {
+                        Attr att = (Attr) atts.item(i);
+                        // work around crimson bug by testing URI rather than name
+                        String attributeNamespace = att.getNamespaceURI();
+                        if ("http://www.w3.org/2000/xmlns/".equals(attributeNamespace)) {
+                            NamespaceNode ns =
+                              new NamespaceNode( (Node)contextNode, att);
+                            // Add only if there's not a closer declaration in force.
+                            String name = ns.getNodeName();
+                            if (!nsMap.containsKey(name)) nsMap.put(name, ns);
+                        }
+                    }
+                    
+                }
+                
+            }
+            // Section 5.4 of the XPath rec requires
+            // this to be present.
+            nsMap.put("xml",
+                      new
+                      NamespaceNode((Node)contextNode,
+                                    "xml",
+                                    "http://www.w3.org/XML/1998/namespace"));
+
+            // An empty default namespace cancels
+            // any previous default.
+            NamespaceNode defaultNS = (NamespaceNode)nsMap.get("");
+            if (defaultNS != null && defaultNS.getNodeValue().length() == 0) {
+                nsMap.remove("");
+            }
+            return nsMap.values().iterator();
+        } 
+        else {
+            return JaxenConstants.EMPTY_ITERATOR;
+        }
+    }
+
+    /** Returns a parsed form of the given XPath string, which will be suitable
+     *  for queries on DOM documents.
+     *  
+     * @param xpath the XPath expression
+     * @return a parsed form of the given XPath string
+     * @throws org.jaxen.saxpath.SAXPathException if the string is syntactically incorrect
+     */
+    public XPath parseXPath (String xpath) throws org.jaxen.saxpath.SAXPathException
+    {
+        return new DOMXPath(xpath);
+    }
+
+    /**
+     * Get the top-level document node.
+     *
+     * @param contextNode any node in the document
+     * @return the root node
+     */
+    public Object getDocumentNode (Object contextNode)
+    {
+        if (isDocument(contextNode)) return contextNode;
+        else return ((Node)contextNode).getOwnerDocument();
+    }
+
+    // Why are there separate methods for getElementNamespaceURI and 
+    // getAttributeNamespaceURI when they do exactly the same thing?
+    // This should be combined in a future version.
+    /**
+     * Get the namespace URI of an element.
+     *
+     * @param element the target node
+     * @return a string (possibly empty) if the node is an element,
+     * and null otherwise
+     */
+    public String getElementNamespaceUri (Object element)
+    {
+        try {
+            Node node = (Node) element;
+            if (node.getNodeType() == Node.ELEMENT_NODE) {
+                return node.getNamespaceURI();
+            }
+        }
+        catch (ClassCastException ex) {
+        }
+        return null;
+    }
+
+
+    /**
+     * Get the local name of an element.
+     *
+     * @param element the target node
+     * @return a string representing the unqualified local name
+     *     if the node is an element, or null otherwise
+     */
+    public String getElementName (Object element)
+    {
+        if (isElement(element)) {
+            String name = ((Node)element).getLocalName();
+            if (name == null) name = ((Node)element).getNodeName();
+            return name;
+        }
+        return null;
+    }
+
+
+    /**
+     * Get the qualified name of an element.
+     *
+     * @param element the target node
+     * @return a string representing the qualified (i.e. possibly
+     *   prefixed) name if the argument is an element, or null otherwise
+     */
+    public String getElementQName (Object element)
+    {
+        try {
+            Node node = (Node) element;
+            if (node.getNodeType() == Node.ELEMENT_NODE) {
+                return node.getNodeName();
+            }
+        }
+        catch (ClassCastException ex) {
+        }
+        return null;
+    }
+
+
+    /**
+     * Get the namespace URI of an attribute.
+     *
+     * @param attribute the target node
+     * 
+     * @return the namespace name of the specified node
+     * 
+     */
+    public String getAttributeNamespaceUri (Object attribute)
+    {
+        try {
+            Node node = (Node) attribute;
+            if (node.getNodeType() == Node.ATTRIBUTE_NODE) {
+                return node.getNamespaceURI();
+            }
+        }
+        catch (ClassCastException ex) {
+        }
+        return null;
+    }
+
+
+    /**
+     * Get the local name of an attribute.
+     *
+     * @param attribute the target node
+     * @return a string representing the unqualified local name
+     * if the node is an attribute, or null otherwise
+     */
+    public String getAttributeName (Object attribute)
+    {
+        if (isAttribute(attribute)) {
+            String name = ((Node)attribute).getLocalName();
+            if (name == null) name = ((Node)attribute).getNodeName();
+            return name;
+        }
+        return null;
+    }
+
+
+    /**
+     * Get the qualified name of an attribute.
+     *
+     * @param attribute the target node
+     * 
+     * @return a string representing the qualified (i.e. possibly
+     * prefixed) name if the argument is an attribute, or null otherwise
+     */
+    public String getAttributeQName (Object attribute)
+    {
+        try {
+            Node node = (Node) attribute;
+            if (node.getNodeType() == Node.ATTRIBUTE_NODE) {
+                return node.getNodeName();
+            }
+        }
+        catch (ClassCastException ex) {
+        }
+        return null;
+    }
+
+
+    /**
+     * Test if a node is a top-level document.
+     *
+     * @param object the target node
+     * @return true if the node is the document root, false otherwise
+     */
+    public boolean isDocument (Object object)
+    {
+        return (object instanceof Node) &&
+            (((Node)object).getNodeType() == Node.DOCUMENT_NODE);
+    }
+
+
+    /**
+     * Test if a node is a namespace.
+     *
+     * @param object the target node
+     * @return true if the node is a namespace, false otherwise
+     */
+    public boolean isNamespace (Object object)
+    {
+        return (object instanceof NamespaceNode);
+    }
+
+
+    /**
+     * Test if a node is an element.
+     *
+     * @param object the target node
+     * @return true if the node is an element, false otherwise
+     */
+    public boolean isElement (Object object)
+    {
+        return (object instanceof Node) &&
+            (((Node)object).getNodeType() == Node.ELEMENT_NODE);
+    }
+
+
+    /**
+     * Test if a node is an attribute. <code>xmlns</code> and 
+     * <code>xmlns:pre</code> attributes do not count as attributes
+     * for the purposes of XPath. 
+     *
+     * @param object the target node
+     * @return true if the node is an attribute, false otherwise
+     */
+    public boolean isAttribute (Object object)
+    {
+        return (object instanceof Node) &&
+            (((Node)object).getNodeType() == Node.ATTRIBUTE_NODE)
+            && ! "http://www.w3.org/2000/xmlns/".equals(((Node) object).getNamespaceURI());
+    }
+
+
+    /**
+     * Test if a node is a comment.
+     *
+     * @param object the target node
+     * @return true if the node is a comment, false otherwise
+     */
+    public boolean isComment (Object object)
+    {
+        return (object instanceof Node) &&
+            (((Node)object).getNodeType() == Node.COMMENT_NODE);
+    }
+
+
+    /**
+     * Test if a node is plain text.
+     *
+     * @param object the target node
+     * @return true if the node is a text node, false otherwise
+     */
+    public boolean isText (Object object)
+    {
+        if (object instanceof Node) {
+            switch (((Node)object).getNodeType()) {
+                case Node.TEXT_NODE:
+                case Node.CDATA_SECTION_NODE:
+                    return true;
+                default:
+                    return false;
+            }
+        } else {
+            return false;
+        }
+    }
+
+
+    /**
+     * Test if a node is a processing instruction.
+     *
+     * @param object the target node
+     * @return true if the node is a processing instruction, false otherwise
+     */
+    public boolean isProcessingInstruction (Object object)
+    {
+        return (object instanceof Node) &&
+            (((Node)object).getNodeType() == Node.PROCESSING_INSTRUCTION_NODE);
+    }
+
+
+    /**
+     * Get the string value of an element node.
+     *
+     * @param object the target node
+     * @return the text inside the node and its descendants if the node
+     * is an element, null otherwise
+     */
+    public String getElementStringValue (Object object)
+    {
+        if (isElement(object)) {
+            return getStringValue((Node)object, new StringBuffer()).toString();
+        }
+        else {
+            return null;
+        }
+    }
+
+
+    /**
+     * Construct a node's string value recursively.
+     *
+     * @param node the current node
+     * @param buffer the buffer for building the text
+     * @return the buffer passed as a parameter (for convenience)
+     */
+    private StringBuffer getStringValue (Node node, StringBuffer buffer)
+    {
+        if (isText(node)) {
+            buffer.append(node.getNodeValue());
+        } else {
+            NodeList children = node.getChildNodes();
+            int length = children.getLength();
+            for (int i = 0; i < length; i++) {
+                getStringValue(children.item(i), buffer);
+            }
+        }
+        return buffer;
+    }
+
+
+    /**
+     * Get the string value of an attribute node.
+     *
+     * @param object the target node
+     * @return the text of the attribute value if the node is an
+     *     attribute, null otherwise
+     */
+    public String getAttributeStringValue (Object object)
+    {
+        if (isAttribute(object)) return ((Node)object).getNodeValue();
+        else return null;
+    }
+
+
+    /**
+     * Get the string value of text.
+     *
+     * @param object the target node
+     * @return the string of text if the node is text, null otherwise
+     */
+    public String getTextStringValue (Object object)
+    {
+        if (isText(object)) return ((Node)object).getNodeValue();
+        else return null;
+    }
+
+
+    /**
+     * Get the string value of a comment node.
+     *
+     * @param object the target node
+     * @return the text of the comment if the node is a comment, null otherwise
+     */
+    public String getCommentStringValue (Object object)
+    {
+        if (isComment(object)) return ((Node)object).getNodeValue();
+        else return null;
+    }
+
+
+    /**
+     * Get the string value of a namespace node.
+     *
+     * @param object the target node
+     * @return the namespace URI as a (possibly empty) string if the
+     *     node is a namespace node, null otherwise
+     */
+    public String getNamespaceStringValue (Object object)
+    {
+        if (isNamespace(object)) return ((NamespaceNode)object).getNodeValue();
+        else return null;
+    }
+
+    /**
+     * Get the prefix value of a namespace node.
+     *
+     * @param object the target node
+     * @return the namespace prefix a (possibly empty) string if the
+     *     node is a namespace node, null otherwise
+     */
+    public String getNamespacePrefix (Object object)
+    {
+        if (isNamespace(object)) return ((NamespaceNode)object).getLocalName();
+        else return null;
+    }
+
+    /**
+     * Translate a namespace prefix to a URI.
+     * 
+     * @param prefix the namespace prefix
+     * @param element the namespace context
+     * @return the namespace URI bound to the prefix in the scope of <code>element</code>;
+     *     null if the prefix is not bound
+     */
+    public String translateNamespacePrefixToUri (String prefix, Object element)
+    {
+        Iterator it = getNamespaceAxisIterator(element);
+        while (it.hasNext()) {
+            NamespaceNode ns = (NamespaceNode)it.next();
+            if (prefix.equals(ns.getNodeName())) return ns.getNodeValue();
+        }
+        return null;
+    }
+
+    /**
+     * Use JAXP to load a namespace aware document from a given URI.
+     *
+     * @param uri the URI of the document to load
+     * @return the new W3C DOM Level 2 Document instance
+     * @throws FunctionCallException containing a nested exception
+     *      if a problem occurs trying to parse the given document
+     */
+    public Object getDocument(String uri) throws FunctionCallException
+    {
+        try
+        {
+            // We really do need to construct a new factory here each time.
+            // DocumentBuilderFactory is not guaranteed to be thread safe? 
+            // Possibly we could make this a thread local.????
+            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+            factory.setNamespaceAware(true);
+            DocumentBuilder builder = factory.newDocumentBuilder();
+            return builder.parse( uri );
+        }
+        catch (ParserConfigurationException e) {
+            throw new FunctionCallException("JAXP setup error in document() function: " + e.getMessage(), e);
+        }
+        catch (SAXException e) {
+           throw new FunctionCallException("XML error in document() function: " + e.getMessage(), e);
+        }
+        catch (IOException e) {
+           throw new FunctionCallException("I/O error in document() function: " + e.getMessage(), e);
+        }
+        
+    }
+    
+    /**
+     * Get the target of a processing instruction node.
+     * 
+     * @param obj the processing instruction
+     * @return the target of the processing instruction
+     * @throws ClassCastException if obj is not a processing instruxtion
+     * 
+     */
+    public String getProcessingInstructionTarget(Object obj)
+    {      
+        if (isProcessingInstruction(obj)) {
+            ProcessingInstruction pi = (ProcessingInstruction) obj;
+            return pi.getTarget();
+        }
+        throw new ClassCastException(obj + " is not a processing instruction");
+    }
+
+    /**
+     * Get the data of a processing instruction node.
+     * 
+     * @param obj the processing instruction
+     * @return the target of the processing instruction
+     * @throws ClassCastException if obj is not a processing instruxtion
+     * 
+     */
+    public String getProcessingInstructionData(Object obj)
+    {
+        if (isProcessingInstruction(obj)) {
+            ProcessingInstruction pi = (ProcessingInstruction) obj;
+            return pi.getData();
+        }
+        throw new ClassCastException(obj + " is not a processing instruction");
+    }
+
+    

+    ////////////////////////////////////////////////////////////////////
+    // Inner class: iterate over DOM nodes.
+    ////////////////////////////////////////////////////////////////////
+
+
+    // FIXME: needs to recurse into
+    // DocumentFragment and EntityReference
+    // to use their children.
+
+    /**
+     * A generic iterator over DOM nodes.
+     *
+     * <p>Concrete subclasses must implement the {@link #getFirstNode}
+     * and {@link #getNextNode} methods for a specific iteration
+     * strategy.</p>
+     */
+    abstract class NodeIterator
+    implements Iterator
+    {
+
+
+        /**
+         * Constructor.
+         *
+         * @param contextNode the starting node
+         */
+        public NodeIterator (Node contextNode)
+        {
+            node = getFirstNode(contextNode);
+            while (!isXPathNode(node)) {
+                node = getNextNode(node);
+            }
+        }
+
+        public boolean hasNext ()
+        {
+            return (node != null);
+        }
+
+        public Object next ()
+        {
+            if (node == null) throw new NoSuchElementException();
+            Node ret = node;
+            node = getNextNode(node);
+            while (!isXPathNode(node)) {
+                node = getNextNode(node);
+            }
+            return ret;
+        }
+
+        public void remove ()
+        {
+            throw new UnsupportedOperationException();
+        }
+
+
+        /**
+         * Get the first node for iteration.
+         *
+         * <p>This method must derive an initial node for iteration
+         * from a context node.</p>
+         *
+         * @param contextNode the starting node
+         * @return the first node in the iteration
+         * @see #getNextNode
+         */
+        protected abstract Node getFirstNode (Node contextNode);
+
+
+        /**
+         * Get the next node for iteration.
+         *
+         * <p>This method must locate a following node from the
+         * current context node.</p>
+         *
+         * @param contextNode the current node in the iteration
+         * @return the following node in the iteration, or null
+         * if there is none
+         * @see #getFirstNode
+         */
+        protected abstract Node getNextNode (Node contextNode);
+
+
+        /**
+         * Test whether a DOM node is usable by XPath.
+         *
+         * @param node the DOM node to test
+         * @return true if the node is usable, false if it should be skipped
+         */
+        private boolean isXPathNode (Node node)
+        {
+            // null is usable, because it means end
+            if (node == null) return true;
+
+            switch (node.getNodeType()) {
+                case Node.DOCUMENT_FRAGMENT_NODE:
+                case Node.DOCUMENT_TYPE_NODE:
+                case Node.ENTITY_NODE:
+                case Node.ENTITY_REFERENCE_NODE:
+                case Node.NOTATION_NODE:
+                    return false;
+                default:
+                    return true;
+            }
+        }
+
+        private Node node;
+    }
+
+
+    

+    ////////////////////////////////////////////////////////////////////
+    // Inner class: iterate over a DOM named node map.
+    ////////////////////////////////////////////////////////////////////
+
+
+    /**
+     * An iterator over an attribute list.
+     */
+    private static class AttributeIterator implements Iterator
+    {
+
+        /**
+         * Constructor.
+         *
+         * @param parent the parent DOM element for the attributes.
+         */
+        AttributeIterator (Node parent)
+        {
+            this.map = parent.getAttributes();
+            this.pos = 0;
+            for (int i = this.map.getLength()-1; i >= 0; i--) {
+                Node node = map.item(i);
+                if (! "http://www.w3.org/2000/xmlns/".equals(node.getNamespaceURI())) {
+                    this.lastAttribute  = i;
+                    break;
+                }
+            }
+        }
+
+        public boolean hasNext ()
+        {
+            return pos <= lastAttribute;
+        }
+
+        public Object next ()
+        {
+            Node attr = map.item(pos++);
+            if (attr == null) throw new NoSuchElementException();
+            else if ("http://www.w3.org/2000/xmlns/".equals(attr.getNamespaceURI())) {
+              // XPath doesn't consider namespace declarations to be attributes 
+              // so skip it and go to the next one
+              return next();
+            }
+            else return attr;
+        }
+
+        public void remove ()
+        {
+            throw new UnsupportedOperationException();
+        }
+
+
+        private NamedNodeMap map;
+        private int pos;
+        private int lastAttribute = -1;
+
+    }
+
+    /**
+     *  Returns the element whose ID is given by elementId.
+     *  If no such element exists, returns null.
+     *  Attributes with the name "ID" are not of type ID unless so defined.
+     *  Attribute types are only known if when the parser understands DTD's or
+     *  schemas that declare attributes of type ID. When JAXP is used, you
+     *  must call <code>setValidating(true)</code> on the
+     *  DocumentBuilderFactory.
+     *
+     *  @param object   a node from the document in which to look for the id
+     *  @param elementId   id to look for
+     *
+     *  @return   element whose ID is given by elementId, or null if no such
+     *            element exists in the document or if the implementation
+     *            does not know about attribute types
+     *  @see   javax.xml.parsers.DocumentBuilderFactory
+     *  
+     *  @throws ClassCastException if object is not an org.w3c.dom.Node object
+     *  
+     */
+    public Object getElementById(Object object, String elementId)
+    {
+        Document doc = (Document)getDocumentNode(object);
+        if (doc != null) return doc.getElementById(elementId);
+        else return null;
+    }
+
+}
+
+// end of DocumentNavigator.java
diff --git a/libjaxen-java/src/java/main/org/jaxen/dom/NamespaceNode.java b/libjaxen-java/src/java/main/org/jaxen/dom/NamespaceNode.java
new file mode 100644
index 0000000..26f8f56
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/dom/NamespaceNode.java
@@ -0,0 +1,867 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/dom/NamespaceNode.java,v 1.25 2006/07/03 11:14:05 elharo Exp $
+ * $Revision: 1.25 $
+ * $Date: 2006/07/03 11:14:05 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: NamespaceNode.java,v 1.25 2006/07/03 11:14:05 elharo Exp $
+ */
+
+////////////////////////////////////////////////////////////////////
+// Inner class for a Namespace node.
+////////////////////////////////////////////////////////////////////
+
+package org.jaxen.dom;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+
+import org.jaxen.pattern.Pattern;
+import org.w3c.dom.DOMException;
+import org.w3c.dom.Document;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.UserDataHandler;
+
+
+/**
+ * Extension DOM2/DOM3 node type for a namespace node.
+ *
+ * <p>This class implements the DOM2 and DOM3 {@link Node} interface
+ * to allow namespace nodes to be included in the result
+ * set of an XPath selectNodes operation, even though DOM does
+ * not model namespaces in scope as separate nodes.</p>
+ *
+ * <p>
+ * While all of the DOM2 methods are implemented with reasonable
+ * defaults, there will be some unexpected surprises, so users are
+ * advised to test for NamespaceNodes and filter them out from the
+ * result sets as early as possible.
+  * </p>
+ *
+ * <ol>
+ *
+ * <li>The {@link #getNodeType} method returns {@link #NAMESPACE_NODE},
+ * which is not one of the usual DOM2 node types.  Generic code may
+ * fall unexpectedly out of switch statements, for example.</li>
+ *
+ * <li>The {@link #getOwnerDocument} method returns the owner document
+ * of the parent node, but that owner document will know nothing about
+ * the namespace node.</p>
+ *
+ * <li>The {@link #isSupported} method always returns false.</li>
+ *
+ * <li> The DOM3 methods sometimes throw UnsupportedOperationException.
+ *      They're here only to allow this class to be compiled with Java 1.5.
+ *       Do not call or rely on them.</li>
+ * </ol>
+ *
+ * <p>All attempts to modify a <code>NamespaceNode</code> will fail with a {@link
+ * DOMException} ({@link
+ * DOMException#NO_MODIFICATION_ALLOWED_ERR}).</p>
+ *
+ * @author David Megginson
+ * @author Elliotte Rusty Harold
+ * @see DocumentNavigator
+ */
+public class NamespaceNode implements Node
+{
+
+    /**
+     * Constant: this is a NamespaceNode.
+     *
+     * @see #getNodeType
+     */
+    public final static short NAMESPACE_NODE = Pattern.NAMESPACE_NODE;
+
+    // FIXME "Note: Numeric codes up to 200 are reserved to W3C for possible future use."
+    // We should be using higher codes. Here we're using 13, the same as DOM 3's type for XPathNamespace.
+    // However, that's only a note not a recommendation.
+
+    /**
+     * Create a new NamespaceNode.
+     *
+     * @param parent the DOM node to which the namespace is attached
+     * @param name the namespace prefix
+     * @param value the namespace URI
+     */
+    public NamespaceNode (Node parent, String name, String value)
+    {
+        this.parent = parent;
+        this.name = name;
+        this.value = value;
+    }
+
+
+    /**
+     * Constructor.
+     *
+     * @param parent the DOM node to which the namespace is attached
+     * @param attribute the DOM attribute object containing the
+     *        namespace declaration
+     */
+    NamespaceNode (Node parent, Node attribute)
+    {
+        String attributeName = attribute.getNodeName();
+    
+        if (attributeName.equals("xmlns")) {
+            this.name = "";
+        }
+        else if (attributeName.startsWith("xmlns:")) {
+            this.name = attributeName.substring(6); // the part after "xmlns:"
+        }
+        else { // workaround for Crimson bug; Crimson incorrectly reports the prefix as the node name
+            this.name = attributeName;
+        }
+        this.parent = parent;
+        this.value = attribute.getNodeValue();
+    }
+
+
+

+    ////////////////////////////////////////////////////////////////////
+    // Implementation of org.w3c.dom.Node.
+    ////////////////////////////////////////////////////////////////////
+
+
+    /**
+     * Get the namespace prefix.
+     *
+     * @return the namespace prefix, or "" for the default namespace
+     */
+    public String getNodeName ()
+    {
+        return name;
+    }
+
+
+    /**
+     * Get the namespace URI.
+     *
+     * @return the namespace URI
+     */
+    public String getNodeValue ()
+    {
+        return value;
+    }
+
+
+    /**
+     * Change the namespace URI (always fails).
+     *
+     * @param value the new URI
+     * @throws DOMException always
+     */
+    public void setNodeValue (String value) throws DOMException
+    {
+        disallowModification();
+    }
+
+
+    /**
+     * Get the node type.
+     *
+     * @return always {@link #NAMESPACE_NODE}.
+     */
+    public short getNodeType ()
+    {
+        return NAMESPACE_NODE;
+    }
+
+
+    /**
+     * Get the parent node.
+     *
+     * <p>This method returns the element that was queried for Namespaces
+     * in effect, <em>not</em> necessarily the actual element containing
+     * the Namespace declaration.</p>
+     *
+     * @return the parent node (not null)
+     */
+    public Node getParentNode ()
+    {
+        return parent;
+    }
+
+
+    /**
+     * Get the list of child nodes.
+     *
+     * @return an empty node list
+     */
+    public NodeList getChildNodes ()
+    {
+        return new EmptyNodeList();
+    }
+
+
+    /**
+     * Get the first child node.
+     *
+     * @return null
+     */
+    public Node getFirstChild ()
+    {
+        return null;
+    }
+
+
+    /**
+     * Get the last child node.
+     *
+     * @return null
+     */
+    public Node getLastChild ()
+    {
+        return null;
+    }
+
+
+    /**
+     * Get the previous sibling node.
+     *
+     * @return null
+     */
+    public Node getPreviousSibling ()
+    {
+        return null;
+    }
+
+
+    /**
+     * Get the next sibling node.
+     *
+     * @return null
+     */
+    public Node getNextSibling ()
+    {
+        return null;
+    }
+
+
+    /**
+     * Get the attribute nodes.
+     *
+     * @return null
+     */
+    public NamedNodeMap getAttributes ()
+    {
+        return null;
+    }
+
+
+    /**
+     * Get the owner document.
+     *
+     * @return the owner document <em>of the parent node</em>
+     */
+    public Document getOwnerDocument ()
+    {
+        if (parent == null) return null;
+        return parent.getOwnerDocument();
+    }
+
+
+    /**
+     * Insert a new child node (always fails).
+     * 
+     * @param newChild the node to add
+     * @param refChild ignored
+     * @return never
+     * @throws DOMException always
+     * @see Node#insertBefore
+     */
+    public Node insertBefore (Node newChild, Node refChild)
+    throws DOMException
+    {
+        disallowModification();
+        return null;
+    }
+
+
+    /**
+     * Replace a child node (always fails).
+     *
+     * @param newChild the node to add
+     * @param oldChild the child node to replace
+     * @return never
+     * @throws DOMException always
+     * @see Node#replaceChild
+     */
+    public Node replaceChild (Node newChild, Node oldChild) throws DOMException
+    {
+        disallowModification();
+        return null;
+    }
+
+
+    /**
+     * Remove a child node (always fails).
+     *
+     * @param oldChild the child node to remove
+     * @return never
+     * @throws DOMException always
+     * @see Node#removeChild
+     */
+    public Node removeChild(Node oldChild) throws DOMException
+    {
+        disallowModification();
+        return null;
+    }
+
+
+    /**
+     * Append a new child node (always fails).
+     *
+     * @param newChild the node to add
+     * @return never
+     * @throws DOMException always
+     * @see Node#appendChild
+     */
+    public Node appendChild(Node newChild) throws DOMException
+    {
+        disallowModification();
+        return null;
+    }
+
+
+    /**
+     * Test for child nodes.
+     *
+     * @return false
+     */
+    public boolean hasChildNodes()
+    {
+        return false;
+    }
+
+
+    /**
+     * Create a copy of this node.
+     *
+     * @param deep make a deep copy (no effect, since namespace nodes
+     *        don't have children).
+     * @return a new copy of this namespace node
+     */
+    public Node cloneNode (boolean deep)
+    {
+        return new NamespaceNode(parent, name, value);
+    }
+
+
+    /**
+     * Normalize the text descendants of this node.
+     *
+     * <p>This method has no effect, since namespace nodes have no
+     * descendants.</p>
+     */
+    public void normalize ()
+    {
+    // no op
+    }
+
+
+    /**
+     * Test if a DOM2 feature is supported. (None are.)
+     *
+     * @param feature the feature name
+     * @param version the feature version
+     * @return false
+     */
+    public boolean isSupported(String feature, String version)
+    {
+        return false;
+    }
+
+
+    /**
+     * Get the namespace URI of this node.
+     *
+     * <p>Namespace declarations are not themselves
+     * Namespace-qualified.</p>
+     *
+     * @return null
+     */
+    public String getNamespaceURI()
+    {
+       return null;
+    }
+
+
+    /**
+     * Get the namespace prefix of this node.
+     *
+     * <p>Namespace declarations are not themselves
+     * namespace-qualified.</p>
+     *
+     * @return null
+     * @see #getLocalName
+     */
+    public String getPrefix()
+    {
+        return null;
+    }
+
+
+    /**
+     * Change the namespace prefix of this node (always fails).
+     *
+     * @param prefix the new prefix
+     * @throws DOMException always thrown
+     */
+    public void setPrefix(String prefix)
+    throws DOMException
+    {
+        disallowModification();
+    }
+
+
+    /**
+     * Get the XPath name of the namespace node;; i.e. the
+     * namespace prefix.
+     *
+     * @return the namespace prefix
+     */
+    public String getLocalName ()
+    {
+        return name;
+    }
+
+
+    /**
+     * Test if this node has attributes.
+     *
+     * @return false
+     */
+    public boolean hasAttributes ()
+    {
+        return false;
+    }
+
+
+    /**
+     * Throw a NO_MODIFICATION_ALLOWED_ERR DOMException.
+     *
+     * @throws DOMException always thrown
+     */
+    private void disallowModification () throws DOMException
+    {
+        throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR,
+                   "Namespace node may not be modified");
+    }
+
+
+

+    ////////////////////////////////////////////////////////////////////
+    // Override default methods from java.lang.Object.
+    ////////////////////////////////////////////////////////////////////
+
+
+    /**
+     * Generate a hash code for a namespace node.
+     *
+     * @return a hash code for this node
+     */
+    public int hashCode ()
+    {
+        return hashCode(parent) + hashCode(name) + hashCode(value);
+    }
+
+
+    /**
+     * Test for equivalence with another object.
+     *
+     * <p>Two Namespace nodes are considered equivalent if their parents,
+     * names, and values are equal.</p>
+     *
+     * @param o the object to test for equality
+     * @return true if the object is equivalent to this node, false
+     *         otherwise
+     */
+    public boolean equals (Object o)
+    {
+        if (o == this) return true;
+        else if (o == null) return false;
+        else if (o instanceof NamespaceNode) {
+            NamespaceNode ns = (NamespaceNode)o;
+            return (equals(parent, ns.getParentNode()) &&
+                equals(name, ns.getNodeName()) &&
+                equals(value, ns.getNodeValue()));
+        } else {
+            return false;
+        }
+    }
+
+
+    /**
+     * Helper method for generating a hash code.
+     *
+     * @param o the object for generating a hash code (possibly null)
+     * @return the object's hash code, or 0 if the object is null
+     * @see java.lang.Object#hashCode
+     */
+    private int hashCode (Object o)
+    {
+        return (o == null ? 0 : o.hashCode());
+    }
+
+
+    /**
+     * Helper method for comparing two objects.
+     *
+     * @param a the first object to compare (possibly null)
+     * @param b the second object to compare (possibly null)
+     * @return true if the objects are equivalent or are both null
+     * @see java.lang.Object#equals
+     */
+    private boolean equals (Object a, Object b)
+    {
+        return ((a == null && b == null) ||
+          (a != null && a.equals(b)));
+    }
+
+

+    ////////////////////////////////////////////////////////////////////
+    // Internal state.
+    ////////////////////////////////////////////////////////////////////
+
+    private Node parent;
+    private String name;
+    private String value;
+
+
+

+    ////////////////////////////////////////////////////////////////////
+    // Inner class: empty node list.
+    ////////////////////////////////////////////////////////////////////
+
+
+    /**
+     * A node list with no members.
+     *
+     * <p>This class is necessary for the {@link Node#getChildNodes}
+     * method, which must return an empty node list rather than
+     * null when there are no children.</p>
+     */
+    private static class EmptyNodeList implements NodeList
+    {
+
+        /**
+         * @see NodeList#getLength
+         */
+        public int getLength ()
+        {
+            return 0;
+        }
+    
+    
+        /**
+         * @see NodeList#item
+         */
+        public Node item(int index)
+        {
+            return null;
+        }
+    
+    }
+
+    ////////////////////////////////////////////////////////////////////
+    // DOM Level 3 methods
+    ////////////////////////////////////////////////////////////////////
+
+    /**
+     * Return the base URI of the document containing this node. 
+     * This only works in DOM 3.
+     *
+     * @return null
+     */
+    public String getBaseURI() {
+        Class clazz = Node.class;
+        try {
+            Class[] args = new Class[0];
+            Method getBaseURI = clazz.getMethod("getBaseURI", args);
+            String base = (String) getBaseURI.invoke(this.getParentNode(), args);
+            return base;
+        }
+        catch (Exception ex) {
+            return null;
+        }
+    }
+
+
+    /**
+     * Compare relative position of this node to another nbode. (Always fails).
+     * This method is included solely for compatibility with the superclass.
+     * 
+     * @param other the node to compare to
+     *
+     * @return never
+     * @throws DOMException NOT_SUPPORTED_ERR
+     */
+    public short compareDocumentPosition(Node other) throws DOMException {
+        DOMException ex = new DOMException(
+          DOMException.NOT_SUPPORTED_ERR,
+          "DOM level 3 interfaces are not fully implemented in Jaxen's NamespaceNode class"
+        );
+        throw ex;
+    }
+
+
+    /**
+     * Return the namespace URI.
+     *
+     * @return the namespace URI
+     * @see #getNodeValue
+     */
+    public String getTextContent() {
+        return value;
+    }
+
+
+    /**
+     * Change the value of this node (always fails).
+     * This method is included solely for compatibility with the superclass.
+     *
+     * @param textContent the new content
+     * @throws DOMException always
+     */
+    public void setTextContent(String textContent) throws DOMException {
+        disallowModification();
+    }
+
+
+    /**
+     * Returns true if and only if this object represents the same XPath namespace node
+     * as the argument; that is, they have the same parent, the same prefix, and the
+     * same URI.
+     * 
+     * @param other the node to compare to
+     * @return true if this object represents the same XPath namespace node
+     *     as other; false otherwise
+     */
+    public boolean isSameNode(Node other)  {
+        boolean a = this.isEqualNode(other);
+        // a bit flaky (should really be 
+        // this.getParentNode().isEqual(other.getParentNode())
+        // but we want this to compile in Java 1.4 without problems
+        // Note that this will mess up code coverage since you can't cover both
+        // branches in the same VM
+        boolean b;
+        Node thisParent = this.getParentNode();
+        Node thatParent = other.getParentNode();
+        try {
+            Class clazz = Node.class;
+            Class[] args = {clazz};
+            Method isEqual = clazz.getMethod("isEqual", args);
+            Object[] args2 = new Object[1];
+            args2[0] = thatParent;
+            Boolean result = (Boolean) isEqual.invoke(thisParent, args2);
+            b = result.booleanValue();
+        }
+        catch (NoSuchMethodException ex) {
+            b = thisParent.equals(thatParent);
+        }
+        catch (InvocationTargetException ex) {
+            b = thisParent.equals(thatParent);
+        }
+        catch (IllegalAccessException ex) {
+            b = thisParent.equals(thatParent);
+        }
+        
+        return a && b;
+        
+    }
+
+
+    /**
+     * Return the prefix bound to this namespace URI within the scope
+     * of this node. 
+     * 
+     * @param namespaceURI the URI to find a prefix binding for
+     *
+     * @return a prefix matching this namespace URI
+     * @throws UnsupportedOperationException in DOM 2
+     */
+    public String lookupPrefix(String namespaceURI) {
+        // This could be fully implemented even in Java 1.4. See
+        // http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/namespaces-algorithms.html#lookupNamespaceURIAlgo
+        // It hardly seems worth the effort though.
+        
+        try {
+            Class clazz = Node.class;
+            Class[] argTypes = {String.class};
+            Method lookupPrefix = clazz.getMethod("lookupPrefix", argTypes);
+            String[] args = {namespaceURI};
+            String result = (String) lookupPrefix.invoke(parent, args);
+            return result;
+        }
+        catch (NoSuchMethodException ex) {
+            throw new UnsupportedOperationException("Cannot lookup prefixes in DOM 2");
+        }
+        catch (InvocationTargetException ex) {
+            throw new UnsupportedOperationException("Cannot lookup prefixes in DOM 2");
+        }
+        catch (IllegalAccessException ex) {
+            throw new UnsupportedOperationException("Cannot lookup prefixes in DOM 2");
+        }
+        
+    }
+
+
+    /**
+     * Return true if the specified URI is the default namespace in
+     * scope (always fails). This method is included solely for 
+     * compatibility with the superclass.
+     * 
+     * @param namespaceURI the URI to check
+     *
+     * @return never
+     * @throws UnsupportedOperationException always
+     */
+    public boolean isDefaultNamespace(String namespaceURI) {
+        return namespaceURI.equals(this.lookupNamespaceURI(null));
+    }
+
+
+    /**
+     * Return the namespace URI mapped to the specified
+     * prefix within the scope of this namespace node.
+     * 
+     * @param prefix the prefix to search for
+     *
+     * @return the namespace URI mapped to this prefix
+     * @throws UnsupportedOperationException in DOM 2
+     */
+    public String lookupNamespaceURI(String prefix) {
+        // This could be fully implemented even in Java 1.4. See
+        // http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/namespaces-algorithms.html#lookupNamespaceURIAlgo
+        // It hardly seems worth the effort though.
+        
+        try {
+            Class clazz = Node.class;
+            Class[] argTypes = {String.class};
+            Method lookupNamespaceURI = clazz.getMethod("lookupNamespaceURI", argTypes);
+            String[] args = {prefix};
+            String result = (String) lookupNamespaceURI.invoke(parent, args);
+            return result;
+        }
+        catch (NoSuchMethodException ex) {
+            throw new UnsupportedOperationException("Cannot lookup namespace URIs in DOM 2");
+        }
+        catch (InvocationTargetException ex) {
+            throw new UnsupportedOperationException("Cannot lookup namespace URIs in DOM 2");
+        }
+        catch (IllegalAccessException ex) {
+            throw new UnsupportedOperationException("Cannot lookup namespace URIs in DOM 2");
+        }
+    }
+
+
+    /**
+     * Returns true if this object binds the same prefix to the same URI.
+     * That is, this object has the same prefix and URI as the argument.
+     * 
+     * @param arg the node to compare to
+     * @return true if this object has the same prefix and URI as the argument; false otherwise
+     */
+    public boolean isEqualNode(Node arg) {
+        if (arg.getNodeType() == this.getNodeType()) {
+            NamespaceNode other = (NamespaceNode) arg;
+            if (other.name == null && this.name != null) return false;
+            else if (other.name != null && this.name == null) return false;
+            else if (other.value == null && this.value != null) return false;
+            else if (other.value != null && this.value == null) return false;
+            else if (other.name == null && this.name == null) {
+                return other.value.equals(this.value);
+            }
+
+            return other.name.equals(this.name) && other.value.equals(this.value);
+        }
+        return false;
+    }
+
+
+    /**
+     * Returns the value of the requested feature. Always returns null.
+     * 
+     * @return null
+     */
+    public Object getFeature(String feature, String version) {
+        return null;
+    }
+
+    
+    // XXX userdata needs testing
+    private HashMap userData = new HashMap();
+
+    /**
+     * Associates an object with a key. 
+     * 
+     * @param key the key by which the data will be retrieved
+     * @param data the object to store with the key
+     * @param handler ignored since namespace nodes cannot be imported, cloned, or renamed
+     * 
+     * @return the value previously associated with this key; or null
+     *     if there isn't any such previous value
+     */
+    public Object setUserData(String key, Object data, UserDataHandler handler) {
+        Object oldValue = getUserData(key);
+        userData.put(key, data);
+        return oldValue;
+    }
+
+
+    /**
+     * Returns the user data associated with the given key. 
+     * 
+     * @param key the lookup key
+     * 
+     * @return the object associated with the key; or null if no such object is available
+     */
+    public Object getUserData(String key) {
+        return userData.get(key);
+    }
+    
+}
+
+// end of NamespaceNode.java
diff --git a/libjaxen-java/src/java/main/org/jaxen/dom/package.html b/libjaxen-java/src/java/main/org/jaxen/dom/package.html
new file mode 100644
index 0000000..6c68750
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/dom/package.html
@@ -0,0 +1,13 @@
+<html>
+	<head>
+		<title>
+			org.jaxen.dom.*
+		</title>
+	</head>
+
+	<body>
+		<p>
+			Navigation for <a href="http://www.w3.org/DOM/">W3C DOM</a> trees.
+		</p>
+	</body>
+</html>
diff --git a/libjaxen-java/src/java/main/org/jaxen/dom4j/DocumentNavigator.java b/libjaxen-java/src/java/main/org/jaxen/dom4j/DocumentNavigator.java
new file mode 100644
index 0000000..edff3c5
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/dom4j/DocumentNavigator.java
@@ -0,0 +1,501 @@
+package org.jaxen.dom4j;
+
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/dom4j/DocumentNavigator.java,v 1.33 2006/07/03 13:17:30 elharo Exp $
+ * $Revision: 1.33 $
+ * $Date: 2006/07/03 13:17:30 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2005 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Jaxen Project and was originally
+ * created by bob mcwhirter <bob at werken.com> and
+ * James Strachan <jstrachan at apache.org>.  For more information on the
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ *
+ * $Id: DocumentNavigator.java,v 1.33 2006/07/03 13:17:30 elharo Exp $
+*/
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+
+import org.dom4j.Attribute;
+import org.dom4j.Branch;
+import org.dom4j.CDATA;
+import org.dom4j.Comment;
+import org.dom4j.Document;
+import org.dom4j.DocumentException;
+import org.dom4j.Element;
+import org.dom4j.Namespace;
+import org.dom4j.Node;
+import org.dom4j.ProcessingInstruction;
+import org.dom4j.QName;
+import org.dom4j.Text;
+import org.dom4j.io.SAXReader;
+import org.jaxen.DefaultNavigator;
+import org.jaxen.FunctionCallException;
+import org.jaxen.NamedAccessNavigator;
+import org.jaxen.Navigator;
+import org.jaxen.XPath;
+import org.jaxen.JaxenConstants;
+import org.jaxen.saxpath.SAXPathException;
+import org.jaxen.util.SingleObjectIterator;
+
+/** 
+ * Interface for navigating around the DOM4J object model.
+ *
+ * <p>
+ * This class is not intended for direct usage, but is
+ * used by the Jaxen engine during evaluation.
+ * </p>
+ *
+ * @see XPath
+ *
+ * @author <a href="mailto:bob at werken.com">bob mcwhirter</a>
+ * @author Stephen Colebourne
+ */
+public class DocumentNavigator extends DefaultNavigator implements NamedAccessNavigator
+{
+    
+    /**
+     * 
+     */
+    private static final long serialVersionUID = 5582300797286535936L;
+    private transient SAXReader reader;
+
+    /** Singleton implementation.
+     */
+    private static class Singleton
+    {
+        /** Singleton instance.
+         */
+        private static DocumentNavigator instance = new DocumentNavigator();
+    }
+
+    /** Retrieve the singleton instance of this <code>DocumentNavigator</code>.
+     */
+    public static Navigator getInstance()
+    {
+        return Singleton.instance;
+    }
+
+    public boolean isElement(Object obj)
+    {
+        return obj instanceof Element;
+    }
+
+    public boolean isComment(Object obj)
+    {
+        return obj instanceof Comment;
+    }
+
+    public boolean isText(Object obj)
+    {
+        return ( obj instanceof Text 
+                 ||
+                 obj instanceof CDATA );
+    }
+
+    public boolean isAttribute(Object obj)
+    {
+        return obj instanceof Attribute;
+    }
+
+    public boolean isProcessingInstruction(Object obj)
+    {
+        return obj instanceof ProcessingInstruction;
+    }
+
+    public boolean isDocument(Object obj)
+    {
+        return obj instanceof Document;
+    }
+
+    public boolean isNamespace(Object obj)
+    {
+        return obj instanceof Namespace;
+    }
+
+    public String getElementName(Object obj)
+    {
+        Element elem = (Element) obj;
+
+        return elem.getName();
+    }
+
+    public String getElementNamespaceUri(Object obj)
+    {
+        Element elem = (Element) obj;
+        
+        String uri = elem.getNamespaceURI();
+        if ( uri == null)
+            return "";
+        else
+            return uri;
+    }
+
+    public String getElementQName(Object obj)
+    {
+        Element elem = (Element) obj;
+
+        return elem.getQualifiedName();
+    }
+
+    public String getAttributeName(Object obj)
+    {
+        Attribute attr = (Attribute) obj;
+
+        return attr.getName();
+    }
+
+    public String getAttributeNamespaceUri(Object obj)
+    {
+        Attribute attr = (Attribute) obj;
+
+        String uri = attr.getNamespaceURI();
+        if ( uri == null)
+            return "";
+        else
+            return uri;
+    }
+
+    public String getAttributeQName(Object obj)
+    {
+        Attribute attr = (Attribute) obj;
+
+        return attr.getQualifiedName();
+    }
+
+    public Iterator getChildAxisIterator(Object contextNode)
+    {
+        Iterator result = null;
+        if ( contextNode instanceof Branch )
+        {
+            Branch node = (Branch) contextNode;
+            result = node.nodeIterator();
+        }
+        if (result != null) {
+            return result;
+        }
+        return JaxenConstants.EMPTY_ITERATOR;
+    }
+
+    /**
+     * Retrieves an <code>Iterator</code> over the child elements that
+     * match the supplied name.
+     *
+     * @param contextNode      the origin context node
+     * @param localName        the local name of the children to return, always present
+     * @param namespacePrefix  the prefix of the namespace of the children to return
+     * @param namespaceURI     the uri of the namespace of the children to return
+     * 
+     * @return an Iterator that traverses the named children, or null if none
+     */
+    public Iterator getChildAxisIterator(
+            Object contextNode, String localName, String namespacePrefix, String namespaceURI) {
+
+        if ( contextNode instanceof Element ) {
+            Element node = (Element) contextNode;
+            return node.elementIterator(QName.get(localName, namespacePrefix, namespaceURI));
+        }
+        if ( contextNode instanceof Document ) {
+            Document node = (Document) contextNode;
+            Element el = node.getRootElement();
+            if (el == null || el.getName().equals(localName) == false) {
+                return JaxenConstants.EMPTY_ITERATOR;
+            }
+            if (namespaceURI != null) {
+                if (namespaceURI.equals(el.getNamespaceURI()) == false) {
+                    return JaxenConstants.EMPTY_ITERATOR;
+                }
+            }
+            return new SingleObjectIterator(el);
+        }
+
+        return JaxenConstants.EMPTY_ITERATOR;
+    }
+
+    public Iterator getParentAxisIterator(Object contextNode)
+    {
+        if ( contextNode instanceof Document )
+        {
+            return JaxenConstants.EMPTY_ITERATOR;
+        }
+
+        Node node = (Node) contextNode;
+
+        Object parent = node.getParent();
+
+        if ( parent == null )
+        {
+            parent = node.getDocument();
+        }
+        
+        return new SingleObjectIterator( parent );
+    }
+
+    public Iterator getAttributeAxisIterator(Object contextNode)
+    {
+        if ( ! ( contextNode instanceof Element ) )
+        {
+            return JaxenConstants.EMPTY_ITERATOR;
+        }
+
+        Element elem = (Element) contextNode;
+
+        return elem.attributeIterator();
+    }
+
+    /**
+     * Retrieves an <code>Iterator</code> over the attribute elements that
+     * match the supplied name.
+     *
+     * @param contextNode  the origin context node
+     * @param localName  the local name of the attributes to return, always present
+     * @param namespacePrefix  the prefix of the namespace of the attributes to return
+     * @param namespaceURI  the URI of the namespace of the attributes to return
+     * @return an Iterator that traverses the named attributes, not null
+     */
+    public Iterator getAttributeAxisIterator(
+            Object contextNode, String localName, String namespacePrefix, String namespaceURI) {
+
+        if ( contextNode instanceof Element ) {
+            Element node = (Element) contextNode;
+            Attribute attr = node.attribute(QName.get(localName, namespacePrefix, namespaceURI));
+            if (attr == null) {
+                return JaxenConstants.EMPTY_ITERATOR;
+            }
+            return new SingleObjectIterator(attr);
+        }
+        return JaxenConstants.EMPTY_ITERATOR;
+    }
+        
+    public Iterator getNamespaceAxisIterator(Object contextNode)
+    {
+        if ( ! ( contextNode instanceof Element ) )
+        {
+            return JaxenConstants.EMPTY_ITERATOR;
+        }
+
+        Element element = (Element) contextNode;
+        List nsList = new ArrayList();
+        HashSet prefixes = new HashSet();
+        for ( Element context = element; context != null; context = context.getParent() ) {
+            List declaredNS = new ArrayList(context.declaredNamespaces());
+            declaredNS.add(context.getNamespace());
+
+            for ( Iterator iter = context.attributes().iterator(); iter.hasNext(); )
+            {
+                Attribute attr = (Attribute) iter.next();
+                declaredNS.add(attr.getNamespace());
+            }
+
+            for ( Iterator iter = declaredNS.iterator(); iter.hasNext(); )
+            {
+                Namespace namespace = (Namespace) iter.next();
+                if (namespace != Namespace.NO_NAMESPACE)
+                {
+                    String prefix = namespace.getPrefix();
+                    if ( ! prefixes.contains( prefix ) ) {
+                        prefixes.add( prefix );
+                        nsList.add( namespace.asXPathResult( element ) );
+                    }
+                }
+            }
+        }
+        nsList.add( Namespace.XML_NAMESPACE.asXPathResult( element ) );
+        return nsList.iterator();
+    }
+
+    public Object getDocumentNode(Object contextNode)
+    {
+        if ( contextNode instanceof Document ) 
+        {
+            return contextNode;
+        }
+        else if ( contextNode instanceof Node ) 
+        {
+            Node node = (Node) contextNode;
+            return node.getDocument();
+        }
+        return null;
+    }
+
+    /** Returns a parsed form of the given XPath string, which will be suitable
+     *  for queries on DOM4J documents.
+     */
+    public XPath parseXPath (String xpath) throws SAXPathException
+    {
+        return new Dom4jXPath(xpath);
+    }
+
+    public Object getParentNode(Object contextNode)
+    {
+        if ( contextNode instanceof Node ) 
+        {
+            Node node = (Node) contextNode;
+            Object answer = node.getParent();
+            if ( answer == null ) 
+            {
+                answer = node.getDocument();
+                if (answer == contextNode) {
+                    return null;
+                }
+            }
+            return answer;            
+        }
+        return null;
+    }
+
+    public String getTextStringValue(Object obj)
+    {
+        return getNodeStringValue( (Node) obj );
+    }
+
+    public String getElementStringValue(Object obj)
+    {
+        return getNodeStringValue( (Node) obj );
+    }
+
+    public String getAttributeStringValue(Object obj)
+    {
+        return getNodeStringValue( (Node) obj );
+    }
+
+    private String getNodeStringValue(Node node)
+    {
+        return node.getStringValue();
+    }
+
+    public String getNamespaceStringValue(Object obj)
+    {
+        Namespace ns = (Namespace) obj;
+
+        return ns.getURI();
+    }
+
+    public String getNamespacePrefix(Object obj)
+    {
+        Namespace ns = (Namespace) obj;
+
+        return ns.getPrefix();
+    }
+
+    public String getCommentStringValue(Object obj)
+    {
+        Comment cmt = (Comment) obj;
+
+        return cmt.getText();
+    }
+    
+    public String translateNamespacePrefixToUri(String prefix, Object context)
+    {
+        Element element = null;
+        if ( context instanceof Element ) 
+        {
+            element = (Element) context;
+        }
+        else if ( context instanceof Node )
+        {
+            Node node = (Node) context;
+            element = node.getParent();
+        }
+        if ( element != null )
+        {
+            Namespace namespace = element.getNamespaceForPrefix( prefix );
+
+            if ( namespace != null ) 
+            {
+                return namespace.getURI();
+            }
+        }
+        return null;
+    }
+    
+    public short getNodeType(Object node) 
+    {
+        if ( node instanceof Node )
+        {
+            return ((Node) node).getNodeType();
+        }
+        return 0;
+    }
+    
+    public Object getDocument(String uri) throws FunctionCallException
+    {
+        try
+        {
+            return getSAXReader().read( uri );
+        }
+        catch (DocumentException e)
+        {
+            throw new FunctionCallException("Failed to parse document for URI: " + uri, e);
+        }
+    }
+
+    public String getProcessingInstructionTarget(Object obj)
+    {
+        ProcessingInstruction pi = (ProcessingInstruction) obj;
+
+        return pi.getTarget();
+    }
+
+    public String getProcessingInstructionData(Object obj)
+    {
+        ProcessingInstruction pi = (ProcessingInstruction) obj;
+
+        return pi.getText();
+    }
+    
+    // Properties
+    //-------------------------------------------------------------------------    
+    public SAXReader getSAXReader()
+    {
+        if ( reader == null ) 
+        {
+            reader = new SAXReader();
+            reader.setMergeAdjacentText( true );
+        }
+        return reader;
+    }
+    
+    public void setSAXReader(SAXReader reader)
+    {
+        this.reader = reader;
+    }
+    
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/dom4j/Dom4jXPath.java b/libjaxen-java/src/java/main/org/jaxen/dom4j/Dom4jXPath.java
new file mode 100644
index 0000000..7690e1a
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/dom4j/Dom4jXPath.java
@@ -0,0 +1,94 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/dom4j/Dom4jXPath.java,v 1.8 2006/06/03 20:44:53 elharo Exp $
+ * $Revision: 1.8 $
+ * $Date: 2006/06/03 20:44:53 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: Dom4jXPath.java,v 1.8 2006/06/03 20:44:53 elharo Exp $
+ */
+
+
+
+package org.jaxen.dom4j;
+
+import org.jaxen.BaseXPath;
+import org.jaxen.JaxenException;
+
+/** An XPath implementation for the dom4j model
+ *
+ * <p>This is the main entry point for matching an XPath against a DOM
+ * tree.  You create a compiled XPath object, then match it against
+ * one or more context nodes using the {@link #selectNodes(Object)}
+ * method, as in the following example:</p>
+ *
+ * <pre>
+ * Node node = ...;
+ * XPath path = new Dom4jXPath("a/b/c");
+ * List results = path.selectNodes(node);
+ * </pre>
+ *
+ * @see BaseXPath
+ * @see <a href="http://dom4j.org/">The dom4j website</a>
+ *
+ * @author <a href="mailto:bob at werken.com">bob mcwhirter</a>
+ * @author <a href="mailto:jstachan at apache.org">James Strachan</a>
+ *
+ * @version $Revision: 1.8 $
+ */
+public class Dom4jXPath extends BaseXPath
+{
+    /**
+     * 
+     */
+    private static final long serialVersionUID = -75510941087659775L;
+
+    /** Construct given an XPath expression string.
+     *
+     *  @param xpathExpr the XPath expression
+     *
+     *  @throws JaxenException if there is a syntax error while
+     *          parsing the expression
+     */
+    public Dom4jXPath(String xpathExpr) throws JaxenException
+    {
+        super( xpathExpr, DocumentNavigator.getInstance() );
+    }
+} 
diff --git a/libjaxen-java/src/java/main/org/jaxen/dom4j/package.html b/libjaxen-java/src/java/main/org/jaxen/dom4j/package.html
new file mode 100644
index 0000000..123ff56
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/dom4j/package.html
@@ -0,0 +1,13 @@
+<html>
+	<head>
+		<title>
+			org.jaxen.dom4j.*
+		</title>
+	</head>
+
+	<body>
+		<p>
+			Navigation for <a href="http://dom4j.org">dom4j</a> trees.
+		</p>
+	</body>
+</html>
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/AdditiveExpr.java b/libjaxen-java/src/java/main/org/jaxen/expr/AdditiveExpr.java
new file mode 100644
index 0000000..6345361
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/AdditiveExpr.java
@@ -0,0 +1,53 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/AdditiveExpr.java,v 1.4 2006/02/05 21:47:40 elharo Exp $
+ * $Revision: 1.4 $
+ * $Date: 2006/02/05 21:47:40 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Jaxen Project and was originally
+ * created by bob mcwhirter <bob at werken.com> and
+ * James Strachan <jstrachan at apache.org>.  For more information on the
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ *
+ * $Id: AdditiveExpr.java,v 1.4 2006/02/05 21:47:40 elharo Exp $
+ */
+package org.jaxen.expr;
+
+public interface AdditiveExpr extends BinaryExpr
+{
+    String getOperator();
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/AllNodeStep.java b/libjaxen-java/src/java/main/org/jaxen/expr/AllNodeStep.java
new file mode 100644
index 0000000..d4d38ec
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/AllNodeStep.java
@@ -0,0 +1,51 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/AllNodeStep.java,v 1.5 2006/02/05 21:47:40 elharo Exp $
+ * $Revision: 1.5 $
+ * $Date: 2006/02/05 21:47:40 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: AllNodeStep.java,v 1.5 2006/02/05 21:47:40 elharo Exp $
+ */
+package org.jaxen.expr;
+
+public interface AllNodeStep extends Step
+{
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/BinaryExpr.java b/libjaxen-java/src/java/main/org/jaxen/expr/BinaryExpr.java
new file mode 100644
index 0000000..5dc96ba
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/BinaryExpr.java
@@ -0,0 +1,56 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/BinaryExpr.java,v 1.6 2006/02/05 21:47:40 elharo Exp $
+ * $Revision: 1.6 $
+ * $Date: 2006/02/05 21:47:40 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: BinaryExpr.java,v 1.6 2006/02/05 21:47:40 elharo Exp $
+ */
+
+
+
+package org.jaxen.expr;
+
+public interface BinaryExpr extends Expr
+{
+    Expr getLHS();
+    Expr getRHS();
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/CommentNodeStep.java b/libjaxen-java/src/java/main/org/jaxen/expr/CommentNodeStep.java
new file mode 100644
index 0000000..bd8823d
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/CommentNodeStep.java
@@ -0,0 +1,51 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/CommentNodeStep.java,v 1.5 2006/02/05 21:47:40 elharo Exp $
+ * $Revision: 1.5 $
+ * $Date: 2006/02/05 21:47:40 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: CommentNodeStep.java,v 1.5 2006/02/05 21:47:40 elharo Exp $
+ */
+package org.jaxen.expr;
+
+public interface CommentNodeStep extends Step
+{
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/DefaultAbsoluteLocationPath.java b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultAbsoluteLocationPath.java
new file mode 100644
index 0000000..5e01b3c
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultAbsoluteLocationPath.java
@@ -0,0 +1,121 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/DefaultAbsoluteLocationPath.java,v 1.17 2006/06/03 20:52:26 elharo Exp $
+ * $Revision: 1.17 $
+ * $Date: 2006/06/03 20:52:26 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Jaxen Project and was originally
+ * created by bob mcwhirter <bob at werken.com> and
+ * James Strachan <jstrachan at apache.org>.  For more information on the
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ *
+ * $Id: DefaultAbsoluteLocationPath.java,v 1.17 2006/06/03 20:52:26 elharo Exp $
+ */
+package org.jaxen.expr;
+
+import java.util.Collections;
+import java.util.List;
+
+import org.jaxen.Context;
+import org.jaxen.ContextSupport;
+import org.jaxen.JaxenException;
+import org.jaxen.Navigator;
+import org.jaxen.util.SingletonList;
+
+/**
+ * @deprecated this class will become non-public in the future;
+ *     use the interface instead
+ */
+public class DefaultAbsoluteLocationPath extends DefaultLocationPath 
+{
+    /**
+     * 
+     */
+    private static final long serialVersionUID = 2174836928310146874L;
+
+    public DefaultAbsoluteLocationPath()
+    {
+    }
+
+    public String toString()
+    {
+        return "[(DefaultAbsoluteLocationPath): " + super.toString() + "]";
+    }
+
+    public boolean isAbsolute() 
+    {
+        return true;
+    }
+
+    public String getText()
+    {
+        return "/" + super.getText();
+    }
+
+    public Object evaluate(Context context) throws JaxenException
+    {
+        ContextSupport support = context.getContextSupport();
+        Navigator      nav     = support.getNavigator();
+        Context absContext = new Context( support );
+        List contextNodes = context.getNodeSet();
+
+        if ( contextNodes.isEmpty() )
+        {
+            return Collections.EMPTY_LIST;
+        }
+
+        Object firstNode = contextNodes.get( 0 );
+        Object docNode   = nav.getDocumentNode( firstNode );
+
+        if ( docNode == null )
+        {
+            return Collections.EMPTY_LIST;
+        }
+
+        List list = new SingletonList(docNode);
+
+        absContext.setNodeSet( list );
+
+        return super.evaluate( absContext );
+    }
+
+    public void accept(Visitor visitor)
+    {
+        visitor.visit(this);
+    }
+}
+
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/DefaultAdditiveExpr.java b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultAdditiveExpr.java
new file mode 100644
index 0000000..37aa478
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultAdditiveExpr.java
@@ -0,0 +1,64 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/DefaultAdditiveExpr.java,v 1.9 2006/02/05 21:47:40 elharo Exp $
+ * $Revision: 1.9 $
+ * $Date: 2006/02/05 21:47:40 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Jaxen Project and was originally
+ * created by bob mcwhirter <bob at werken.com> and
+ * James Strachan <jstrachan at apache.org>.  For more information on the
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ *
+ * $Id: DefaultAdditiveExpr.java,v 1.9 2006/02/05 21:47:40 elharo Exp $
+ */
+package org.jaxen.expr;
+
+abstract class DefaultAdditiveExpr extends DefaultArithExpr implements AdditiveExpr
+{
+    DefaultAdditiveExpr( Expr lhs,
+                                Expr rhs )
+    {
+        super( lhs,
+               rhs );
+    }
+
+    public String toString()
+    {
+        return "[(" + getClass().getName() + "): " + getLHS() + ", " + getRHS() + "]";
+    }
+}
+
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/DefaultAllNodeStep.java b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultAllNodeStep.java
new file mode 100644
index 0000000..1067c74
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultAllNodeStep.java
@@ -0,0 +1,91 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/DefaultAllNodeStep.java,v 1.13 2006/06/03 20:52:26 elharo Exp $
+ * $Revision: 1.13 $
+ * $Date: 2006/06/03 20:52:26 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: DefaultAllNodeStep.java,v 1.13 2006/06/03 20:52:26 elharo Exp $
+ */
+
+
+
+package org.jaxen.expr;
+
+import org.jaxen.ContextSupport;
+import org.jaxen.expr.iter.IterableAxis;
+
+/**
+ * @deprecated this class will become non-public in the future;
+ *     use the interface instead
+ */
+public class DefaultAllNodeStep extends DefaultStep implements AllNodeStep
+{
+    /**
+     * 
+     */
+    private static final long serialVersionUID = 292886316770123856L;
+    
+    public DefaultAllNodeStep(IterableAxis axis, PredicateSet predicateSet)
+    {
+        super( axis, predicateSet );
+    }
+
+    public String toString()
+    {
+        return "[(DefaultAllNodeStep): " + getAxisName() + "]";
+    }
+
+    public String getText()
+    {
+        return getAxisName() + "::node()" + super.getText();
+    }
+
+    public boolean matches(Object node,
+                           ContextSupport contextSupport)
+    {
+        return true;
+    }
+    
+    public void accept(Visitor visitor)
+    {
+        visitor.visit(this);
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/DefaultAndExpr.java b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultAndExpr.java
new file mode 100644
index 0000000..7510bae
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultAndExpr.java
@@ -0,0 +1,106 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/DefaultAndExpr.java,v 1.15 2006/06/03 20:52:26 elharo Exp $
+ * $Revision: 1.15 $
+ * $Date: 2006/06/03 20:52:26 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: DefaultAndExpr.java,v 1.15 2006/06/03 20:52:26 elharo Exp $
+ */
+
+package org.jaxen.expr;
+
+import org.jaxen.Context;
+import org.jaxen.JaxenException;
+import org.jaxen.Navigator;
+import org.jaxen.function.BooleanFunction;
+
+class DefaultAndExpr extends DefaultLogicalExpr
+{
+    /**
+     * 
+     */
+    private static final long serialVersionUID = -5237984010263103742L;
+
+    DefaultAndExpr(Expr lhs,
+                          Expr rhs)
+    {
+        super( lhs,
+               rhs );
+    }
+
+    public String getOperator()
+    {
+        return "and";
+    }
+
+    public String toString()
+    {
+        return "[(DefaultAndExpr): " + getLHS() + ", " + getRHS() + "]";
+    }
+
+    public Object evaluate(Context context) throws JaxenException
+    {
+        Navigator nav = context.getNavigator();
+        Boolean lhsValue = BooleanFunction.evaluate( getLHS().evaluate( context ), nav );
+
+        if ( !lhsValue.booleanValue() )
+        {
+            return Boolean.FALSE;
+        }
+
+        // Short circuits are required in XPath. "The right operand is not 
+        // evaluated if the left operand evaluates to false."
+        Boolean rhsValue = BooleanFunction.evaluate( getRHS().evaluate( context ), nav );
+
+        if ( !rhsValue.booleanValue() )
+        {
+            return Boolean.FALSE;
+        }
+
+        return Boolean.TRUE;
+    }
+    
+    public void accept(Visitor visitor)
+    {
+        visitor.visit(this);
+    }
+    
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/DefaultArithExpr.java b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultArithExpr.java
new file mode 100644
index 0000000..e3f42bb
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultArithExpr.java
@@ -0,0 +1,66 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/DefaultArithExpr.java,v 1.10 2006/02/05 21:47:40 elharo Exp $
+ * $Revision: 1.10 $
+ * $Date: 2006/02/05 21:47:40 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: DefaultArithExpr.java,v 1.10 2006/02/05 21:47:40 elharo Exp $
+ */
+
+
+
+package org.jaxen.expr;
+
+abstract class DefaultArithExpr extends DefaultBinaryExpr 
+{
+    DefaultArithExpr(Expr lhs,
+                            Expr rhs)
+    {
+        super( lhs,
+               rhs );
+    }
+
+    public String toString()
+    {
+        return "[(DefaultArithExpr): " + getLHS() + ", " + getRHS() + "]";
+    }
+
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/DefaultBinaryExpr.java b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultBinaryExpr.java
new file mode 100644
index 0000000..2685a86
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultBinaryExpr.java
@@ -0,0 +1,103 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/DefaultBinaryExpr.java,v 1.8 2006/02/05 21:47:40 elharo Exp $
+ * $Revision: 1.8 $
+ * $Date: 2006/02/05 21:47:40 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: DefaultBinaryExpr.java,v 1.8 2006/02/05 21:47:40 elharo Exp $
+ */
+
+
+
+package org.jaxen.expr;
+
+abstract class DefaultBinaryExpr extends DefaultExpr implements BinaryExpr
+{
+    private Expr lhs;
+    private Expr rhs;
+
+    DefaultBinaryExpr(Expr lhs,
+                             Expr rhs)
+    {
+        this.lhs = lhs;
+        this.rhs = rhs;
+    }
+
+    public Expr getLHS()
+    {
+        return this.lhs;
+    }
+
+    public Expr getRHS()
+    {
+        return this.rhs;
+    }
+
+    public void setLHS(Expr lhs)
+    {
+        this.lhs = lhs;
+    }
+
+    public void setRHS(Expr rhs)
+    {
+        this.rhs = rhs;
+    }
+
+    public abstract String getOperator();
+
+    public String getText()
+    {
+        return "(" + getLHS().getText() + " " + getOperator() + " " + getRHS().getText() + ")";
+    }
+
+    public String toString()
+    {
+        return "[(" + getClass().getName() + "): " + getLHS() + ", " + getRHS() + "]";
+    }
+
+    public Expr simplify()
+    {
+        setLHS( getLHS().simplify() );
+        setRHS( getRHS().simplify() );
+
+        return this;
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/DefaultCommentNodeStep.java b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultCommentNodeStep.java
new file mode 100644
index 0000000..884467e
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultCommentNodeStep.java
@@ -0,0 +1,92 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/DefaultCommentNodeStep.java,v 1.13 2006/06/03 20:52:26 elharo Exp $
+ * $Revision: 1.13 $
+ * $Date: 2006/06/03 20:52:26 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: DefaultCommentNodeStep.java,v 1.13 2006/06/03 20:52:26 elharo Exp $
+ */
+
+
+
+package org.jaxen.expr;
+
+import org.jaxen.ContextSupport;
+import org.jaxen.Navigator;
+import org.jaxen.expr.iter.IterableAxis;
+
+/**
+ * @deprecated this class will become non-public in the future;
+ *     use the interface instead
+ */
+public class DefaultCommentNodeStep extends DefaultStep implements CommentNodeStep
+{
+    /**
+     * 
+     */
+    private static final long serialVersionUID = 4340788283861875606L;
+    public DefaultCommentNodeStep(IterableAxis axis, PredicateSet predicateSet)
+    {
+        super( axis, predicateSet );
+    }
+
+    public String toString()
+    {
+        return "[(DefaultCommentNodeStep): " + getAxis() + "]";
+    }
+
+    public String getText()
+    {
+        return getAxisName() + "::comment()";
+    }
+
+    public boolean matches(Object node,
+                           ContextSupport contextSupport)
+    {
+        Navigator nav = contextSupport.getNavigator();
+
+        return nav.isComment( node );
+    }
+    public void accept(Visitor visitor)
+    {
+        visitor.visit(this);
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/DefaultDivExpr.java b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultDivExpr.java
new file mode 100644
index 0000000..61149a0
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultDivExpr.java
@@ -0,0 +1,88 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/DefaultDivExpr.java,v 1.13 2006/06/03 20:52:26 elharo Exp $
+ * $Revision: 1.13 $
+ * $Date: 2006/06/03 20:52:26 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: DefaultDivExpr.java,v 1.13 2006/06/03 20:52:26 elharo Exp $
+ */
+
+
+package org.jaxen.expr;
+
+import org.jaxen.Context;
+import org.jaxen.JaxenException;
+import org.jaxen.function.NumberFunction;
+
+class DefaultDivExpr extends DefaultMultiplicativeExpr
+{
+    /**
+     * 
+     */
+    private static final long serialVersionUID = 6318739386201615441L;
+    DefaultDivExpr(Expr lhs,
+                          Expr rhs)
+    {
+        super( lhs,
+               rhs );
+    }
+
+    public String getOperator()
+    {
+        return "div";
+    }
+
+    public Object evaluate(Context context) throws JaxenException
+    {
+        Number lhsValue = NumberFunction.evaluate( getLHS().evaluate( context ),
+                                                   context.getNavigator() );
+        Number rhsValue = NumberFunction.evaluate( getRHS().evaluate( context ),
+                                                   context.getNavigator() );
+
+        double result = lhsValue.doubleValue() / rhsValue.doubleValue();
+
+        return new Double( result );
+    }
+    public void accept(Visitor visitor)
+    {
+        visitor.visit(this);
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/DefaultEqualityExpr.java b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultEqualityExpr.java
new file mode 100644
index 0000000..398278b
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultEqualityExpr.java
@@ -0,0 +1,155 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/DefaultEqualityExpr.java,v 1.14 2006/02/05 21:47:40 elharo Exp $
+ * $Revision: 1.14 $
+ * $Date: 2006/02/05 21:47:40 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: DefaultEqualityExpr.java,v 1.14 2006/02/05 21:47:40 elharo Exp $
+ */
+
+
+
+package org.jaxen.expr;
+
+import java.util.Iterator;
+import java.util.List;
+import org.jaxen.Context;
+import org.jaxen.JaxenException;
+import org.jaxen.Navigator;
+import org.jaxen.function.BooleanFunction;
+import org.jaxen.function.NumberFunction;
+import org.jaxen.function.StringFunction;
+
+abstract class DefaultEqualityExpr extends DefaultTruthExpr implements EqualityExpr 
+  {
+  DefaultEqualityExpr( Expr lhs, Expr rhs )
+    {
+    super( lhs, rhs );
+    }
+
+  public String toString()
+    {
+    return "[(DefaultEqualityExpr): " + getLHS() + ", " + getRHS() + "]";
+    }
+  
+  public Object evaluate( Context context ) throws JaxenException
+    {
+    Object lhsValue = getLHS().evaluate( context );
+    Object rhsValue = getRHS().evaluate( context );
+    
+    if( lhsValue == null || rhsValue == null )
+      {
+      return Boolean.FALSE;
+      }
+    
+    Navigator nav = context.getNavigator();
+
+    if( bothAreSets( lhsValue, rhsValue ) )
+      {
+      return evaluateSetSet( (List) lhsValue, (List) rhsValue, nav );
+      }
+    else if ( eitherIsSet( lhsValue, rhsValue ) )
+      {
+      if ( isSet( lhsValue ) )
+        {
+        return evaluateSetSet( (List) lhsValue, convertToList( rhsValue ), nav );                
+        }
+      else
+        {
+        return evaluateSetSet( convertToList( lhsValue ), (List) rhsValue, nav );                                
+        }
+      }  
+    else
+      {
+      return evaluateObjectObject( lhsValue, rhsValue, nav ) ? Boolean.TRUE : Boolean.FALSE;
+      }    
+    }
+  
+  private Boolean evaluateSetSet( List lhsSet, List rhsSet, Navigator nav )
+    {
+    if( setIsEmpty( lhsSet ) || setIsEmpty( rhsSet ) )
+      {
+      return Boolean.FALSE;
+      }
+    
+    for( Iterator lhsIterator = lhsSet.iterator(); lhsIterator.hasNext(); )
+      {
+      Object lhs = lhsIterator.next();
+      
+      for( Iterator rhsIterator = rhsSet.iterator(); rhsIterator.hasNext(); )
+        {
+        Object rhs = rhsIterator.next();
+        
+        if( evaluateObjectObject( lhs, rhs, nav ) )
+          {
+          return Boolean.TRUE;
+          }
+        }
+      }
+    
+    return Boolean.FALSE;
+    }
+  
+  private boolean evaluateObjectObject( Object lhs, Object rhs, Navigator nav )
+    {
+    if( eitherIsBoolean( lhs, rhs ) )
+      {            
+      return evaluateObjectObject( BooleanFunction.evaluate( lhs, nav ),
+                                   BooleanFunction.evaluate( rhs, nav ) );
+      }
+    else if( eitherIsNumber( lhs, rhs ) )
+      {
+      return evaluateObjectObject( NumberFunction.evaluate( lhs,
+                                                            nav ),
+                                   NumberFunction.evaluate( rhs,
+                                                            nav ) );                                              
+      }
+    else
+      {
+      return evaluateObjectObject( StringFunction.evaluate( lhs,
+                                                            nav ),
+                                   StringFunction.evaluate( rhs,
+                                                            nav ) );
+      }
+    }
+  
+  protected abstract boolean evaluateObjectObject( Object lhs, Object rhs );
+  }
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/DefaultEqualsExpr.java b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultEqualsExpr.java
new file mode 100644
index 0000000..41fa5dd
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultEqualsExpr.java
@@ -0,0 +1,93 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/DefaultEqualsExpr.java,v 1.12 2006/06/03 20:52:26 elharo Exp $
+ * $Revision: 1.12 $
+ * $Date: 2006/06/03 20:52:26 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: DefaultEqualsExpr.java,v 1.12 2006/06/03 20:52:26 elharo Exp $
+ */
+
+
+
+package org.jaxen.expr;
+
+import org.jaxen.function.NumberFunction;
+
+class DefaultEqualsExpr extends DefaultEqualityExpr {
+    
+    /**
+     * 
+     */
+    private static final long serialVersionUID = -8327599812627931648L;
+    
+  DefaultEqualsExpr( Expr lhs, Expr rhs )
+    {
+    super( lhs, rhs );
+    }
+
+  public String getOperator()
+    {
+    return "=";
+    }
+
+  public String toString()
+    {
+    return "[(DefaultEqualsExpr): " + getLHS() + ", " + getRHS() + "]";
+    }
+  
+  protected boolean evaluateObjectObject( Object lhs, Object rhs )
+    {
+    if( eitherIsNumber( lhs, rhs ) )
+      {
+      if( NumberFunction.isNaN( (Double) lhs ) || NumberFunction.isNaN( (Double) rhs ) )
+        {
+        return false;
+        }
+      }
+    
+    return lhs.equals( rhs );
+    }
+  
+    public void accept(Visitor visitor)
+    {
+        visitor.visit(this);
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/DefaultExpr.java b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultExpr.java
new file mode 100644
index 0000000..be9f6cb
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultExpr.java
@@ -0,0 +1,93 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/DefaultExpr.java,v 1.14 2006/02/05 21:47:40 elharo Exp $
+ * $Revision: 1.14 $
+ * $Date: 2006/02/05 21:47:40 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: DefaultExpr.java,v 1.14 2006/02/05 21:47:40 elharo Exp $
+ */
+
+
+
+package org.jaxen.expr;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.jaxen.util.SingleObjectIterator;
+import org.jaxen.util.SingletonList;
+
+/**
+ * @deprecated this class will become non-public in the future;
+ *     use the interface instead
+ */
+public abstract class DefaultExpr implements Expr
+{
+    public Expr simplify()
+    {
+        return this;
+    }
+
+    static public Iterator convertToIterator(Object obj)
+    {
+        if ( obj instanceof Iterator )
+        {
+            return (Iterator) obj;
+        }
+
+        if ( obj instanceof List )
+        {
+            return ((List)obj).iterator();
+        }
+
+        return new SingleObjectIterator( obj );
+    }
+
+    static public List convertToList(Object obj)
+    {
+        if ( obj instanceof List )
+        {
+            return (List) obj;
+        }
+
+        return new SingletonList(obj);
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/DefaultFilterExpr.java b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultFilterExpr.java
new file mode 100644
index 0000000..8239a5c
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultFilterExpr.java
@@ -0,0 +1,183 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/DefaultFilterExpr.java,v 1.18 2006/06/03 20:52:26 elharo Exp $
+ * $Revision: 1.18 $
+ * $Date: 2006/06/03 20:52:26 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: DefaultFilterExpr.java,v 1.18 2006/06/03 20:52:26 elharo Exp $
+ */
+
+
+
+package org.jaxen.expr;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.jaxen.Context;
+import org.jaxen.JaxenException;
+
+/**
+ * @deprecated this class will become non-public in the future;
+ *     use the interface instead
+ */
+public class DefaultFilterExpr extends DefaultExpr implements FilterExpr, Predicated
+{
+    /**
+     * 
+     */
+    private static final long serialVersionUID = -549640659288005735L;
+    private Expr expr;
+    private PredicateSet predicates;
+
+    public DefaultFilterExpr(PredicateSet predicateSet)
+    {
+        this.predicates = predicateSet;
+    }
+
+    public DefaultFilterExpr(Expr expr, PredicateSet predicateSet)
+    {
+        this.expr       = expr;
+        this.predicates = predicateSet;
+    }
+
+    public void addPredicate(Predicate predicate)
+    {
+        this.predicates.addPredicate( predicate );
+    }
+
+    public List getPredicates()
+    {
+        return this.predicates.getPredicates();
+    }
+
+    public PredicateSet getPredicateSet()
+    {
+        return this.predicates;
+    }
+
+    public Expr getExpr()
+    {
+        return this.expr;
+    }
+
+    public String toString()
+    {
+        return "[(DefaultFilterExpr): expr: " + expr + " predicates: " + predicates + " ]";
+    }
+
+    public String getText()
+    {
+        String text = "";
+        if ( this.expr != null )
+        {
+            text = this.expr.getText();
+        }
+        text += predicates.getText();
+        return text;
+    }
+
+    public Expr simplify()
+    {
+        this.predicates.simplify();
+
+        if ( this.expr != null ) 
+        {
+            this.expr = this.expr.simplify();
+        }
+
+        if ( this.predicates.getPredicates().size() == 0 )
+        {
+            return getExpr();
+        }
+
+        return this;
+    }
+
+    /** Returns true if the current filter matches at least one of the context nodes
+     */
+    public boolean asBoolean(Context context) throws JaxenException 
+    {
+        Object results = null;
+        if ( expr != null ) 
+        {
+            results = expr.evaluate( context );
+        }
+        else
+        {
+            List nodeSet = context.getNodeSet();
+            ArrayList list = new ArrayList(nodeSet.size());
+            list.addAll( nodeSet );
+            results = list;
+        }
+        
+        if ( results instanceof Boolean ) 
+        {
+            Boolean b = (Boolean) results;
+            return b.booleanValue();
+        }
+        if ( results instanceof List )
+        {
+            return getPredicateSet().evaluateAsBoolean( 
+                (List) results, context.getContextSupport() 
+            );
+        }
+        
+        return false;
+    }
+    
+    public Object evaluate(Context context) throws JaxenException
+    {
+        Object results = getExpr().evaluate( context );
+        
+        if ( results instanceof List )
+        {
+            List newresults = getPredicateSet().evaluatePredicates( (List) results,
+                                    context.getContextSupport() );
+        results = newresults;
+        }
+
+        return results;
+    }
+    public void accept(Visitor visitor)
+    {
+        visitor.visit(this);
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/DefaultFunctionCallExpr.java b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultFunctionCallExpr.java
new file mode 100644
index 0000000..09dc863
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultFunctionCallExpr.java
@@ -0,0 +1,203 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/DefaultFunctionCallExpr.java,v 1.16 2006/06/03 20:52:26 elharo Exp $
+ * $Revision: 1.16 $
+ * $Date: 2006/06/03 20:52:26 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2004 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Jaxen Project and was originally
+ * created by bob mcwhirter <bob at werken.com> and
+ * James Strachan <jstrachan at apache.org>.  For more information on the
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ *
+ * $Id: DefaultFunctionCallExpr.java,v 1.16 2006/06/03 20:52:26 elharo Exp $
+ */
+
+package org.jaxen.expr;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.jaxen.Context;
+import org.jaxen.Function;
+import org.jaxen.JaxenException;
+
+/**
+ * @deprecated this class will become non-public in the future;
+ *     use the interface instead
+ */
+public class DefaultFunctionCallExpr extends DefaultExpr implements FunctionCallExpr
+{
+    /**
+     * 
+     */
+    private static final long serialVersionUID = -4747789292572193708L;
+    private String prefix;
+    private String functionName;
+    private List parameters;
+
+    public DefaultFunctionCallExpr(String prefix, String functionName)
+    {
+        this.prefix = prefix;
+        this.functionName = functionName;
+        this.parameters = new ArrayList();
+    }
+
+    public void addParameter(Expr parameter)
+    {
+        this.parameters.add(parameter);
+    }
+
+
+    public List getParameters()
+    {
+        return this.parameters;
+    }
+
+    public String getPrefix()
+    {
+        return this.prefix;
+    }
+
+    public String getFunctionName()
+    {
+        return this.functionName;
+    }
+
+
+    public String getText()
+    {
+        StringBuffer buf = new StringBuffer();
+        String prefix = getPrefix();
+
+        if (prefix != null &&
+                prefix.length() > 0)
+        {
+            buf.append(prefix);
+            buf.append(":");
+        }
+
+        buf.append(getFunctionName());
+        buf.append("(");
+
+        Iterator paramIter = getParameters().iterator();
+
+        while (paramIter.hasNext()) {
+            Expr eachParam = (Expr) paramIter.next();
+
+            buf.append(eachParam.getText());
+
+            if (paramIter.hasNext())
+            {
+                buf.append(", ");
+            }
+        }
+
+        buf.append(")");
+
+        return buf.toString();
+    }
+
+    public Expr simplify()
+    {
+        List paramExprs = getParameters();
+        int paramSize = paramExprs.size();
+
+        List newParams = new ArrayList(paramSize);
+
+        for (int i = 0; i < paramSize; ++i)
+        {
+            Expr eachParam = (Expr) paramExprs.get(i);
+
+            newParams.add(eachParam.simplify());
+        }
+
+        this.parameters = newParams;
+
+        return this;
+    }
+
+
+    public String toString()
+    {
+        String prefix = getPrefix();
+
+        if (prefix == null)
+        {
+            return "[(DefaultFunctionCallExpr): " + getFunctionName() + "(" + getParameters() + ") ]";
+        }
+
+        return "[(DefaultFunctionCallExpr): " + getPrefix() + ":" + getFunctionName() + "(" + getParameters() + ") ]";
+    }
+
+    public Object evaluate(Context context) throws JaxenException
+    {
+        String namespaceURI =
+                context.translateNamespacePrefixToUri(getPrefix());
+
+        Function func = context.getFunction(namespaceURI,
+                getPrefix(),
+                getFunctionName());
+        List paramValues = evaluateParams(context);
+
+        return func.call(context, paramValues);
+    }
+
+    public List evaluateParams(Context context) throws JaxenException
+    {
+        List paramExprs = getParameters();
+        int paramSize = paramExprs.size();
+
+        List paramValues = new ArrayList(paramSize);
+
+        for (int i = 0; i < paramSize; ++i)
+        {
+            Expr eachParam = (Expr) paramExprs.get(i);
+
+            Object eachValue = eachParam.evaluate(context);
+
+            paramValues.add(eachValue);
+        }
+        return paramValues;
+    }
+
+    public void accept(Visitor visitor)
+    {
+        visitor.visit(this);
+    }
+}
+
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/DefaultGreaterThanEqualExpr.java b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultGreaterThanEqualExpr.java
new file mode 100644
index 0000000..4b7e929
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultGreaterThanEqualExpr.java
@@ -0,0 +1,74 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/DefaultGreaterThanEqualExpr.java,v 1.13 2006/06/03 20:52:26 elharo Exp $
+ * $Revision: 1.13 $
+ * $Date: 2006/06/03 20:52:26 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: DefaultGreaterThanEqualExpr.java,v 1.13 2006/06/03 20:52:26 elharo Exp $
+ */
+
+package org.jaxen.expr;
+
+class DefaultGreaterThanEqualExpr extends DefaultRelationalExpr
+  {
+  /**
+     * 
+     */
+    private static final long serialVersionUID = -7848747981787197470L;
+DefaultGreaterThanEqualExpr( Expr lhs, Expr rhs )
+    {
+    super( lhs, rhs );
+    }
+
+  public String getOperator()
+    {
+    return ">=";
+    }
+
+  protected boolean evaluateDoubleDouble( Double lhs, Double rhs )
+    {
+    return lhs.compareTo( rhs ) >= 0;        
+    }
+    public void accept(Visitor visitor)
+    {
+        visitor.visit(this);
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/DefaultGreaterThanExpr.java b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultGreaterThanExpr.java
new file mode 100644
index 0000000..f8a8aed
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultGreaterThanExpr.java
@@ -0,0 +1,76 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/DefaultGreaterThanExpr.java,v 1.13 2006/06/03 20:52:26 elharo Exp $
+ * $Revision: 1.13 $
+ * $Date: 2006/06/03 20:52:26 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: DefaultGreaterThanExpr.java,v 1.13 2006/06/03 20:52:26 elharo Exp $
+ */
+
+package org.jaxen.expr;
+
+class DefaultGreaterThanExpr extends DefaultRelationalExpr
+  {
+  /**
+     * 
+     */
+    private static final long serialVersionUID = 6379252220540222867L;
+
+DefaultGreaterThanExpr( Expr lhs, Expr rhs )
+    {
+    super( lhs, rhs );
+    }
+
+  public String getOperator()
+    {
+    return ">";
+    }
+
+  protected boolean evaluateDoubleDouble( Double lhs, Double rhs )
+    {
+    return lhs.compareTo( rhs ) > 0;        
+    }
+    
+    public void accept(Visitor visitor)
+    {
+        visitor.visit(this);
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/DefaultLessThanEqualExpr.java b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultLessThanEqualExpr.java
new file mode 100644
index 0000000..a09d70e
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultLessThanEqualExpr.java
@@ -0,0 +1,75 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/DefaultLessThanEqualExpr.java,v 1.13 2006/06/03 20:52:26 elharo Exp $
+ * $Revision: 1.13 $
+ * $Date: 2006/06/03 20:52:26 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: DefaultLessThanEqualExpr.java,v 1.13 2006/06/03 20:52:26 elharo Exp $
+ */
+
+package org.jaxen.expr;
+
+class DefaultLessThanEqualExpr extends DefaultRelationalExpr
+  {
+  /**
+     * 
+     */
+    private static final long serialVersionUID = 7980276649555334242L;
+DefaultLessThanEqualExpr( Expr lhs, Expr rhs )
+    {
+    super( lhs, rhs );
+    }
+
+  public String getOperator()
+    {
+    return "<=";
+    }
+
+  protected boolean evaluateDoubleDouble( Double lhs, Double rhs )
+    {
+    return lhs.compareTo( rhs ) <= 0;        
+    }
+    public void accept(Visitor visitor)
+    {
+        visitor.visit(this);
+    }
+
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/DefaultLessThanExpr.java b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultLessThanExpr.java
new file mode 100644
index 0000000..b3b25b0
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultLessThanExpr.java
@@ -0,0 +1,74 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/DefaultLessThanExpr.java,v 1.14 2006/06/03 20:52:26 elharo Exp $
+ * $Revision: 1.14 $
+ * $Date: 2006/06/03 20:52:26 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: DefaultLessThanExpr.java,v 1.14 2006/06/03 20:52:26 elharo Exp $
+ */
+
+package org.jaxen.expr;
+
+class DefaultLessThanExpr extends DefaultRelationalExpr
+  {
+  /**
+     * 
+     */
+    private static final long serialVersionUID = 8423816025305001283L;
+DefaultLessThanExpr( Expr lhs, Expr rhs )
+    {
+    super( lhs, rhs );
+    }
+
+  public String getOperator()
+    {
+    return "<";
+    }
+
+  protected boolean evaluateDoubleDouble( Double lhs, Double rhs )
+    {
+    return lhs.compareTo( rhs ) < 0;
+    }    
+    public void accept(Visitor visitor)
+    {
+        visitor.visit(this);
+    }  
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/DefaultLiteralExpr.java b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultLiteralExpr.java
new file mode 100644
index 0000000..4e09268
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultLiteralExpr.java
@@ -0,0 +1,91 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/DefaultLiteralExpr.java,v 1.11 2006/06/03 20:52:26 elharo Exp $
+ * $Revision: 1.11 $
+ * $Date: 2006/06/03 20:52:26 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: DefaultLiteralExpr.java,v 1.11 2006/06/03 20:52:26 elharo Exp $
+ */
+
+
+
+package org.jaxen.expr;
+
+import org.jaxen.Context;
+
+class DefaultLiteralExpr extends DefaultExpr implements LiteralExpr
+{
+    /**
+     * 
+     */
+    private static final long serialVersionUID = -953829179036273338L;
+    private String literal;
+
+    DefaultLiteralExpr(String literal)
+    {
+        this.literal = literal;
+    }
+
+    public String getLiteral()
+    {
+        return this.literal;
+    }
+
+    public String toString()
+    {
+        return "[(DefaultLiteralExpr): " + getLiteral() + "]";
+    }
+
+    public String getText()
+    {
+        return "\"" + getLiteral() + "\"";
+    }
+
+    public Object evaluate(Context context)
+    {
+        return getLiteral();
+    }
+    
+    public void accept(Visitor visitor)
+    {
+        visitor.visit(this);
+    }   
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/DefaultLocationPath.java b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultLocationPath.java
new file mode 100644
index 0000000..c0f9fab
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultLocationPath.java
@@ -0,0 +1,164 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/DefaultLocationPath.java,v 1.29 2006/02/05 21:47:40 elharo Exp $
+ * $Revision: 1.29 $
+ * $Date: 2006/02/05 21:47:40 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Jaxen Project and was originally
+ * created by bob mcwhirter <bob at werken.com> and
+ * James Strachan <jstrachan at apache.org>.  For more information on the
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ *
+ * $Id: DefaultLocationPath.java,v 1.29 2006/02/05 21:47:40 elharo Exp $
+ */
+package org.jaxen.expr;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.jaxen.Context;
+import org.jaxen.ContextSupport;
+import org.jaxen.JaxenException;
+
+abstract class DefaultLocationPath extends DefaultExpr implements LocationPath
+{
+    private List steps;
+    
+    /**
+     * Create a new empty location path.
+     */
+    DefaultLocationPath()
+    {
+        this.steps = new LinkedList();
+    }
+
+    public void addStep(Step step)
+    {
+        getSteps().add(step);
+    }
+
+    public List getSteps()
+    {
+        return this.steps;
+    }
+
+    public Expr simplify()
+    {
+        Iterator stepIter = getSteps().iterator();
+        Step eachStep = null;
+        while (stepIter.hasNext())
+        {
+            eachStep = (Step) stepIter.next();
+            eachStep.simplify();
+        }
+        return this;
+    }
+
+    public String getText()
+    {
+        StringBuffer buf = new StringBuffer();
+        Iterator stepIter = getSteps().iterator();
+        while (stepIter.hasNext())
+        {
+            buf.append(((Step) stepIter.next()).getText());
+            if (stepIter.hasNext())
+            {
+                buf.append("/");
+            }
+        }
+        return buf.toString();
+    }
+
+    public String toString()
+    {
+        StringBuffer buf = new StringBuffer();
+        Iterator stepIter = getSteps().iterator();
+        while (stepIter.hasNext())
+        {
+            buf.append(stepIter.next().toString());
+            if (stepIter.hasNext())
+            {
+                buf.append("/");
+            }
+        }
+        return buf.toString();
+    }
+
+    public boolean isAbsolute()
+    {
+        return false;
+    }
+
+    public Object evaluate(Context context) throws JaxenException
+    {
+        List nodeSet = context.getNodeSet();
+        List contextNodeSet = new ArrayList(nodeSet);
+        ContextSupport support = context.getContextSupport();
+        Context stepContext = new Context(support);
+        Iterator stepIter = getSteps().iterator();
+        while ( stepIter.hasNext() )
+        {
+            Step eachStep = (Step) stepIter.next();
+            stepContext.setNodeSet(contextNodeSet);
+            contextNodeSet = eachStep.evaluate(stepContext);
+            // now we need to reverse the list if this is a reverse axis
+            if (isReverseAxis(eachStep)) {
+                Collections.reverse(contextNodeSet);
+            }
+        }
+        
+        if (getSteps().size() > 1) {
+            Collections.sort(contextNodeSet, new NodeComparator(support.getNavigator()));
+        }
+        
+        return contextNodeSet;
+    }
+
+    private boolean isReverseAxis(Step step) {
+
+        int axis = step.getAxis();
+        return axis == org.jaxen.saxpath.Axis.PRECEDING
+          || axis == org.jaxen.saxpath.Axis.PRECEDING_SIBLING
+          || axis == org.jaxen.saxpath.Axis.ANCESTOR
+          || axis == org.jaxen.saxpath.Axis.ANCESTOR_OR_SELF;
+    }
+
+}
+
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/DefaultLogicalExpr.java b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultLogicalExpr.java
new file mode 100644
index 0000000..0a805f6
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultLogicalExpr.java
@@ -0,0 +1,60 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/DefaultLogicalExpr.java,v 1.8 2006/02/05 21:47:40 elharo Exp $
+ * $Revision: 1.8 $
+ * $Date: 2006/02/05 21:47:40 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: DefaultLogicalExpr.java,v 1.8 2006/02/05 21:47:40 elharo Exp $
+ */
+
+
+
+package org.jaxen.expr;
+
+abstract class DefaultLogicalExpr extends DefaultTruthExpr implements LogicalExpr
+{
+    DefaultLogicalExpr(Expr lhs,
+                              Expr rhs)
+    {
+        super( lhs,
+               rhs );
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/DefaultMinusExpr.java b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultMinusExpr.java
new file mode 100644
index 0000000..88ba07b
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultMinusExpr.java
@@ -0,0 +1,90 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/DefaultMinusExpr.java,v 1.13 2006/06/03 20:52:26 elharo Exp $
+ * $Revision: 1.13 $
+ * $Date: 2006/06/03 20:52:26 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Jaxen Project and was originally
+ * created by bob mcwhirter <bob at werken.com> and
+ * James Strachan <jstrachan at apache.org>.  For more information on the
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ *
+ * $Id: DefaultMinusExpr.java,v 1.13 2006/06/03 20:52:26 elharo Exp $
+ */
+
+
+package org.jaxen.expr;
+
+import org.jaxen.Context;
+import org.jaxen.JaxenException;
+import org.jaxen.function.NumberFunction;
+
+class DefaultMinusExpr extends DefaultAdditiveExpr
+{
+    /**
+     * 
+     */
+    private static final long serialVersionUID = 6468563688098527800L;
+
+    DefaultMinusExpr(Expr lhs,
+                            Expr rhs)
+    {
+        super( lhs,
+               rhs );
+    }
+
+    public String getOperator()
+    {
+        return "-";
+    }
+
+    public Object evaluate(Context context) throws JaxenException
+    {
+        Number lhsValue = NumberFunction.evaluate( getLHS().evaluate( context ),
+                                                   context.getNavigator() );
+        Number rhsValue = NumberFunction.evaluate( getRHS().evaluate( context ),
+                                                   context.getNavigator() );
+
+        double result = lhsValue.doubleValue() - rhsValue.doubleValue();
+        return new Double( result );
+    }
+
+    public void accept(Visitor visitor)
+    {
+        visitor.visit(this);
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/DefaultModExpr.java b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultModExpr.java
new file mode 100644
index 0000000..94f6284
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultModExpr.java
@@ -0,0 +1,88 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/DefaultModExpr.java,v 1.14 2006/06/03 20:52:26 elharo Exp $
+ * $Revision: 1.14 $
+ * $Date: 2006/06/03 20:52:26 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Jaxen Project and was originally
+ * created by bob mcwhirter <bob at werken.com> and
+ * James Strachan <jstrachan at apache.org>.  For more information on the
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ *
+ * $Id: DefaultModExpr.java,v 1.14 2006/06/03 20:52:26 elharo Exp $
+ */
+package org.jaxen.expr;
+
+import org.jaxen.Context;
+import org.jaxen.JaxenException;
+import org.jaxen.function.NumberFunction;
+
+class DefaultModExpr extends DefaultMultiplicativeExpr
+{
+    /**
+     * 
+     */
+    private static final long serialVersionUID = -5554964716492040687L;
+
+    DefaultModExpr( Expr lhs,
+                           Expr rhs )
+    {
+        super( lhs,
+               rhs );
+    }
+
+    public String getOperator()
+    {
+        return "mod";
+    }
+
+    public Object evaluate( Context context ) throws JaxenException
+    {
+        Number lhsValue = NumberFunction.evaluate( getLHS().evaluate( context ),
+                                                   context.getNavigator() );
+        Number rhsValue = NumberFunction.evaluate( getRHS().evaluate( context ),
+                                                   context.getNavigator() );
+
+        double result = lhsValue.doubleValue() % rhsValue.doubleValue();
+        return new Double( result );
+    }
+
+    public void accept( Visitor visitor )
+    {
+        visitor.visit( this );
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/DefaultMultiplicativeExpr.java b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultMultiplicativeExpr.java
new file mode 100644
index 0000000..dc49d83
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultMultiplicativeExpr.java
@@ -0,0 +1,66 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/DefaultMultiplicativeExpr.java,v 1.9 2006/02/05 21:47:40 elharo Exp $
+ * $Revision: 1.9 $
+ * $Date: 2006/02/05 21:47:40 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: DefaultMultiplicativeExpr.java,v 1.9 2006/02/05 21:47:40 elharo Exp $
+ */
+
+
+
+package org.jaxen.expr;
+
+abstract class DefaultMultiplicativeExpr extends DefaultArithExpr 
+    implements MultiplicativeExpr
+{
+    DefaultMultiplicativeExpr(Expr lhs,
+                                     Expr rhs)
+    {
+        super( lhs,
+               rhs );
+    }
+
+    public String toString()
+    {
+        return "[(DefaultMultiplicativeExpr): " + getLHS() + ", " + getRHS() + "]";
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/DefaultMultiplyExpr.java b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultMultiplyExpr.java
new file mode 100644
index 0000000..7c49858
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultMultiplyExpr.java
@@ -0,0 +1,89 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/DefaultMultiplyExpr.java,v 1.13 2006/06/03 20:52:26 elharo Exp $
+ * $Revision: 1.13 $
+ * $Date: 2006/06/03 20:52:26 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Jaxen Project and was originally
+ * created by bob mcwhirter <bob at werken.com> and
+ * James Strachan <jstrachan at apache.org>.  For more information on the
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ *
+ * $Id: DefaultMultiplyExpr.java,v 1.13 2006/06/03 20:52:26 elharo Exp $
+ */
+package org.jaxen.expr;
+
+import org.jaxen.Context;
+import org.jaxen.JaxenException;
+import org.jaxen.function.NumberFunction;
+
+class DefaultMultiplyExpr extends DefaultMultiplicativeExpr
+{
+    /**
+     * 
+     */
+    private static final long serialVersionUID = 2760053878102260365L;
+
+    DefaultMultiplyExpr( Expr lhs,
+                                Expr rhs )
+    {
+        super( lhs,
+               rhs );
+    }
+
+    public String getOperator()
+    {
+        return "*";
+    }
+
+    public Object evaluate( Context context ) throws JaxenException
+    {
+        Number lhsValue = NumberFunction.evaluate( getLHS().evaluate( context ),
+                                                   context.getNavigator() );
+        Number rhsValue = NumberFunction.evaluate( getRHS().evaluate( context ),
+                                                   context.getNavigator() );
+
+        double result = lhsValue.doubleValue() * rhsValue.doubleValue();
+
+        return new Double( result );
+    }
+
+    public void accept( Visitor visitor )
+    {
+        visitor.visit( this );
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/DefaultNameStep.java b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultNameStep.java
new file mode 100644
index 0000000..d54f721
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultNameStep.java
@@ -0,0 +1,413 @@
+/*
+ $Id: DefaultNameStep.java,v 1.50 2006/10/06 13:11:45 elharo Exp $
+
+ Copyright 2003 The Werken Company. All Rights Reserved.
+ 
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+  * Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+
+  * Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+
+  * Neither the name of the Jaxen Project nor the names of its
+    contributors may be used to endorse or promote products derived 
+    from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ */
+package org.jaxen.expr;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+import org.jaxen.Context;
+import org.jaxen.ContextSupport;
+import org.jaxen.JaxenException;
+import org.jaxen.UnresolvableException;
+import org.jaxen.Navigator;
+import org.jaxen.expr.iter.IterableAxis;
+import org.jaxen.saxpath.Axis;
+
+/** 
+ * Expression object that represents any flavor
+ * of name-test steps within an XPath.
+ * <p>
+ * This includes simple steps, such as "foo",
+ * non-default-axis steps, such as "following-sibling::foo"
+ * or "@foo", and namespace-aware steps, such
+ * as "foo:bar".
+ *
+ * @author bob mcwhirter (bob at werken.com)
+ * @author Stephen Colebourne
+ * @deprecated this class will become non-public in the future;
+ *     use the interface instead
+ */
+public class DefaultNameStep extends DefaultStep implements NameStep {
+    
+    /**
+     * 
+     */
+    private static final long serialVersionUID = 428414912247718390L;
+
+    /** 
+     * Our prefix, bound through the current Context.
+     * The empty-string ("") if no prefix was specified.
+     * Decidedly NOT-NULL, due to SAXPath constraints.
+     * This is the 'foo' in 'foo:bar'.
+     */
+    private String prefix;
+
+    /**
+     * Our local-name.
+     * This is the 'bar' in 'foo:bar'.
+     */
+    private String localName;
+
+    /** Quick flag denoting if the local name was '*' */
+    private boolean matchesAnyName;
+
+    /** Quick flag denoting if we have a namespace prefix **/
+    private boolean hasPrefix;
+
+    /**
+     * Constructor.
+     * 
+     * @param axis  the axis to work through
+     * @param prefix  the name prefix
+     * @param localName  the local name
+     * @param predicateSet  the set of predicates
+     */    
+    public DefaultNameStep(IterableAxis axis,
+                           String prefix,
+                           String localName,
+                           PredicateSet predicateSet) {
+        super(axis, predicateSet);
+
+        this.prefix = prefix;
+        this.localName = localName;
+        this.matchesAnyName = "*".equals(localName);
+        this.hasPrefix = (this.prefix != null && this.prefix.length() > 0);
+    }
+
+    /**
+     * Gets the namespace prefix.
+     * 
+     * @return the prefix
+     */
+    public String getPrefix() {
+        return this.prefix;
+    }
+
+    /**
+     * Gets the local name.
+     * 
+     * @return the local name
+     */
+    public String getLocalName() {
+        return this.localName;
+    }
+
+    /**
+     * Does this step match any name? (i.e. Is it '*'?)
+     * 
+     * @return true if it matches any name
+     */
+    public boolean isMatchesAnyName() {
+        return matchesAnyName;
+    }
+
+    /**
+     * Gets the step as a fully defined XPath.
+     * 
+     * @return the full XPath for this step
+     */
+    public String getText() {
+        StringBuffer buf = new StringBuffer(64);
+        buf.append(getAxisName()).append("::");
+        if (getPrefix() != null && getPrefix().length() > 0) {
+            buf.append(getPrefix()).append(':');
+        }
+        return buf.append(getLocalName()).append(super.getText()).toString();
+    }
+
+    /**
+     * Evaluate the context node set to find the new node set.
+     * <p>
+     * This method overrides the version in <code>DefaultStep</code> for performance.
+     */
+    public List evaluate(Context context) throws JaxenException {
+
+        List contextNodeSet  = context.getNodeSet();
+        int contextSize = contextNodeSet.size();
+        // optimize for context size 0
+        if (contextSize == 0) {
+            return Collections.EMPTY_LIST;
+        }
+        ContextSupport support = context.getContextSupport();
+        IterableAxis iterableAxis = getIterableAxis();
+        boolean namedAccess = (!matchesAnyName && iterableAxis.supportsNamedAccess(support));
+        
+        // optimize for context size 1 (common case, avoids lots of object creation)
+        if (contextSize == 1) {
+            Object contextNode = contextNodeSet.get(0);
+            if (namedAccess) {
+                // get the iterator over the nodes and check it
+                String uri = null;
+                if (hasPrefix) {
+                    uri = support.translateNamespacePrefixToUri(prefix);
+                    if (uri == null) {
+                        throw new UnresolvableException("XPath expression uses unbound namespace prefix " + prefix);
+                    }
+                }
+                Iterator axisNodeIter = iterableAxis.namedAccessIterator(
+                                contextNode, support, localName, prefix, uri);
+                if (axisNodeIter == null || axisNodeIter.hasNext() == false) {
+                    return Collections.EMPTY_LIST;
+                }
+
+                // convert iterator to list for predicate test
+                // no need to filter as named access guarantees this
+                List newNodeSet = new ArrayList();
+                while (axisNodeIter.hasNext()) {
+                    newNodeSet.add(axisNodeIter.next());
+                }
+                
+                // evaluate the predicates
+                return getPredicateSet().evaluatePredicates(newNodeSet, support);
+                
+            } 
+            else {
+                // get the iterator over the nodes and check it
+                Iterator axisNodeIter = iterableAxis.iterator(contextNode, support);
+                if (axisNodeIter == null || axisNodeIter.hasNext() == false) {
+                    return Collections.EMPTY_LIST;
+                }
+
+                // run through iterator, filtering using matches()
+                // adding to list for predicate test
+                List newNodeSet = new ArrayList(contextSize);
+                while (axisNodeIter.hasNext()) {
+                    Object eachAxisNode = axisNodeIter.next();
+                    if (matches(eachAxisNode, support)) {
+                        newNodeSet.add(eachAxisNode);
+                    }
+                }
+                
+                // evaluate the predicates
+                return getPredicateSet().evaluatePredicates(newNodeSet, support);
+            }
+        }
+
+        // full case
+        IdentitySet unique = new IdentitySet();
+        List interimSet = new ArrayList(contextSize);
+        List newNodeSet = new ArrayList(contextSize);
+        
+        if (namedAccess) {
+            String uri = null;
+            if (hasPrefix) {
+                uri = support.translateNamespacePrefixToUri(prefix);
+                if (uri == null) {
+                    throw new UnresolvableException("XPath expression uses unbound namespace prefix " + prefix);
+                }
+            }
+            for (int i = 0; i < contextSize; ++i) {
+                Object eachContextNode = contextNodeSet.get(i);
+
+                Iterator axisNodeIter = iterableAxis.namedAccessIterator(
+                                eachContextNode, support, localName, prefix, uri);
+                if (axisNodeIter == null || axisNodeIter.hasNext() == false) {
+                    continue;
+                }
+
+                // ensure only one of each node in the result
+                while (axisNodeIter.hasNext()) {
+                    Object eachAxisNode = axisNodeIter.next();
+                    if (! unique.contains(eachAxisNode)) {
+                        unique.add(eachAxisNode);
+                        interimSet.add(eachAxisNode);
+                    }
+                }
+
+                // evaluate the predicates
+                newNodeSet.addAll(getPredicateSet().evaluatePredicates(interimSet, support));
+                interimSet.clear();
+            }
+            
+        } else {
+            for (int i = 0; i < contextSize; ++i) {
+                Object eachContextNode = contextNodeSet.get(i);
+
+                Iterator axisNodeIter = axisIterator(eachContextNode, support);
+                if (axisNodeIter == null || axisNodeIter.hasNext() == false) {
+                    continue;
+                }
+
+                /* See jaxen-106. Might be able to optimize this by doing
+                 * specific matching for individual axes. For instance on namespace axis
+                 * we should only get namespace nodes and on attribute axes we only get 
+                 * attribute nodes. Self and parent axes have single members.
+                 * Children, descendant, ancestor, and sibling axes never 
+                 * see any attributes or namespaces
+                 */
+                
+                // ensure only unique matching nodes in the result
+                while (axisNodeIter.hasNext()) {
+                    Object eachAxisNode = axisNodeIter.next();
+
+                    if (matches(eachAxisNode, support)) {
+                        if (! unique.contains(eachAxisNode)) {
+                            unique.add(eachAxisNode);
+                            interimSet.add(eachAxisNode);
+                        }
+                    }
+                }
+
+                // evaluate the predicates
+                newNodeSet.addAll(getPredicateSet().evaluatePredicates(interimSet, support));
+                interimSet.clear();
+            }
+        }
+        
+        return newNodeSet;
+    }
+    
+    /**
+     * Checks whether the node matches this step.
+     * 
+     * @param node  the node to check
+     * @param contextSupport  the context support
+     * @return true if matches
+     * @throws JaxenException 
+     */
+    public boolean matches(Object node, ContextSupport contextSupport) throws JaxenException {
+        
+        Navigator nav  = contextSupport.getNavigator();
+        String myUri = null;
+        String nodeName = null;
+        String nodeUri = null;
+
+        if (nav.isElement(node)) {
+            nodeName = nav.getElementName(node);
+            nodeUri = nav.getElementNamespaceUri(node);
+        } 
+        else if (nav.isText(node)) {
+            return false;
+        } 
+        else if (nav.isAttribute(node)) {
+            if (getAxis() != Axis.ATTRIBUTE) {
+                return false;
+            }
+            nodeName = nav.getAttributeName(node);
+            nodeUri = nav.getAttributeNamespaceUri(node);
+            
+        } 
+        else if (nav.isDocument(node)) {
+            return false;
+        } 
+        else if (nav.isNamespace(node)) {
+            if (getAxis() != Axis.NAMESPACE) {
+                // Only works for namespace::*
+                return false;
+            }
+            nodeName = nav.getNamespacePrefix(node);
+        } 
+        else {
+            return false;
+        }
+
+        if (hasPrefix) {
+            myUri = contextSupport.translateNamespacePrefixToUri(this.prefix);
+            if (myUri == null) {
+            	throw new UnresolvableException("Cannot resolve namespace prefix '"+this.prefix+"'");
+            }
+        } 
+        else if (matchesAnyName) {
+            return true;
+        }
+
+        // If we map to a non-empty namespace and the node does not
+        // or vice-versa, fail-fast.
+        if (hasNamespace(myUri) != hasNamespace(nodeUri)) {
+            return false;
+        }
+        
+        // To fail-fast, we check the equality of
+        // local-names first.  Shorter strings compare
+        // quicker.
+        if (matchesAnyName || nodeName.equals(getLocalName())) {
+            return matchesNamespaceURIs(myUri, nodeUri);
+        }
+
+        return false;
+    }
+
+    /**
+     * Checks whether the URI represents a namespace.
+     * 
+     * @param uri  the URI to check
+     * @return true if non-null and non-empty
+     */
+    private boolean hasNamespace(String uri) {
+        return (uri != null && uri.length() > 0);
+    }
+
+    /**
+     * Compares two namespace URIs, handling null.
+     * 
+     * @param uri1  the first URI
+     * @param uri2  the second URI
+     * @return true if equal, where null==""
+     */
+    protected boolean matchesNamespaceURIs(String uri1, String uri2) {
+        if (uri1 == uri2) {
+            return true;
+        }
+        if (uri1 == null) {
+            return (uri2.length() == 0);
+        }
+        if (uri2 == null) {
+            return (uri1.length() == 0);
+        }
+        return uri1.equals(uri2);
+    }
+
+    /**
+     * Visitor pattern for the step.
+     * 
+     * @param visitor  the visitor object
+     */
+    public void accept(Visitor visitor) {
+        visitor.visit(this);
+    }
+    
+    /**
+     * Returns a full information debugging string.
+     * 
+     * @return a debugging string
+     */
+    public String toString() {
+        String prefix = getPrefix();
+        String qName = "".equals(prefix) ? getLocalName() : getPrefix() + ":" + getLocalName();
+        return "[(DefaultNameStep): " +  qName +  "]";
+    }
+
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/DefaultNotEqualsExpr.java b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultNotEqualsExpr.java
new file mode 100644
index 0000000..79b5c45
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultNotEqualsExpr.java
@@ -0,0 +1,94 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/DefaultNotEqualsExpr.java,v 1.13 2006/06/03 20:52:26 elharo Exp $
+ * $Revision: 1.13 $
+ * $Date: 2006/06/03 20:52:26 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: DefaultNotEqualsExpr.java,v 1.13 2006/06/03 20:52:26 elharo Exp $
+ */
+
+
+
+package org.jaxen.expr;
+
+import org.jaxen.function.NumberFunction;
+
+class DefaultNotEqualsExpr extends DefaultEqualityExpr 
+  {
+  /**
+     * 
+     */
+    private static final long serialVersionUID = -8001267398136979152L;
+
+DefaultNotEqualsExpr( Expr lhs, Expr rhs )
+    {
+    super( lhs, rhs );
+    }
+
+  public String getOperator()
+    {
+    return "!=";
+    }
+
+  public String toString()
+    {
+    return "[(DefaultNotEqualsExpr): " + getLHS() + ", " + getRHS() + "]";
+    }
+  
+    protected boolean evaluateObjectObject( Object lhs, Object rhs )
+    {
+        if( eitherIsNumber( lhs, rhs ) )
+        {
+    
+            if( NumberFunction.isNaN( (Double) lhs ) || NumberFunction.isNaN( (Double) rhs ) )
+            {
+                return true;
+            }
+    
+        }
+        return !lhs.equals( rhs );
+    }
+
+    public void accept(Visitor visitor)
+    {
+        visitor.visit(this);
+    }   
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/DefaultNumberExpr.java b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultNumberExpr.java
new file mode 100644
index 0000000..e6897cc
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultNumberExpr.java
@@ -0,0 +1,92 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/DefaultNumberExpr.java,v 1.11 2006/06/03 20:52:26 elharo Exp $
+ * $Revision: 1.11 $
+ * $Date: 2006/06/03 20:52:26 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Jaxen Project and was originally
+ * created by bob mcwhirter <bob at werken.com> and
+ * James Strachan <jstrachan at apache.org>.  For more information on the
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ *
+ * $Id: DefaultNumberExpr.java,v 1.11 2006/06/03 20:52:26 elharo Exp $
+ */
+
+
+package org.jaxen.expr;
+
+import org.jaxen.Context;
+
+
+class DefaultNumberExpr extends DefaultExpr implements NumberExpr
+{
+    /**
+     * 
+     */
+    private static final long serialVersionUID = -6021898973386269611L;
+    private Number number;
+
+    DefaultNumberExpr( Number number )
+    {
+        this.number = number;
+    }
+
+    public Number getNumber()
+    {
+        return this.number;
+    }
+
+    public String toString()
+    {
+        return "[(DefaultNumberExpr): " + getNumber() + "]";
+    }
+
+    public String getText()
+    {
+        return getNumber().toString();
+    }
+
+    public Object evaluate( Context context )
+    {
+        return getNumber();
+    }
+
+    public void accept( Visitor visitor )
+    {
+        visitor.visit( this );
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/DefaultOrExpr.java b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultOrExpr.java
new file mode 100644
index 0000000..c21440f
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultOrExpr.java
@@ -0,0 +1,108 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/DefaultOrExpr.java,v 1.16 2006/06/03 20:52:26 elharo Exp $
+ * $Revision: 1.16 $
+ * $Date: 2006/06/03 20:52:26 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: DefaultOrExpr.java,v 1.16 2006/06/03 20:52:26 elharo Exp $
+ */
+
+
+
+package org.jaxen.expr;
+
+import org.jaxen.Context;
+import org.jaxen.JaxenException;
+import org.jaxen.Navigator;
+import org.jaxen.function.BooleanFunction;
+
+class DefaultOrExpr extends DefaultLogicalExpr 
+{
+    /**
+     * 
+     */
+    private static final long serialVersionUID = 4894552680753026730L;
+
+    DefaultOrExpr(Expr lhs,
+                         Expr rhs)
+    {
+        super( lhs,
+               rhs );
+    }
+
+    public String getOperator()
+    {
+        return "or";
+    }
+
+    public String toString()
+    {
+        return "[(DefaultOrExpr): " + getLHS() + ", " + getRHS() + "]";
+    }
+
+    public Object evaluate(Context context) throws JaxenException
+    {
+        Navigator nav = context.getNavigator();
+        Boolean lhsValue = BooleanFunction.evaluate( getLHS().evaluate( context ), nav );
+
+        if ( lhsValue.booleanValue() )
+        {
+            return Boolean.TRUE;
+        }
+
+        // Short circuits are required in XPath. "The right operand is not 
+        // evaluated if the left operand evaluates to true."
+        Boolean rhsValue = BooleanFunction.evaluate( getRHS().evaluate( context ), nav );
+
+        if ( rhsValue.booleanValue() )
+        {
+            return Boolean.TRUE;
+        }
+
+        return Boolean.FALSE;
+    }
+    
+    public void accept(Visitor visitor)
+    {
+        visitor.visit(this);
+    }
+    
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/DefaultPathExpr.java b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultPathExpr.java
new file mode 100644
index 0000000..0957bfb
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultPathExpr.java
@@ -0,0 +1,151 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/DefaultPathExpr.java,v 1.15 2006/10/03 16:24:32 elharo Exp $
+ * $Revision: 1.15 $
+ * $Date: 2006/10/03 16:24:32 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Jaxen Project and was originally
+ * created by bob mcwhirter <bob at werken.com> and
+ * James Strachan <jstrachan at apache.org>.  For more information on the
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ *
+ * $Id: DefaultPathExpr.java,v 1.15 2006/10/03 16:24:32 elharo Exp $
+ */
+
+package org.jaxen.expr;
+
+
+import org.jaxen.Context;
+import org.jaxen.JaxenException;
+
+
+class DefaultPathExpr extends DefaultExpr implements PathExpr {
+
+    private static final long serialVersionUID = -6593934674727004281L;
+    private Expr filterExpr;
+    private LocationPath locationPath;
+
+    DefaultPathExpr(Expr filterExpr,
+                           LocationPath locationPath) {
+        this.filterExpr = filterExpr;
+        this.locationPath = locationPath;
+    }
+
+    public Expr getFilterExpr() {
+        return this.filterExpr;
+    }
+
+
+    public void setFilterExpr(Expr filterExpr) {
+        this.filterExpr = filterExpr;
+    }
+
+
+    public LocationPath getLocationPath() {
+        return this.locationPath;
+    }
+
+
+    public String toString() {
+        if (getLocationPath() != null) {
+            return "[(DefaultPathExpr): " + getFilterExpr() + ", " + getLocationPath() + "]";
+        }
+
+        return "[(DefaultPathExpr): " + getFilterExpr() + "]";
+    }
+
+
+    public String getText() {
+        StringBuffer buf = new StringBuffer();
+
+        if (getFilterExpr() != null) {
+            buf.append(getFilterExpr().getText());
+        }
+
+        if (getLocationPath() != null) {
+            if (!getLocationPath().getSteps().isEmpty()) buf.append("/");
+            buf.append(getLocationPath().getText());
+        }
+
+        return buf.toString();
+    }
+
+
+    public Expr simplify() {
+        if (getFilterExpr() != null) {
+            setFilterExpr(getFilterExpr().simplify());
+        }
+
+        if (getLocationPath() != null) {
+            getLocationPath().simplify();
+        }
+
+        if (getFilterExpr() == null && getLocationPath() == null) {
+            return null;
+        }
+
+
+        if (getLocationPath() == null) {
+            return getFilterExpr();
+        }
+
+        if (getFilterExpr() == null) {
+            return getLocationPath();
+        }
+
+        return this;
+    }
+
+    public Object evaluate(Context context) throws JaxenException {
+        Object results = null;
+        Context pathContext = null;
+        if (getFilterExpr() != null) {
+            results = getFilterExpr().evaluate(context);
+            pathContext = new Context(context.getContextSupport());
+            pathContext.setNodeSet(convertToList(results));
+        }
+        if (getLocationPath() != null) {
+            return getLocationPath().evaluate(pathContext);
+        }
+        return results;
+    }
+
+    public void accept(Visitor visitor) {
+        visitor.visit(this);
+    }
+}
+
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/DefaultPlusExpr.java b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultPlusExpr.java
new file mode 100644
index 0000000..d74ca44
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultPlusExpr.java
@@ -0,0 +1,88 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/DefaultPlusExpr.java,v 1.13 2006/06/03 20:52:26 elharo Exp $
+ * $Revision: 1.13 $
+ * $Date: 2006/06/03 20:52:26 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: DefaultPlusExpr.java,v 1.13 2006/06/03 20:52:26 elharo Exp $
+ */
+
+
+package org.jaxen.expr;
+
+import org.jaxen.Context;
+import org.jaxen.JaxenException;
+import org.jaxen.function.NumberFunction;
+
+class DefaultPlusExpr extends DefaultAdditiveExpr
+{
+    /**
+     * 
+     */
+    private static final long serialVersionUID = -1426954461146769374L;
+    DefaultPlusExpr(Expr lhs,
+                           Expr rhs)
+    {
+        super( lhs,
+               rhs );
+    }
+
+    public String getOperator()
+    {
+        return "+";
+    }
+
+    public Object evaluate(Context context) throws JaxenException
+    {
+        Number lhsValue = NumberFunction.evaluate( getLHS().evaluate( context ),
+                                                   context.getNavigator() );
+        Number rhsValue = NumberFunction.evaluate( getRHS().evaluate( context ),
+                                                   context.getNavigator() );
+
+        double result = lhsValue.doubleValue() + rhsValue.doubleValue();
+
+        return new Double( result );        
+    }
+    public void accept(Visitor visitor)
+    {
+        visitor.visit(this);
+    }   
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/DefaultPredicate.java b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultPredicate.java
new file mode 100644
index 0000000..b787621
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultPredicate.java
@@ -0,0 +1,101 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/DefaultPredicate.java,v 1.12 2006/06/03 20:52:26 elharo Exp $
+ * $Revision: 1.12 $
+ * $Date: 2006/06/03 20:52:26 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: DefaultPredicate.java,v 1.12 2006/06/03 20:52:26 elharo Exp $
+ */
+
+
+
+package org.jaxen.expr;
+
+import org.jaxen.Context;
+import org.jaxen.JaxenException;
+
+class DefaultPredicate implements Predicate
+{
+    /**
+     * 
+     */
+    private static final long serialVersionUID = -4140068594075364971L;
+    private Expr expr;
+
+    DefaultPredicate(Expr expr)
+    {
+        setExpr( expr );
+    }
+
+    public Expr getExpr()
+    {
+        return this.expr;
+    }
+
+    public void setExpr(Expr expr)
+    {
+        this.expr = expr;
+    }
+
+    public String getText()
+    {
+        return "[" + getExpr().getText() + "]";
+    }
+
+    public String toString()
+    {
+        return "[(DefaultPredicate): " + getExpr() + "]";
+    }
+
+    public void simplify()
+    {
+        setExpr( getExpr().simplify() );
+    }
+
+    public Object evaluate(Context context) throws JaxenException
+    {
+        return getExpr().evaluate( context );
+    }
+    public void accept(Visitor visitor)
+    {
+        visitor.visit(this);
+    }   
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/DefaultProcessingInstructionNodeStep.java b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultProcessingInstructionNodeStep.java
new file mode 100644
index 0000000..4687516
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultProcessingInstructionNodeStep.java
@@ -0,0 +1,111 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/DefaultProcessingInstructionNodeStep.java,v 1.16 2006/06/03 20:52:26 elharo Exp $
+ * $Revision: 1.16 $
+ * $Date: 2006/06/03 20:52:26 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: DefaultProcessingInstructionNodeStep.java,v 1.16 2006/06/03 20:52:26 elharo Exp $
+ */
+
+
+
+package org.jaxen.expr;
+
+import org.jaxen.ContextSupport;
+import org.jaxen.Navigator;
+import org.jaxen.expr.iter.IterableAxis;
+
+/**
+ * @deprecated this class will become non-public in the future;
+ *     use the interface instead
+ */
+public class DefaultProcessingInstructionNodeStep extends DefaultStep
+    implements ProcessingInstructionNodeStep
+{
+    /**
+     * 
+     */
+    private static final long serialVersionUID = -4825000697808126927L;
+    private String name;
+
+    public DefaultProcessingInstructionNodeStep(IterableAxis axis,
+                                                String name,
+                                                PredicateSet predicateSet)
+    {
+        super( axis, predicateSet );
+
+        this.name = name;
+    }
+
+    public String getName()
+    {
+        return this.name;
+    }
+
+    public boolean matches(Object node,
+                           ContextSupport support)
+    {
+        Navigator nav = support.getNavigator();
+
+        boolean isPi = nav.isProcessingInstruction( node );
+
+        if ( isPi )
+        {
+            String name = getName();
+
+            if ( name == null || name.length() == 0 )
+            {
+                return true;
+            }
+            else
+            {
+                return name.equals( nav.getProcessingInstructionTarget( node ) );
+            }
+        }
+
+        return false;
+    }
+    
+    public void accept(Visitor visitor)
+    {
+        visitor.visit(this);
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/DefaultRelationalExpr.java b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultRelationalExpr.java
new file mode 100644
index 0000000..a24dec6
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultRelationalExpr.java
@@ -0,0 +1,142 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/DefaultRelationalExpr.java,v 1.14 2006/02/05 21:47:40 elharo Exp $
+ * $Revision: 1.14 $
+ * $Date: 2006/02/05 21:47:40 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: DefaultRelationalExpr.java,v 1.14 2006/02/05 21:47:40 elharo Exp $
+ */
+
+
+
+package org.jaxen.expr;
+
+import java.util.Iterator;
+import java.util.List;
+import org.jaxen.Context;
+import org.jaxen.JaxenException;
+import org.jaxen.Navigator;
+import org.jaxen.function.NumberFunction;
+
+abstract class DefaultRelationalExpr extends DefaultTruthExpr implements RelationalExpr 
+  {
+  DefaultRelationalExpr( Expr lhs, Expr rhs )
+    {
+    super( lhs, rhs );
+    }
+  
+  public String toString()
+    {
+    return "[(DefaultRelationalExpr): " + getLHS() + ", " + getRHS() + "]";
+    }
+
+  public Object evaluate( Context context ) throws JaxenException
+    {
+    Object lhsValue = getLHS().evaluate( context );
+    Object rhsValue = getRHS().evaluate( context );
+    Navigator nav = context.getNavigator();
+
+    if( bothAreSets( lhsValue, rhsValue ) )
+      {
+      return evaluateSetSet( (List) lhsValue, (List) rhsValue, nav );
+      }
+
+    if( eitherIsSet( lhsValue, rhsValue ) )
+      {
+      if( isSet( lhsValue ) )
+        {        
+        return evaluateSetSet( (List) lhsValue, convertToList( rhsValue ), nav );              
+        }
+      else
+        {
+        return evaluateSetSet( convertToList( lhsValue ), (List) rhsValue, nav );              
+        }
+      }
+    
+    return evaluateObjectObject( lhsValue, rhsValue, nav ) ? Boolean.TRUE : Boolean.FALSE;
+    }
+
+  private Object evaluateSetSet( List lhsSet, List rhsSet, Navigator nav )
+    {
+    if( setIsEmpty( lhsSet ) || setIsEmpty( rhsSet ) ) // return false if either is null or empty
+      {
+      return Boolean.FALSE;
+      }    
+    
+    for( Iterator lhsIterator = lhsSet.iterator(); lhsIterator.hasNext(); )
+      {
+      Object lhs = lhsIterator.next();        
+      
+      for( Iterator rhsIterator = rhsSet.iterator(); rhsIterator.hasNext(); )
+        {
+        Object rhs = rhsIterator.next();
+        
+        if( evaluateObjectObject( lhs, rhs, nav ) )
+          {
+          return Boolean.TRUE;
+          }
+        }
+      }      
+    
+    return Boolean.FALSE;
+    }
+  
+  private boolean evaluateObjectObject( Object lhs, Object rhs, Navigator nav )
+    {
+    if( lhs == null || rhs == null )
+      {
+      return false;
+      }
+    
+    Double lhsNum = NumberFunction.evaluate( lhs, nav );
+    Double rhsNum = NumberFunction.evaluate( rhs, nav );      
+    
+    if( NumberFunction.isNaN( lhsNum ) || NumberFunction.isNaN( rhsNum ) )
+      {
+      return false;
+      }
+    
+    return evaluateDoubleDouble( lhsNum, rhsNum );
+    }
+  
+  protected abstract boolean evaluateDoubleDouble( Double lhs, Double rhs );    
+  }
+
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/DefaultRelativeLocationPath.java b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultRelativeLocationPath.java
new file mode 100644
index 0000000..b5ac271
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultRelativeLocationPath.java
@@ -0,0 +1,73 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/DefaultRelativeLocationPath.java,v 1.12 2006/06/03 20:52:26 elharo Exp $
+ * $Revision: 1.12 $
+ * $Date: 2006/06/03 20:52:26 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: DefaultRelativeLocationPath.java,v 1.12 2006/06/03 20:52:26 elharo Exp $
+ */
+
+
+
+package org.jaxen.expr;
+
+/**
+ * @deprecated this class will become non-public in the future;
+ *     use the interface instead
+ */
+public class DefaultRelativeLocationPath extends DefaultLocationPath 
+{
+
+    /**
+     * 
+     */
+    private static final long serialVersionUID = -1006862529366150615L;
+
+    public String toString()
+    {
+        return "[(DefaultRelativeLocationPath): " + super.toString() + "]";
+    }
+    
+    public void accept(Visitor visitor)
+    {
+        visitor.visit(this);
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/DefaultStep.java b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultStep.java
new file mode 100644
index 0000000..776dec8
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultStep.java
@@ -0,0 +1,171 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/DefaultStep.java,v 1.21 2006/02/05 21:47:40 elharo Exp $
+ * $Revision: 1.21 $
+ * $Date: 2006/02/05 21:47:40 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: DefaultStep.java,v 1.21 2006/02/05 21:47:40 elharo Exp $
+ */
+package org.jaxen.expr;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.jaxen.Context;
+import org.jaxen.ContextSupport;
+import org.jaxen.JaxenException;
+import org.jaxen.UnsupportedAxisException;
+import org.jaxen.expr.iter.IterableAxis;
+import org.jaxen.saxpath.Axis;
+
+/**
+ * @deprecated this class will become non-public in the future;
+ *     use the interface instead
+ */
+public abstract class DefaultStep implements Step
+{
+    private IterableAxis axis;
+    private PredicateSet predicates;
+
+    public DefaultStep(IterableAxis axis, PredicateSet predicates)
+    {
+        this.axis = axis;
+        this.predicates = predicates;
+    }
+
+    public void addPredicate(Predicate predicate)
+    {
+        this.predicates.addPredicate(predicate);
+    }
+
+    public List getPredicates()
+    {
+        return this.predicates.getPredicates();
+    }
+
+    public PredicateSet getPredicateSet()
+    {
+        return this.predicates;
+    }
+
+    public int getAxis()
+    {
+        return this.axis.value();
+    }
+
+    public IterableAxis getIterableAxis()
+    {
+        return this.axis;
+    }
+
+    public String getAxisName()
+    {
+        return Axis.lookup(getAxis());
+    }
+
+    public String getText()
+    {
+        return this.predicates.getText();
+    }
+
+    public String toString()
+    {
+        return getIterableAxis() + " " + super.toString();
+    }
+
+    public void simplify()
+    {
+        this.predicates.simplify();
+    }
+
+    public Iterator axisIterator(Object contextNode, ContextSupport support)
+        throws UnsupportedAxisException
+    {
+        return getIterableAxis().iterator(contextNode, support);
+    }
+
+    public List evaluate(final Context context) throws JaxenException
+    {
+        final List contextNodeSet  = context.getNodeSet();
+        final IdentitySet unique = new IdentitySet();
+        final int contextSize = contextNodeSet.size();
+
+        // ???? try linked lists instead?
+        // ???? initial size for these?
+        final ArrayList interimSet = new ArrayList();
+        final ArrayList newNodeSet = new ArrayList();
+        final ContextSupport support = context.getContextSupport();
+            
+        // ???? use iterator instead
+        for ( int i = 0 ; i < contextSize ; ++i )
+        {
+            Object eachContextNode = contextNodeSet.get( i );
+
+
+                /* See jaxen-106. Might be able to optimize this by doing
+                 * specific matching for individual axes. For instance on namespace axis
+                 * we should only get namespace nodes and on attribute axes we only get 
+                 * attribute nodes. Self and parent axes have single members.
+                 * Children, descendant, ancestor, and sibling axes never 
+                 * see any attributes or namespaces
+                 */
+            Iterator axisNodeIter = axis.iterator(eachContextNode, support);
+            while ( axisNodeIter.hasNext() )
+            {
+                Object eachAxisNode = axisNodeIter.next();
+                if ( ! unique.contains( eachAxisNode ) )
+                {
+                    if ( matches( eachAxisNode, support ) )
+                    {
+                        unique.add( eachAxisNode );
+                        interimSet.add( eachAxisNode );
+                    }
+                }
+            }
+            newNodeSet.addAll(getPredicateSet().evaluatePredicates(
+                              interimSet, support ));
+            interimSet.clear();
+        }
+        return newNodeSet;
+    }
+
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/DefaultTextNodeStep.java b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultTextNodeStep.java
new file mode 100644
index 0000000..3ecbad3
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultTextNodeStep.java
@@ -0,0 +1,89 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/DefaultTextNodeStep.java,v 1.13 2006/06/03 20:52:26 elharo Exp $
+ * $Revision: 1.13 $
+ * $Date: 2006/06/03 20:52:26 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: DefaultTextNodeStep.java,v 1.13 2006/06/03 20:52:26 elharo Exp $
+ */
+
+
+
+package org.jaxen.expr;
+
+import org.jaxen.ContextSupport;
+import org.jaxen.Navigator;
+import org.jaxen.expr.iter.IterableAxis;
+
+/**
+ * @deprecated this class will become non-public in the future;
+ *     use the interface instead
+ */
+public class DefaultTextNodeStep extends DefaultStep implements TextNodeStep
+{
+    /**
+     * 
+     */
+    private static final long serialVersionUID = -3821960984972022948L;
+
+    public DefaultTextNodeStep(IterableAxis axis, PredicateSet predicateSet )
+    {
+        super( axis, predicateSet );
+    }
+
+    public boolean matches(Object node,
+                           ContextSupport support)
+    {
+        Navigator nav = support.getNavigator();
+
+        return nav.isText( node );
+    }
+
+    public String getText()
+    {
+        return getAxisName() + "::text()" + super.getText();
+    }
+    
+    public void accept(Visitor visitor)
+    {
+        visitor.visit(this);
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/DefaultTruthExpr.java b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultTruthExpr.java
new file mode 100644
index 0000000..cbe7043
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultTruthExpr.java
@@ -0,0 +1,119 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/DefaultTruthExpr.java,v 1.10 2006/02/05 21:47:40 elharo Exp $
+ * $Revision: 1.10 $
+ * $Date: 2006/02/05 21:47:40 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: DefaultTruthExpr.java,v 1.10 2006/02/05 21:47:40 elharo Exp $
+ */
+
+
+
+package org.jaxen.expr;
+
+import java.util.List;
+
+abstract class DefaultTruthExpr extends DefaultBinaryExpr 
+{
+    DefaultTruthExpr(Expr lhs,
+                            Expr rhs)
+    {
+        super( lhs,
+               rhs );
+    }
+
+    public String toString()
+    {
+        return "[(DefaultTruthExpr): " + getLHS() + ", " + getRHS() + "]";
+    }
+
+    protected boolean bothAreSets(Object lhs,
+                                  Object rhs)
+    {
+        return ( lhs instanceof List
+                 &&
+                 rhs instanceof List );
+    }
+
+    protected boolean eitherIsSet(Object lhs,
+                                  Object rhs)
+    {
+        return ( lhs instanceof List
+                 ||
+                 rhs instanceof List );
+    }
+
+    protected boolean isSet(Object obj)
+    {
+        return ( obj instanceof List );
+    }
+    
+    protected boolean setIsEmpty( List set )
+      {
+      return (set == null || set.size() == 0);
+      }
+
+    protected boolean eitherIsBoolean(Object lhs,
+                                      Object rhs)
+    {
+        return ( lhs instanceof Boolean
+                 ||
+                 rhs instanceof Boolean );
+    }
+
+    protected boolean bothAreBoolean(Object lhs,
+                                     Object rhs)
+    {
+        return ( lhs instanceof Boolean
+                 &&
+                 rhs instanceof Boolean );
+    }
+
+    protected boolean eitherIsNumber(Object lhs,
+                                     Object rhs)
+    {
+        return ( lhs instanceof Number
+                 ||
+                 rhs instanceof Number );
+    } 
+
+}
+
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/DefaultUnaryExpr.java b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultUnaryExpr.java
new file mode 100644
index 0000000..b1416ef
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultUnaryExpr.java
@@ -0,0 +1,102 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/DefaultUnaryExpr.java,v 1.15 2006/06/03 20:52:26 elharo Exp $
+ * $Revision: 1.15 $
+ * $Date: 2006/06/03 20:52:26 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: DefaultUnaryExpr.java,v 1.15 2006/06/03 20:52:26 elharo Exp $
+ */
+
+
+
+package org.jaxen.expr;
+
+import org.jaxen.Context;
+import org.jaxen.JaxenException;
+import org.jaxen.function.NumberFunction;
+
+class DefaultUnaryExpr extends DefaultExpr implements UnaryExpr
+{
+    /**
+     * 
+     */
+    private static final long serialVersionUID = 2303714238683092334L;
+    private Expr expr;
+
+    DefaultUnaryExpr(Expr expr)
+    {
+        this.expr = expr;
+    }
+
+    public Expr getExpr()
+    {
+        return this.expr;
+    }
+
+    public String toString()
+    {
+        return "[(DefaultUnaryExpr): " + getExpr() + "]";
+    }
+
+    public String getText()
+    {
+        return "-(" + getExpr().getText() + ")";
+    }
+
+    public Expr simplify()
+    {
+        expr = expr.simplify();
+
+        return this;
+    }
+
+    public Object evaluate(Context context) throws JaxenException
+    {
+        Number number = NumberFunction.evaluate( getExpr().evaluate( context ),
+                                                 context.getNavigator() );
+
+        return new Double( number.doubleValue() * -1 );
+    }
+    public void accept(Visitor visitor)
+    {
+        visitor.visit(this);
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/DefaultUnionExpr.java b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultUnionExpr.java
new file mode 100644
index 0000000..2c1f340
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultUnionExpr.java
@@ -0,0 +1,131 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/DefaultUnionExpr.java,v 1.16 2006/06/03 20:52:26 elharo Exp $
+ * $Revision: 1.16 $
+ * $Date: 2006/06/03 20:52:26 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: DefaultUnionExpr.java,v 1.16 2006/06/03 20:52:26 elharo Exp $
+ */
+
+
+
+package org.jaxen.expr;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import org.jaxen.Context;
+import org.jaxen.JaxenException;
+import org.jaxen.XPathSyntaxException;
+
+/**
+ * @deprecated this class will become non-public in the future;
+ *     use the interface instead
+ */
+public class DefaultUnionExpr extends DefaultBinaryExpr implements UnionExpr
+{
+    /**
+     * 
+     */
+    private static final long serialVersionUID = 7629142718276852707L;
+
+    public DefaultUnionExpr(Expr lhs,
+                            Expr rhs)
+    {
+        super( lhs,
+               rhs );
+    }
+
+    public String getOperator()
+    {
+        return "|";
+    }
+
+    public String toString()
+    {
+        return "[(DefaultUnionExpr): " + getLHS() + ", " + getRHS() + "]";
+    }
+
+    public Object evaluate(Context context) throws JaxenException
+    {
+        List results = new ArrayList();
+
+        try {
+            List lhsResults = (List) getLHS().evaluate( context );
+            List rhsResults = (List) getRHS().evaluate( context );
+    
+            Set unique = new HashSet();
+    
+            results.addAll( lhsResults );
+            unique.addAll( lhsResults );
+    
+            Iterator rhsIter = rhsResults.iterator();
+    
+            while ( rhsIter.hasNext() )
+            {
+                Object each = rhsIter.next();
+    
+                if ( ! unique.contains( each ) )
+                {
+                    results.add( each );
+                    unique.add( each );
+                }
+            }
+            
+            Collections.sort(results, new NodeComparator(context.getNavigator()));
+    
+            return results;
+        }
+        catch (ClassCastException e) {
+            throw new XPathSyntaxException(this.getText(), context.getPosition(), "Unions are only allowed over node-sets");
+        }
+    }
+    
+    public void accept(Visitor visitor)
+    {
+        visitor.visit(this);
+    }
+    
+}
+
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/DefaultVariableReferenceExpr.java b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultVariableReferenceExpr.java
new file mode 100644
index 0000000..4681789
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultVariableReferenceExpr.java
@@ -0,0 +1,112 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/DefaultVariableReferenceExpr.java,v 1.15 2006/10/06 13:19:57 elharo Exp $
+ * $Revision: 1.15 $
+ * $Date: 2006/10/06 13:19:57 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: DefaultVariableReferenceExpr.java,v 1.15 2006/10/06 13:19:57 elharo Exp $
+ */
+
+package org.jaxen.expr;
+
+import org.jaxen.Context;
+import org.jaxen.UnresolvableException;
+
+class DefaultVariableReferenceExpr extends DefaultExpr implements VariableReferenceExpr
+{
+    /**
+     * 
+     */
+    private static final long serialVersionUID = 8832095437149358674L;
+    private String prefix;
+    private String localName;
+
+    DefaultVariableReferenceExpr(String prefix,
+                                        String variableName)
+    {
+        this.prefix       = prefix;
+        this.localName = variableName;
+    }
+
+    public String getPrefix()
+    {
+        return this.prefix;
+    }
+
+    public String getVariableName()
+    {
+        return this.localName;
+    }
+
+    public String toString()
+    {
+        return "[(DefaultVariableReferenceExpr): " + getQName() + "]";
+    }
+    
+    private String getQName() {
+        if ( "".equals(prefix) )
+        {
+            return localName;
+        }
+        return prefix + ":" + localName;
+    }
+
+    public String getText()
+    {
+        return "$" + getQName();
+    }
+
+    public Object evaluate(Context context)
+        throws UnresolvableException
+    {
+        String namespaceURI =
+            context.translateNamespacePrefixToUri( getPrefix() );
+
+        return context.getVariableValue( namespaceURI,
+                                         prefix,
+                                         localName );
+    }
+    
+    public void accept(Visitor visitor)
+    {
+        visitor.visit(this);
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/DefaultXPathExpr.java b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultXPathExpr.java
new file mode 100644
index 0000000..c2b6d58
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultXPathExpr.java
@@ -0,0 +1,106 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/DefaultXPathExpr.java,v 1.9 2006/06/03 20:52:26 elharo Exp $
+ * $Revision: 1.9 $
+ * $Date: 2006/06/03 20:52:26 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: DefaultXPathExpr.java,v 1.9 2006/06/03 20:52:26 elharo Exp $
+ */
+
+
+
+package org.jaxen.expr;
+
+import java.util.List;
+
+import org.jaxen.Context;
+import org.jaxen.JaxenException;
+
+/**
+ * @deprecated this class will become non-public in the future;
+ *     use the interface instead
+ */
+public class DefaultXPathExpr implements XPathExpr
+{
+    /**
+     * 
+     */
+    private static final long serialVersionUID = 3007613096320896040L;
+    private Expr rootExpr;
+
+    public DefaultXPathExpr(Expr rootExpr)
+    {
+        this.rootExpr = rootExpr;
+    }
+
+    public Expr getRootExpr()
+    {
+        return this.rootExpr;
+    }
+
+    public void setRootExpr(Expr rootExpr)
+    {
+        this.rootExpr = rootExpr;
+    }
+
+    public String toString()
+    {
+        return "[(DefaultXPath): " + getRootExpr() + "]";
+    }
+
+    public String getText()
+    {
+        return getRootExpr().getText();
+    }
+
+    public void simplify()
+    {
+        setRootExpr( getRootExpr().simplify() );
+    }
+
+    public List asList(Context context) throws JaxenException
+    {
+        Expr expr = getRootExpr();
+        Object value = expr.evaluate( context );
+        List result = DefaultExpr.convertToList( value );
+        return result;
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/DefaultXPathFactory.java b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultXPathFactory.java
new file mode 100644
index 0000000..593c749
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/DefaultXPathFactory.java
@@ -0,0 +1,376 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/DefaultXPathFactory.java,v 1.15 2006/02/05 21:47:40 elharo Exp $
+ * $Revision: 1.15 $
+ * $Date: 2006/02/05 21:47:40 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Jaxen Project and was originally
+ * created by bob mcwhirter <bob at werken.com> and
+ * James Strachan <jstrachan at apache.org>.  For more information on the
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ *
+ * $Id: DefaultXPathFactory.java,v 1.15 2006/02/05 21:47:40 elharo Exp $
+ */
+package org.jaxen.expr;
+
+import org.jaxen.JaxenException;
+import org.jaxen.expr.iter.IterableAncestorAxis;
+import org.jaxen.expr.iter.IterableAncestorOrSelfAxis;
+import org.jaxen.expr.iter.IterableAttributeAxis;
+import org.jaxen.expr.iter.IterableAxis;
+import org.jaxen.expr.iter.IterableChildAxis;
+import org.jaxen.expr.iter.IterableDescendantAxis;
+import org.jaxen.expr.iter.IterableDescendantOrSelfAxis;
+import org.jaxen.expr.iter.IterableFollowingAxis;
+import org.jaxen.expr.iter.IterableFollowingSiblingAxis;
+import org.jaxen.expr.iter.IterableNamespaceAxis;
+import org.jaxen.expr.iter.IterableParentAxis;
+import org.jaxen.expr.iter.IterablePrecedingAxis;
+import org.jaxen.expr.iter.IterablePrecedingSiblingAxis;
+import org.jaxen.expr.iter.IterableSelfAxis;
+import org.jaxen.saxpath.Axis;
+import org.jaxen.saxpath.Operator;
+
+public class DefaultXPathFactory implements XPathFactory
+{
+    public XPathExpr createXPath( Expr rootExpr ) throws JaxenException
+    {
+        return new DefaultXPathExpr( rootExpr );
+    }
+
+    public PathExpr createPathExpr( FilterExpr filterExpr,
+                                    LocationPath locationPath ) throws JaxenException
+    {
+        return new DefaultPathExpr( filterExpr,
+                                    locationPath );
+    }
+
+    public LocationPath createRelativeLocationPath() throws JaxenException
+    {
+        return new DefaultRelativeLocationPath();
+    }
+
+    public LocationPath createAbsoluteLocationPath() throws JaxenException
+    {
+        return new DefaultAbsoluteLocationPath();
+    }
+
+    public BinaryExpr createOrExpr( Expr lhs,
+                                    Expr rhs ) throws JaxenException
+    {
+        return new DefaultOrExpr( lhs,
+                                  rhs );
+    }
+
+    public BinaryExpr createAndExpr( Expr lhs,
+                                     Expr rhs ) throws JaxenException
+    {
+        return new DefaultAndExpr( lhs,
+                                   rhs );
+    }
+
+    public BinaryExpr createEqualityExpr( Expr lhs,
+                                          Expr rhs,
+                                          int equalityOperator ) throws JaxenException
+    {
+        switch( equalityOperator )
+        {
+            case Operator.EQUALS:
+                {
+                    return new DefaultEqualsExpr( lhs,
+                                                  rhs );
+                }
+            case Operator.NOT_EQUALS:
+                {
+                    return new DefaultNotEqualsExpr( lhs,
+                                                     rhs );
+                }
+        }
+        throw new JaxenException( "Unhandled operator in createEqualityExpr(): " + equalityOperator );
+    }
+
+    public BinaryExpr createRelationalExpr( Expr lhs,
+                                            Expr rhs,
+                                            int relationalOperator ) throws JaxenException
+    {
+        switch( relationalOperator )
+        {
+            case Operator.LESS_THAN:
+                {
+                    return new DefaultLessThanExpr( lhs,
+                                                    rhs );
+                }
+            case Operator.GREATER_THAN:
+                {
+                    return new DefaultGreaterThanExpr( lhs,
+                                                       rhs );
+                }
+            case Operator.LESS_THAN_EQUALS:
+                {
+                    return new DefaultLessThanEqualExpr( lhs,
+                                                         rhs );
+                }
+            case Operator.GREATER_THAN_EQUALS:
+                {
+                    return new DefaultGreaterThanEqualExpr( lhs,
+                                                            rhs );
+                }
+        }
+        throw new JaxenException( "Unhandled operator in createRelationalExpr(): " + relationalOperator );
+    }
+
+    public BinaryExpr createAdditiveExpr( Expr lhs,
+                                          Expr rhs,
+                                          int additiveOperator ) throws JaxenException
+    {
+        switch( additiveOperator )
+        {
+            case Operator.ADD:
+                {
+                    return new DefaultPlusExpr( lhs,
+                                                rhs );
+                }
+            case Operator.SUBTRACT:
+                {
+                    return new DefaultMinusExpr( lhs,
+                                                 rhs );
+                }
+        }
+        throw new JaxenException( "Unhandled operator in createAdditiveExpr(): " + additiveOperator );
+    }
+
+    public BinaryExpr createMultiplicativeExpr( Expr lhs,
+                                                Expr rhs,
+                                                int multiplicativeOperator ) throws JaxenException
+    {
+        switch( multiplicativeOperator )
+        {
+            case Operator.MULTIPLY:
+                {
+                    return new DefaultMultiplyExpr( lhs,
+                                                    rhs );
+                }
+            case Operator.DIV:
+                {
+                    return new DefaultDivExpr( lhs,
+                                               rhs );
+                }
+            case Operator.MOD:
+                {
+                    return new DefaultModExpr( lhs,
+                                               rhs );
+                }
+        }
+        throw new JaxenException( "Unhandled operator in createMultiplicativeExpr(): " + multiplicativeOperator );
+    }
+
+    public Expr createUnaryExpr( Expr expr,
+                                 int unaryOperator ) throws JaxenException
+    {
+        switch( unaryOperator )
+        {
+            case Operator.NEGATIVE:
+                {
+                    return new DefaultUnaryExpr( expr );
+                }
+        }
+        return expr;
+    }
+
+    public UnionExpr createUnionExpr( Expr lhs,
+                                      Expr rhs ) throws JaxenException
+    {
+        return new DefaultUnionExpr( lhs,
+                                     rhs );
+    }
+
+    public FilterExpr createFilterExpr( Expr expr ) throws JaxenException
+    {
+        return new DefaultFilterExpr( expr, createPredicateSet() );
+    }
+
+    public FunctionCallExpr createFunctionCallExpr( String prefix,
+                                                    String functionName ) throws JaxenException
+    {
+        return new DefaultFunctionCallExpr( prefix,
+                                            functionName );
+    }
+
+    public NumberExpr createNumberExpr( int number ) throws JaxenException
+    {
+        return new DefaultNumberExpr( new Double( number ) );
+    }
+
+    public NumberExpr createNumberExpr( double number ) throws JaxenException
+    {
+        return new DefaultNumberExpr( new Double( number ) );
+    }
+
+    public LiteralExpr createLiteralExpr( String literal ) throws JaxenException
+    {
+        return new DefaultLiteralExpr( literal );
+    }
+
+    public VariableReferenceExpr createVariableReferenceExpr( String prefix,
+                                                              String variable ) throws JaxenException
+    {
+        return new DefaultVariableReferenceExpr( prefix,
+                                                 variable );
+    }
+
+    public Step createNameStep( int axis,
+                                String prefix,
+                                String localName ) throws JaxenException
+    {
+        IterableAxis iter = getIterableAxis( axis );
+        return new DefaultNameStep( iter,
+                                    prefix,
+                                    localName,
+                                    createPredicateSet() );
+    }
+
+    public Step createTextNodeStep( int axis ) throws JaxenException
+    {
+        IterableAxis iter = getIterableAxis( axis );
+        return new DefaultTextNodeStep( iter, createPredicateSet() );
+    }
+
+    public Step createCommentNodeStep( int axis ) throws JaxenException
+    {
+        IterableAxis iter = getIterableAxis( axis );
+        return new DefaultCommentNodeStep( iter, createPredicateSet() );
+    }
+
+    public Step createAllNodeStep( int axis ) throws JaxenException
+    {
+        IterableAxis iter = getIterableAxis( axis );
+        return new DefaultAllNodeStep( iter, createPredicateSet() );
+    }
+
+    public Step createProcessingInstructionNodeStep( int axis,
+                                                     String piName ) throws JaxenException
+    {
+        IterableAxis iter = getIterableAxis( axis );
+        return new DefaultProcessingInstructionNodeStep( iter,
+                                                         piName,
+                                                         createPredicateSet() );
+    }
+
+    public Predicate createPredicate( Expr predicateExpr ) throws JaxenException
+    {
+        return new DefaultPredicate( predicateExpr );
+    }
+
+    protected IterableAxis getIterableAxis( int axis )
+    {
+        IterableAxis iter = null;
+        switch( axis )
+        {
+            case Axis.CHILD:
+                {
+                    iter = new IterableChildAxis( axis );
+                    break;
+                }
+            case Axis.DESCENDANT:
+                {
+                    iter = new IterableDescendantAxis( axis );
+                    break;
+                }
+            case Axis.PARENT:
+                {
+                    iter = new IterableParentAxis( axis );
+                    break;
+                }
+            case Axis.FOLLOWING_SIBLING:
+                {
+                    iter = new IterableFollowingSiblingAxis( axis );
+                    break;
+                }
+            case Axis.PRECEDING_SIBLING:
+                {
+                    iter = new IterablePrecedingSiblingAxis( axis );
+                    break;
+                }
+            case Axis.FOLLOWING:
+                {
+                    iter = new IterableFollowingAxis( axis );
+                    break;
+                }
+            case Axis.PRECEDING:
+                {
+                    iter = new IterablePrecedingAxis( axis );
+                    break;
+                }
+            case Axis.ATTRIBUTE:
+                {
+                    iter = new IterableAttributeAxis( axis );
+                    break;
+                }
+            case Axis.NAMESPACE:
+                {
+                    iter = new IterableNamespaceAxis( axis );
+                    break;
+                }
+            case Axis.SELF:
+                {
+                    iter = new IterableSelfAxis( axis );
+                    break;
+                }
+            case Axis.DESCENDANT_OR_SELF:
+                {
+                    iter = new IterableDescendantOrSelfAxis( axis );
+                    break;
+                }
+            case Axis.ANCESTOR_OR_SELF:
+                {
+                    iter = new IterableAncestorOrSelfAxis( axis );
+                    break;
+                }
+            case Axis.ANCESTOR:
+                {
+                    iter = new IterableAncestorAxis( axis );
+                    break;
+                }
+        }
+        return iter;
+    }
+
+    public PredicateSet createPredicateSet() throws JaxenException
+    {
+        return new PredicateSet();
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/EqualityExpr.java b/libjaxen-java/src/java/main/org/jaxen/expr/EqualityExpr.java
new file mode 100644
index 0000000..42003d5
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/EqualityExpr.java
@@ -0,0 +1,50 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/EqualityExpr.java,v 1.4 2006/02/05 21:47:40 elharo Exp $
+ * $Revision: 1.4 $
+ * $Date: 2006/02/05 21:47:40 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: EqualityExpr.java,v 1.4 2006/02/05 21:47:40 elharo Exp $
+ */
+package org.jaxen.expr;
+public interface EqualityExpr extends BinaryExpr{
+    public String getOperator();
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/Expr.java b/libjaxen-java/src/java/main/org/jaxen/expr/Expr.java
new file mode 100644
index 0000000..5d9c201
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/Expr.java
@@ -0,0 +1,61 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/Expr.java,v 1.11 2006/02/05 21:47:40 elharo Exp $
+ * $Revision: 1.11 $
+ * $Date: 2006/02/05 21:47:40 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: Expr.java,v 1.11 2006/02/05 21:47:40 elharo Exp $
+ */
+
+
+
+package org.jaxen.expr;
+
+import java.io.Serializable;
+import org.jaxen.Context;
+import org.jaxen.JaxenException;
+
+public interface Expr extends Serializable, Visitable
+{
+    String getText();
+    Expr   simplify();
+    Object evaluate(Context context) throws JaxenException;
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/FilterExpr.java b/libjaxen-java/src/java/main/org/jaxen/expr/FilterExpr.java
new file mode 100644
index 0000000..80bc6eb
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/FilterExpr.java
@@ -0,0 +1,66 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/FilterExpr.java,v 1.9 2006/02/05 21:47:40 elharo Exp $
+ * $Revision: 1.9 $
+ * $Date: 2006/02/05 21:47:40 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: FilterExpr.java,v 1.9 2006/02/05 21:47:40 elharo Exp $
+ */
+
+
+
+package org.jaxen.expr;
+
+import org.jaxen.Context;
+import org.jaxen.JaxenException;
+
+public interface FilterExpr extends Expr, Predicated
+{
+
+    /** Evaluates the filter expression on the current context
+     * and returns true if at least one node matches.
+     */
+    public boolean asBoolean(Context context) throws JaxenException;
+    /** 
+     * @return underlying filter expression
+     */
+    public Expr getExpr();
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/FunctionCallExpr.java b/libjaxen-java/src/java/main/org/jaxen/expr/FunctionCallExpr.java
new file mode 100644
index 0000000..bb6c270
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/FunctionCallExpr.java
@@ -0,0 +1,59 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/FunctionCallExpr.java,v 1.7 2006/02/05 21:47:40 elharo Exp $
+ * $Revision: 1.7 $
+ * $Date: 2006/02/05 21:47:40 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: FunctionCallExpr.java,v 1.7 2006/02/05 21:47:40 elharo Exp $
+ */
+
+
+
+package org.jaxen.expr;
+import java.util.List;
+
+public interface FunctionCallExpr extends Expr
+{
+    public String getPrefix();
+    public String getFunctionName();
+    public void addParameter(Expr parameter);
+    public List getParameters();
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/IdentitySet.java b/libjaxen-java/src/java/main/org/jaxen/expr/IdentitySet.java
new file mode 100644
index 0000000..7560f54
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/IdentitySet.java
@@ -0,0 +1,85 @@
+/*
+ $Id$
+
+ Copyright 2005 Elliotte Rusty Harold. All Rights Reserved.
+ 
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+  * Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+
+  * Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+
+  * Neither the name of the Jaxen Project nor the names of its
+    contributors may be used to endorse or promote products derived 
+    from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ */
+package org.jaxen.expr;
+
+import java.util.HashSet;
+
+
+/**
+ * <p>
+ *  This is a set that uses identity rather than equality semantics.
+ * </p>
+ * 
+ * @author Elliotte Rusty Harold
+ *
+ */
+final class IdentitySet {
+
+    private HashSet contents = new HashSet();
+    
+    IdentitySet() {
+        super();
+    }
+
+    void add(Object object) {
+        IdentityWrapper wrapper = new IdentityWrapper(object);
+        contents.add(wrapper);
+    }
+
+    public boolean contains(Object object) {
+        IdentityWrapper wrapper = new IdentityWrapper(object);
+        return contents.contains(wrapper);
+    }
+    
+    private static class IdentityWrapper {
+
+        private Object object;
+        
+        IdentityWrapper(Object object) {
+            this.object = object;
+        }
+        
+        public boolean equals(Object o) {
+            IdentityWrapper w = (IdentityWrapper) o;
+            return object == w.object;
+        }
+
+        public int hashCode() {
+            return System.identityHashCode(object);
+        }
+
+    }
+
+
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/LiteralExpr.java b/libjaxen-java/src/java/main/org/jaxen/expr/LiteralExpr.java
new file mode 100644
index 0000000..ccd9244
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/LiteralExpr.java
@@ -0,0 +1,55 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/LiteralExpr.java,v 1.7 2006/02/05 21:47:40 elharo Exp $
+ * $Revision: 1.7 $
+ * $Date: 2006/02/05 21:47:40 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: LiteralExpr.java,v 1.7 2006/02/05 21:47:40 elharo Exp $
+ */
+
+
+
+package org.jaxen.expr;
+
+public interface LiteralExpr extends Expr
+{
+    public String getLiteral();
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/LocationPath.java b/libjaxen-java/src/java/main/org/jaxen/expr/LocationPath.java
new file mode 100644
index 0000000..ad91ee6
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/LocationPath.java
@@ -0,0 +1,61 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/LocationPath.java,v 1.8 2006/02/05 21:47:40 elharo Exp $
+ * $Revision: 1.8 $
+ * $Date: 2006/02/05 21:47:40 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: LocationPath.java,v 1.8 2006/02/05 21:47:40 elharo Exp $
+ */
+
+
+
+package org.jaxen.expr;
+
+import java.util.List;
+
+public interface LocationPath extends Expr
+{
+    void addStep(Step step);
+
+    List getSteps();
+    
+    boolean isAbsolute();
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/LogicalExpr.java b/libjaxen-java/src/java/main/org/jaxen/expr/LogicalExpr.java
new file mode 100644
index 0000000..14fefbd
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/LogicalExpr.java
@@ -0,0 +1,51 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/LogicalExpr.java,v 1.4 2006/02/05 21:47:40 elharo Exp $
+ * $Revision: 1.4 $
+ * $Date: 2006/02/05 21:47:40 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: LogicalExpr.java,v 1.4 2006/02/05 21:47:40 elharo Exp $
+ */
+package org.jaxen.expr;
+
+public interface LogicalExpr extends BinaryExpr{
+    public String getOperator();
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/MultiplicativeExpr.java b/libjaxen-java/src/java/main/org/jaxen/expr/MultiplicativeExpr.java
new file mode 100644
index 0000000..edbb178
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/MultiplicativeExpr.java
@@ -0,0 +1,51 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/MultiplicativeExpr.java,v 1.4 2006/02/05 21:47:40 elharo Exp $
+ * $Revision: 1.4 $
+ * $Date: 2006/02/05 21:47:40 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: MultiplicativeExpr.java,v 1.4 2006/02/05 21:47:40 elharo Exp $
+ */
+package org.jaxen.expr;
+
+public interface MultiplicativeExpr extends BinaryExpr{
+    public String getOperator();
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/NameStep.java b/libjaxen-java/src/java/main/org/jaxen/expr/NameStep.java
new file mode 100644
index 0000000..030d281
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/NameStep.java
@@ -0,0 +1,54 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/NameStep.java,v 1.4 2006/02/05 21:47:40 elharo Exp $
+ * $Revision: 1.4 $
+ * $Date: 2006/02/05 21:47:40 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: NameStep.java,v 1.4 2006/02/05 21:47:40 elharo Exp $
+ */
+package org.jaxen.expr;
+
+//public interface Step extends Predicated, Expr
+public interface NameStep extends Step
+{
+    public String getPrefix();
+    public String getLocalName();
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/NodeComparator.java b/libjaxen-java/src/java/main/org/jaxen/expr/NodeComparator.java
new file mode 100644
index 0000000..582a049
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/NodeComparator.java
@@ -0,0 +1,157 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2005 Elliotte Rusty Harold.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+package org.jaxen.expr;
+
+import java.util.Comparator;
+import java.util.Iterator;
+
+import org.jaxen.Navigator;
+import org.jaxen.UnsupportedAxisException;
+
+
+class NodeComparator implements Comparator {
+    
+    private Navigator navigator;
+
+
+    NodeComparator(Navigator navigator) {
+        this.navigator = navigator;
+    }
+    
+    public int compare(Object o1, Object o2) {
+        
+        if (navigator == null) return 0;
+        
+        if (isNonChild(o1) && isNonChild(o2)) {
+            
+            try {
+                Object p1 = navigator.getParentNode(o1);
+                Object p2 = navigator.getParentNode(o2);
+            
+                if (p1 == p2) {
+                    if (navigator.isNamespace(o1) && navigator.isAttribute(o2)) {
+                        return -1;
+                    }
+                    else if (navigator.isNamespace(o2) && navigator.isAttribute(o1)) {
+                        return 1;
+                    }
+                }
+
+                return compare(p1, p2);
+            }
+            catch (UnsupportedAxisException ex) {
+                return 0;
+            }
+            
+        }
+
+        try {
+            int depth1 = getDepth(o1);
+            int depth2 = getDepth(o2);
+            
+            Object a1 = o1;
+            Object a2 = o2;
+                        
+            while (depth1 > depth2) {
+                a1 = navigator.getParentNode(a1);
+                depth1--;
+            }
+            if (a1 == o2) return 1;
+            
+            while (depth2 > depth1) {
+                a2 = navigator.getParentNode(a2);
+                depth2--;
+            }
+            if (a2 == o1) return -1;
+            
+            // a1 and a2 are now at same depth; and are not the same
+            while (true) {
+                Object p1 = navigator.getParentNode(a1);
+                Object p2 = navigator.getParentNode(a2);
+                if (p1 == p2) {
+                    return compareSiblings(a1, a2);
+                }
+                a1 = p1;
+                a2 = p2;
+            }
+            
+        }
+        catch (UnsupportedAxisException ex) {
+            return 0; // ???? should I throw an exception instead?
+        }
+    }
+    
+
+    private boolean isNonChild(Object o) {
+        return navigator.isAttribute(o) || navigator.isNamespace(o);
+    }
+
+    private int compareSiblings(Object sib1, Object sib2) 
+      throws UnsupportedAxisException {
+
+        Iterator following = navigator.getFollowingSiblingAxisIterator(sib1);
+        while (following.hasNext()) {
+            Object next = following.next();
+            if (next.equals(sib2)) return -1;
+        }
+        return 1;
+        
+    }
+
+    private int getDepth(Object o) throws UnsupportedAxisException {
+
+        int depth = 0;
+        Object parent = o;
+        
+        while ((parent = navigator.getParentNode(parent)) != null) {
+            depth++;
+        }
+        return depth;
+        
+    }
+    
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/NumberExpr.java b/libjaxen-java/src/java/main/org/jaxen/expr/NumberExpr.java
new file mode 100644
index 0000000..503ee2e
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/NumberExpr.java
@@ -0,0 +1,53 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/NumberExpr.java,v 1.7 2006/02/05 21:47:40 elharo Exp $
+ * $Revision: 1.7 $
+ * $Date: 2006/02/05 21:47:40 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Jaxen Project and was originally
+ * created by bob mcwhirter <bob at werken.com> and
+ * James Strachan <jstrachan at apache.org>.  For more information on the
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ *
+ * $Id: NumberExpr.java,v 1.7 2006/02/05 21:47:40 elharo Exp $
+ */
+package org.jaxen.expr;
+
+public interface NumberExpr extends Expr
+{
+    public Number getNumber();
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/PathExpr.java b/libjaxen-java/src/java/main/org/jaxen/expr/PathExpr.java
new file mode 100644
index 0000000..4332a67
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/PathExpr.java
@@ -0,0 +1,58 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/PathExpr.java,v 1.6 2006/02/05 21:47:40 elharo Exp $
+ * $Revision: 1.6 $
+ * $Date: 2006/02/05 21:47:40 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: PathExpr.java,v 1.6 2006/02/05 21:47:40 elharo Exp $
+ */
+
+
+
+package org.jaxen.expr;
+
+public interface PathExpr extends Expr
+{
+    Expr getFilterExpr();
+    void setFilterExpr(Expr filterExpr);
+
+    LocationPath getLocationPath();
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/Predicate.java b/libjaxen-java/src/java/main/org/jaxen/expr/Predicate.java
new file mode 100644
index 0000000..c6497da
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/Predicate.java
@@ -0,0 +1,67 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/Predicate.java,v 1.10 2006/02/05 21:47:40 elharo Exp $
+ * $Revision: 1.10 $
+ * $Date: 2006/02/05 21:47:40 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: Predicate.java,v 1.10 2006/02/05 21:47:40 elharo Exp $
+ */
+
+
+
+package org.jaxen.expr;
+
+import java.io.Serializable;
+import org.jaxen.Context;
+import org.jaxen.JaxenException;
+
+public interface Predicate extends Serializable, Visitable
+{
+    Expr getExpr();
+    void setExpr(Expr expr);
+
+    void simplify();
+
+    String getText();
+
+    Object evaluate(Context context) throws JaxenException;
+
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/PredicateSet.java b/libjaxen-java/src/java/main/org/jaxen/expr/PredicateSet.java
new file mode 100644
index 0000000..06aded1
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/PredicateSet.java
@@ -0,0 +1,234 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/PredicateSet.java,v 1.22 2006/09/15 21:03:23 elharo Exp $
+ * $Revision: 1.22 $
+ * $Date: 2006/09/15 21:03:23 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Jaxen Project and was originally
+ * created by bob mcwhirter <bob at werken.com> and
+ * James Strachan <jstrachan at apache.org>.  For more information on the
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ *
+ * $Id: PredicateSet.java,v 1.22 2006/09/15 21:03:23 elharo Exp $
+ */
+
+
+
+package org.jaxen.expr;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import org.jaxen.Context;
+import org.jaxen.ContextSupport;
+import org.jaxen.JaxenException;
+import org.jaxen.function.BooleanFunction;
+
+public class PredicateSet implements Serializable
+{
+
+    private static final long serialVersionUID = -7166491740228977853L;
+    
+    private List predicates;
+
+    public PredicateSet()
+    {
+        this.predicates = Collections.EMPTY_LIST;
+    }
+
+    public void addPredicate(Predicate predicate)
+    {
+        if ( this.predicates == Collections.EMPTY_LIST )
+        {
+            this.predicates = new ArrayList();
+        }
+
+        this.predicates.add( predicate );
+    }
+
+    public List getPredicates()
+    {
+        return this.predicates;
+    }
+
+    public void simplify()
+    {
+        Iterator  predIter = this.predicates.iterator();
+        Predicate eachPred = null;
+
+        while ( predIter.hasNext() )
+        {
+            eachPred = (Predicate) predIter.next();
+            eachPred.simplify();
+        }
+    }
+
+    public String getText()
+    {
+        StringBuffer buf = new StringBuffer();
+
+        Iterator  predIter = this.predicates.iterator();
+        Predicate eachPred = null;
+
+        while ( predIter.hasNext() )
+        {
+            eachPred = (Predicate) predIter.next();
+            buf.append( eachPred.getText() );
+        }
+
+        return buf.toString();
+    }
+
+    protected boolean evaluateAsBoolean(List contextNodeSet,
+                                      ContextSupport support) throws JaxenException
+    {
+        return anyMatchingNode( contextNodeSet, support );
+    }
+
+   private boolean anyMatchingNode(List contextNodeSet, ContextSupport support)
+     throws JaxenException {
+        // Easy way out (necessary)
+        if (predicates.size() == 0) {
+            return false;
+        }
+        Iterator predIter = predicates.iterator();
+
+        // initial list to filter
+        List nodes2Filter = contextNodeSet;
+        // apply all predicates
+        while(predIter.hasNext()) {
+            final int nodes2FilterSize = nodes2Filter.size();
+            // Set up a dummy context with a list to hold each node
+            Context predContext = new Context(support);
+            List tempList = new ArrayList(1);
+            predContext.setNodeSet(tempList);
+            // loop through the current nodes to filter and add to the
+            // filtered nodes list if the predicate succeeds
+            for (int i = 0; i < nodes2FilterSize; ++i) {
+                Object contextNode = nodes2Filter.get(i);
+                tempList.clear();
+                tempList.add(contextNode);
+                predContext.setNodeSet(tempList);
+                // ????
+                predContext.setPosition(i + 1);
+                predContext.setSize(nodes2FilterSize);
+                Object predResult = ((Predicate)predIter.next()).evaluate(predContext);
+                if (predResult instanceof Number) {
+                    // Here we assume nodes are in forward or reverse order
+                    // as appropriate for axis
+                    int proximity = ((Number) predResult).intValue();
+                    if (proximity == (i + 1)) {
+                        return true;
+                    }
+                }
+                else {
+                    Boolean includes =
+                        BooleanFunction.evaluate(predResult,
+                                                predContext.getNavigator());
+                    if (includes.booleanValue()) {
+                        return true;
+                    }
+                }
+            }
+        }
+        
+        return false;
+    }
+   
+    
+    
+    
+   protected List evaluatePredicates(List contextNodeSet, ContextSupport support)
+            throws JaxenException {
+        // Easy way out (necessary)
+        if (predicates.size() == 0) {
+            return contextNodeSet;
+        }
+        Iterator predIter = predicates.iterator();
+
+        // initial list to filter
+        List nodes2Filter = contextNodeSet;
+        // apply all predicates
+        while(predIter.hasNext()) {
+            nodes2Filter =
+                applyPredicate((Predicate)predIter.next(), nodes2Filter, support);
+        }
+        
+        return nodes2Filter;
+    }
+   
+    public List applyPredicate(Predicate predicate, List nodes2Filter, ContextSupport support)
+            throws JaxenException {
+        final int nodes2FilterSize = nodes2Filter.size();
+        List filteredNodes = new ArrayList(nodes2FilterSize);
+        // Set up a dummy context with a list to hold each node
+        Context predContext = new Context(support);
+        List tempList = new ArrayList(1);
+        predContext.setNodeSet(tempList);
+        // loop through the current nodes to filter and add to the
+        // filtered nodes list if the predicate succeeds
+        for (int i = 0; i < nodes2FilterSize; ++i) {
+            Object contextNode = nodes2Filter.get(i);
+            tempList.clear();
+            tempList.add(contextNode);
+            predContext.setNodeSet(tempList);
+            // ????
+            predContext.setPosition(i + 1);
+            predContext.setSize(nodes2FilterSize);
+            Object predResult = predicate.evaluate(predContext);
+            if (predResult instanceof Number) {
+                // Here we assume nodes are in forward or reverse order
+                // as appropriate for axis
+                int proximity = ((Number) predResult).intValue();
+                if (proximity == (i + 1)) {
+                    filteredNodes.add(contextNode);
+                }
+            }
+            else {
+                Boolean includes =
+                    BooleanFunction.evaluate(predResult,
+                                            predContext.getNavigator());
+                if (includes.booleanValue()) {
+                    filteredNodes.add(contextNode);
+                }
+            }
+        }
+        return filteredNodes;
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/Predicated.java b/libjaxen-java/src/java/main/org/jaxen/expr/Predicated.java
new file mode 100644
index 0000000..5c09b5e
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/Predicated.java
@@ -0,0 +1,60 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/Predicated.java,v 1.8 2006/02/05 21:47:40 elharo Exp $
+ * $Revision: 1.8 $
+ * $Date: 2006/02/05 21:47:40 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: Predicated.java,v 1.8 2006/02/05 21:47:40 elharo Exp $
+ */
+
+
+
+package org.jaxen.expr;
+
+import java.io.Serializable;
+import java.util.List;
+
+public interface Predicated extends Serializable
+{
+    void addPredicate(Predicate predicate);
+    List getPredicates();
+    PredicateSet getPredicateSet();
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/ProcessingInstructionNodeStep.java b/libjaxen-java/src/java/main/org/jaxen/expr/ProcessingInstructionNodeStep.java
new file mode 100644
index 0000000..ae928b2
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/ProcessingInstructionNodeStep.java
@@ -0,0 +1,52 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/ProcessingInstructionNodeStep.java,v 1.4 2006/02/05 21:47:40 elharo Exp $
+ * $Revision: 1.4 $
+ * $Date: 2006/02/05 21:47:40 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: ProcessingInstructionNodeStep.java,v 1.4 2006/02/05 21:47:40 elharo Exp $
+ */
+package org.jaxen.expr;
+
+public interface ProcessingInstructionNodeStep extends Step
+{
+    public String getName();
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/RelationalExpr.java b/libjaxen-java/src/java/main/org/jaxen/expr/RelationalExpr.java
new file mode 100644
index 0000000..68c13c9
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/RelationalExpr.java
@@ -0,0 +1,50 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/RelationalExpr.java,v 1.4 2006/02/05 21:47:40 elharo Exp $
+ * $Revision: 1.4 $
+ * $Date: 2006/02/05 21:47:40 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: RelationalExpr.java,v 1.4 2006/02/05 21:47:40 elharo Exp $
+ */
+package org.jaxen.expr; 
+public interface RelationalExpr extends BinaryExpr{
+    public String getOperator();
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/Step.java b/libjaxen-java/src/java/main/org/jaxen/expr/Step.java
new file mode 100644
index 0000000..1e71584
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/Step.java
@@ -0,0 +1,101 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/Step.java,v 1.10 2006/02/05 21:47:40 elharo Exp $
+ * $Revision: 1.10 $
+ * $Date: 2006/02/05 21:47:40 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: Step.java,v 1.10 2006/02/05 21:47:40 elharo Exp $
+ */
+
+package org.jaxen.expr;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.jaxen.Context;
+import org.jaxen.ContextSupport;
+import org.jaxen.JaxenException;
+import org.jaxen.UnsupportedAxisException;
+
+/**
+ * A Step represents a location step in a LocationPath. The node-set selected by 
+ * the location step is the node-set that results from generating an initial 
+ * node-set from the axis and node-test, and then filtering that node-set by 
+ * each of the predicates in turn.
+ * 
+ * The initial node-set consists of the nodes having the relationship to the 
+ * context node specified by the axis, and having the node type and expanded-name 
+ * specified by the node test.
+ */
+public interface Step extends Predicated, Visitable
+{
+
+    /**
+     * Performs the node-test part of evaluating the step for the given node
+     * (which must be on the axis).
+     */    
+    boolean matches(Object node,
+                    ContextSupport contextSupport) throws JaxenException;
+
+    String getText();
+
+    void simplify();
+
+    /**
+     * Get an identifier for the current axis.
+     * @see org.jaxen.saxpath.Axis
+     */
+    public int getAxis();
+
+    /**
+     * Get an Iterator for the current axis starting in the given contextNode.
+     */    
+    Iterator axisIterator(Object contextNode,
+                          ContextSupport support) throws UnsupportedAxisException;
+
+    /**
+     * For each node in the given context calls matches() for every node on the
+     * axis, then filters the result by each of the predicates.
+     */
+    List evaluate(Context context) throws JaxenException;
+
+}
+
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/TextNodeStep.java b/libjaxen-java/src/java/main/org/jaxen/expr/TextNodeStep.java
new file mode 100644
index 0000000..a584ecf
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/TextNodeStep.java
@@ -0,0 +1,51 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/TextNodeStep.java,v 1.5 2006/02/05 21:47:40 elharo Exp $
+ * $Revision: 1.5 $
+ * $Date: 2006/02/05 21:47:40 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: TextNodeStep.java,v 1.5 2006/02/05 21:47:40 elharo Exp $
+ */
+package org.jaxen.expr;
+
+public interface TextNodeStep extends Step
+{
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/UnaryExpr.java b/libjaxen-java/src/java/main/org/jaxen/expr/UnaryExpr.java
new file mode 100644
index 0000000..d47ac8b
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/UnaryExpr.java
@@ -0,0 +1,55 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/UnaryExpr.java,v 1.6 2006/02/05 21:47:40 elharo Exp $
+ * $Revision: 1.6 $
+ * $Date: 2006/02/05 21:47:40 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: UnaryExpr.java,v 1.6 2006/02/05 21:47:40 elharo Exp $
+ */
+
+
+
+package org.jaxen.expr;
+
+public interface UnaryExpr extends Expr
+{
+    Expr getExpr();
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/UnionExpr.java b/libjaxen-java/src/java/main/org/jaxen/expr/UnionExpr.java
new file mode 100644
index 0000000..8738b75
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/UnionExpr.java
@@ -0,0 +1,54 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/UnionExpr.java,v 1.6 2006/02/05 21:47:40 elharo Exp $
+ * $Revision: 1.6 $
+ * $Date: 2006/02/05 21:47:40 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: UnionExpr.java,v 1.6 2006/02/05 21:47:40 elharo Exp $
+ */
+
+
+
+package org.jaxen.expr;
+
+public interface UnionExpr extends BinaryExpr
+{
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/VariableReferenceExpr.java b/libjaxen-java/src/java/main/org/jaxen/expr/VariableReferenceExpr.java
new file mode 100644
index 0000000..7b77838
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/VariableReferenceExpr.java
@@ -0,0 +1,56 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/VariableReferenceExpr.java,v 1.7 2006/02/05 21:47:40 elharo Exp $
+ * $Revision: 1.7 $
+ * $Date: 2006/02/05 21:47:40 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: VariableReferenceExpr.java,v 1.7 2006/02/05 21:47:40 elharo Exp $
+ */
+
+
+
+package org.jaxen.expr;
+
+public interface VariableReferenceExpr extends Expr
+{
+    public String getPrefix();
+    public String getVariableName();
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/Visitable.java b/libjaxen-java/src/java/main/org/jaxen/expr/Visitable.java
new file mode 100644
index 0000000..74efd12
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/Visitable.java
@@ -0,0 +1,50 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/Visitable.java,v 1.4 2006/02/05 21:47:40 elharo Exp $
+ * $Revision: 1.4 $
+ * $Date: 2006/02/05 21:47:40 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: Visitable.java,v 1.4 2006/02/05 21:47:40 elharo Exp $
+ */
+package org.jaxen.expr;
+public interface Visitable {
+    public void accept(Visitor visitor);
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/Visitor.java b/libjaxen-java/src/java/main/org/jaxen/expr/Visitor.java
new file mode 100644
index 0000000..0654d64
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/Visitor.java
@@ -0,0 +1,71 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/Visitor.java,v 1.4 2006/02/05 21:47:40 elharo Exp $
+ * $Revision: 1.4 $
+ * $Date: 2006/02/05 21:47:40 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: Visitor.java,v 1.4 2006/02/05 21:47:40 elharo Exp $
+ */
+package org.jaxen.expr;
+
+public interface Visitor {
+    public void visit(PathExpr path);
+    public void visit(LocationPath path);
+    public void visit(LogicalExpr expr);
+    public void visit(EqualityExpr expr);
+    public void visit(FilterExpr expr);
+    public void visit(RelationalExpr expr);
+    public void visit(AdditiveExpr expr);
+    public void visit(MultiplicativeExpr expr);
+    public void visit(UnaryExpr expr);
+    public void visit(UnionExpr expr);
+    public void visit(NumberExpr expr);
+    public void visit(LiteralExpr expr);
+    public void visit(VariableReferenceExpr expr);
+    public void visit(FunctionCallExpr expr);
+    // Steps
+    public void visit(NameStep step);
+    public void visit(ProcessingInstructionNodeStep step);
+    public void visit(AllNodeStep step);
+    public void visit(TextNodeStep step);
+    public void visit(CommentNodeStep step);
+    public void visit(Predicate predicate);
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/VisitorSupport.java b/libjaxen-java/src/java/main/org/jaxen/expr/VisitorSupport.java
new file mode 100644
index 0000000..c202e5c
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/VisitorSupport.java
@@ -0,0 +1,89 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/VisitorSupport.java,v 1.4 2006/02/05 21:47:40 elharo Exp $
+ * $Revision: 1.4 $
+ * $Date: 2006/02/05 21:47:40 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: VisitorSupport.java,v 1.4 2006/02/05 21:47:40 elharo Exp $
+ */
+package org.jaxen.expr;
+public class VisitorSupport implements Visitor {
+    public void visit(PathExpr path) {
+    }
+    public void visit(LocationPath path) {
+    }
+    public void visit(LogicalExpr expr) {
+    }
+    public void visit(EqualityExpr expr) {
+    }
+    public void visit(FilterExpr expr) {
+    }
+    public void visit(RelationalExpr expr) {
+    }
+    public void visit(AdditiveExpr expr) {
+    }
+    public void visit(MultiplicativeExpr expr) {
+    }
+    public void visit(UnaryExpr expr) {
+    }
+    public void visit(UnionExpr expr) {
+    }
+    public void visit(NumberExpr expr) {
+    }
+    public void visit(LiteralExpr expr) {
+    }
+    public void visit(VariableReferenceExpr expr) {
+    }
+    public void visit(FunctionCallExpr expr) {
+    }
+    public void visit(NameStep step){
+    }
+    public void visit(ProcessingInstructionNodeStep step){
+    }
+    public void visit(AllNodeStep step){
+    }
+    public void visit(TextNodeStep step){
+    }
+    public void visit(CommentNodeStep step){
+    }
+    public void visit(Predicate predicate){
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/XPathExpr.java b/libjaxen-java/src/java/main/org/jaxen/expr/XPathExpr.java
new file mode 100644
index 0000000..38b6150
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/XPathExpr.java
@@ -0,0 +1,67 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/XPathExpr.java,v 1.6 2006/02/05 21:47:40 elharo Exp $
+ * $Revision: 1.6 $
+ * $Date: 2006/02/05 21:47:40 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: XPathExpr.java,v 1.6 2006/02/05 21:47:40 elharo Exp $
+ */
+
+
+
+package org.jaxen.expr;
+
+import java.io.Serializable;
+import java.util.List;
+
+import org.jaxen.Context;
+import org.jaxen.JaxenException;
+
+public interface XPathExpr extends Serializable
+{
+    Expr getRootExpr();
+    void setRootExpr(Expr rootExpr);
+    String getText();
+    void simplify();
+
+    List asList(Context context) throws JaxenException;
+
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/XPathFactory.java b/libjaxen-java/src/java/main/org/jaxen/expr/XPathFactory.java
new file mode 100644
index 0000000..c7db5ee
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/XPathFactory.java
@@ -0,0 +1,121 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/XPathFactory.java,v 1.11 2006/02/05 21:47:40 elharo Exp $
+ * $Revision: 1.11 $
+ * $Date: 2006/02/05 21:47:40 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Jaxen Project and was originally
+ * created by bob mcwhirter <bob at werken.com> and
+ * James Strachan <jstrachan at apache.org>.  For more information on the
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ *
+ * $Id: XPathFactory.java,v 1.11 2006/02/05 21:47:40 elharo Exp $
+ */
+package org.jaxen.expr;
+
+import org.jaxen.JaxenException;
+
+public interface XPathFactory
+{
+    XPathExpr createXPath( Expr rootExpr ) throws JaxenException;
+
+    PathExpr createPathExpr( FilterExpr filterExpr,
+                             LocationPath locationPath ) throws JaxenException;
+
+    LocationPath createRelativeLocationPath() throws JaxenException;
+
+    LocationPath createAbsoluteLocationPath() throws JaxenException;
+
+    BinaryExpr createOrExpr( Expr lhs,
+                             Expr rhs ) throws JaxenException;
+
+    BinaryExpr createAndExpr( Expr lhs,
+                              Expr rhs ) throws JaxenException;
+
+    BinaryExpr createEqualityExpr( Expr lhs,
+                                   Expr rhs,
+                                   int equalityOperator ) throws JaxenException;
+
+    BinaryExpr createRelationalExpr( Expr lhs,
+                                     Expr rhs,
+                                     int relationalOperator ) throws JaxenException;
+
+    BinaryExpr createAdditiveExpr( Expr lhs,
+                                   Expr rhs,
+                                   int additiveOperator ) throws JaxenException;
+
+    BinaryExpr createMultiplicativeExpr( Expr lhs,
+                                         Expr rhs,
+                                         int multiplicativeOperator ) throws JaxenException;
+
+    Expr createUnaryExpr( Expr expr,
+                          int unaryOperator ) throws JaxenException;
+
+    UnionExpr createUnionExpr( Expr lhs,
+                               Expr rhs ) throws JaxenException;
+
+    FilterExpr createFilterExpr( Expr expr ) throws JaxenException;
+
+    FunctionCallExpr createFunctionCallExpr( String prefix,
+                                             String functionName ) throws JaxenException;
+
+    NumberExpr createNumberExpr( int number ) throws JaxenException;
+
+    NumberExpr createNumberExpr( double number ) throws JaxenException;
+
+    LiteralExpr createLiteralExpr( String literal ) throws JaxenException;
+
+    VariableReferenceExpr createVariableReferenceExpr( String prefix,
+                                                       String variableName ) throws JaxenException;
+
+    Step createNameStep( int axis,
+                         String prefix,
+                         String localName ) throws JaxenException;
+
+    Step createAllNodeStep( int axis ) throws JaxenException;
+
+    Step createCommentNodeStep( int axis ) throws JaxenException;
+
+    Step createTextNodeStep( int axis ) throws JaxenException;
+
+    Step createProcessingInstructionNodeStep( int axis,
+                                              String name ) throws JaxenException;
+
+    Predicate createPredicate( Expr predicateExpr ) throws JaxenException;
+
+    PredicateSet createPredicateSet() throws JaxenException;
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/iter/IterableAncestorAxis.java b/libjaxen-java/src/java/main/org/jaxen/expr/iter/IterableAncestorAxis.java
new file mode 100644
index 0000000..5b1e60f
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/iter/IterableAncestorAxis.java
@@ -0,0 +1,75 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/iter/IterableAncestorAxis.java,v 1.7 2006/06/03 20:50:12 elharo Exp $
+ * $Revision: 1.7 $
+ * $Date: 2006/06/03 20:50:12 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: IterableAncestorAxis.java,v 1.7 2006/06/03 20:50:12 elharo Exp $
+ */
+
+
+package org.jaxen.expr.iter;
+
+import java.util.Iterator;
+
+import org.jaxen.ContextSupport;
+import org.jaxen.UnsupportedAxisException;
+
+public class IterableAncestorAxis extends IterableAxis
+{
+
+    /**
+     * 
+     */
+    private static final long serialVersionUID = 1L;
+
+    public IterableAncestorAxis(int value)
+    {
+        super( value );
+    }
+
+    public Iterator iterator(Object contextNode,
+                             ContextSupport support) throws UnsupportedAxisException
+    {
+        return support.getNavigator().getAncestorAxisIterator( contextNode );
+    }
+    
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/iter/IterableAncestorOrSelfAxis.java b/libjaxen-java/src/java/main/org/jaxen/expr/iter/IterableAncestorOrSelfAxis.java
new file mode 100644
index 0000000..8aa1e1f
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/iter/IterableAncestorOrSelfAxis.java
@@ -0,0 +1,73 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/iter/IterableAncestorOrSelfAxis.java,v 1.7 2006/06/03 20:50:12 elharo Exp $
+ * $Revision: 1.7 $
+ * $Date: 2006/06/03 20:50:12 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: IterableAncestorOrSelfAxis.java,v 1.7 2006/06/03 20:50:12 elharo Exp $
+ */
+
+
+package org.jaxen.expr.iter;
+
+import java.util.Iterator;
+
+import org.jaxen.ContextSupport;
+import org.jaxen.UnsupportedAxisException;
+
+public class IterableAncestorOrSelfAxis extends IterableAxis
+{
+    /**
+     * 
+     */
+    private static final long serialVersionUID = 1L;
+
+    public IterableAncestorOrSelfAxis(int value)
+    {
+        super( value );
+    }
+
+    public Iterator iterator(Object contextNode,
+                             ContextSupport support) throws UnsupportedAxisException
+    {
+        return support.getNavigator().getAncestorOrSelfAxisIterator( contextNode );
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/iter/IterableAttributeAxis.java b/libjaxen-java/src/java/main/org/jaxen/expr/iter/IterableAttributeAxis.java
new file mode 100644
index 0000000..d2e36c8
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/iter/IterableAttributeAxis.java
@@ -0,0 +1,109 @@
+/*
+ $Id: IterableAttributeAxis.java,v 1.9 2006/06/03 20:50:12 elharo Exp $
+
+ Copyright 2003 The Werken Company. All Rights Reserved.
+ 
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+  * Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+
+  * Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+
+  * Neither the name of the Jaxen Project nor the names of its
+    contributors may be used to endorse or promote products derived 
+    from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ */
+package org.jaxen.expr.iter;
+
+import java.util.Iterator;
+
+import org.jaxen.ContextSupport;
+import org.jaxen.NamedAccessNavigator;
+import org.jaxen.UnsupportedAxisException;
+
+/**
+ * Provide access to the XPath attribute axis.
+ * This axis does not include namespace declarations such as 
+ * <code>xmlns</code> and <code>xmlns:<i>prefix</i></code>.
+ * It does include attributes defaulted from the DTD.
+ * 
+ * @author Bob McWhirter
+ * @author James Strachan
+ * @author Stephen Colebourne
+ */
+public class IterableAttributeAxis extends IterableAxis {
+    
+    /**
+     * 
+     */
+    private static final long serialVersionUID = 1L;
+    
+    /**
+     * Constructor.
+     * 
+     * @param value the axis value
+     */
+    public IterableAttributeAxis(int value) {
+        super(value);
+    }
+
+    /**
+     * Gets an iterator for the attribute axis.
+     * 
+     * @param contextNode  the current context node to work from
+     * @param support  the additional context information
+     */
+    public Iterator iterator(Object contextNode, ContextSupport support) throws UnsupportedAxisException {
+        return support.getNavigator().getAttributeAxisIterator(contextNode);
+    }
+
+    /**
+     * Gets the iterator for the attribute axis that supports named access.
+     * 
+     * @param contextNode  the current context node to work from
+     * @param support  the additional context information
+     * @param localName  the local name of the attributes to return
+     * @param namespacePrefix  the prefix of the namespace of the attributes to return
+     * @param namespaceURI  the uri of the namespace of the attributes to return
+     */
+    public Iterator namedAccessIterator(
+        Object contextNode,
+        ContextSupport support,
+        String localName,
+        String namespacePrefix,
+        String namespaceURI)
+            throws UnsupportedAxisException {
+                
+        NamedAccessNavigator nav = (NamedAccessNavigator) support.getNavigator();
+        return nav.getAttributeAxisIterator(contextNode, localName, namespacePrefix, namespaceURI);
+    }
+
+    /**
+     * Does this axis support named access?
+     * 
+     * @param support  the additional context information
+     * @return true if named access is supported. If not iterator() will be used.
+     */
+    public boolean supportsNamedAccess(ContextSupport support) {
+        return (support.getNavigator() instanceof NamedAccessNavigator);
+    }
+
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/iter/IterableAxis.java b/libjaxen-java/src/java/main/org/jaxen/expr/iter/IterableAxis.java
new file mode 100644
index 0000000..06c9176
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/iter/IterableAxis.java
@@ -0,0 +1,112 @@
+/*
+ $Id: IterableAxis.java,v 1.9 2006/02/05 21:47:42 elharo Exp $
+
+ Copyright 2003 The Werken Company. All Rights Reserved.
+ 
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+  * Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+
+  * Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+
+  * Neither the name of the Jaxen Project nor the names of its
+    contributors may be used to endorse or promote products derived 
+    from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ */
+package org.jaxen.expr.iter;
+
+import java.io.Serializable;
+import java.util.Iterator;
+
+import org.jaxen.ContextSupport;
+import org.jaxen.UnsupportedAxisException;
+
+/**
+ * Provide access to the XPath axes.
+ * 
+ * @author Bob McWhirter
+ * @author James Strachan
+ * @author Stephen Colebourne
+ */
+public abstract class IterableAxis implements Serializable {
+    
+    /** The axis type */
+    private int value;
+
+    /**
+     * Constructor.
+     * 
+     * @param axisValue
+     */
+    public IterableAxis(int axisValue) {
+        this.value = axisValue;
+    }
+
+    /**
+     * Gets the axis value.
+     * 
+     * @return the axis value
+     */
+    public int value() {
+        return this.value;
+    }
+
+    /**
+     * Gets the iterator for a specific XPath axis.
+     * 
+     * @param contextNode  the current context node to work from
+     * @param support  the additional context information
+     * @return an iterator for the axis 
+     * @throws UnsupportedAxisException
+     */
+    public abstract Iterator iterator(Object contextNode, ContextSupport support) throws UnsupportedAxisException;
+
+    /**
+     * Gets the iterator for a specific XPath axis that supports named access.
+     *
+     * @param contextNode  the current context node to work from
+     * @param support  the additional context information
+     * @param localName  the local name of the nodes to return
+     * @param namespacePrefix  the prefix of the namespace of the nodes to return
+     * @param namespaceURI  the URI of the namespace of the nodes to return
+     */
+    public Iterator namedAccessIterator(
+        Object contextNode,
+        ContextSupport support,
+        String localName,
+        String namespacePrefix,
+        String namespaceURI)
+            throws UnsupportedAxisException {
+                
+        throw new UnsupportedOperationException("Named access unsupported");
+    }
+
+    /**
+     * Does this axis support named access?
+     * 
+     * @param support  the additional context information
+     * @return true if named access supported. If not iterator() will be used
+     */
+    public boolean supportsNamedAccess(ContextSupport support) {
+        return false;
+    }
+
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/iter/IterableChildAxis.java b/libjaxen-java/src/java/main/org/jaxen/expr/iter/IterableChildAxis.java
new file mode 100644
index 0000000..fb7306c
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/iter/IterableChildAxis.java
@@ -0,0 +1,111 @@
+/*
+ $Id: IterableChildAxis.java,v 1.11 2006/06/03 20:50:12 elharo Exp $
+
+ Copyright 2003 The Werken Company. All Rights Reserved.
+ 
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+  * Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+
+  * Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+
+  * Neither the name of the Jaxen Project nor the names of its
+    contributors may be used to endorse or promote products derived 
+    from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ */
+package org.jaxen.expr.iter;
+
+import java.util.Iterator;
+
+import org.jaxen.ContextSupport;
+import org.jaxen.NamedAccessNavigator;
+import org.jaxen.UnsupportedAxisException;
+
+/**
+ * Provide access to the child xpath axis.
+ * 
+ * @author Bob McWhirter
+ * @author James Strachan
+ * @author Stephen Colebourne
+ */
+public class IterableChildAxis extends IterableAxis {
+    
+    /**
+     * 
+     */
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * Constructor.
+     * 
+     * @param value the axis value
+     */
+    public IterableChildAxis(int value) {
+        super(value);
+    }
+
+    /**
+     * Gets the iterator for the child axis.
+     * 
+     * @param contextNode  the current context node to work from
+     * @param support  the additional context information
+     * @return an iterator over the children of the context node
+     * @throws UnsupportedAxisException if the child axis is not supported
+     */
+    public Iterator iterator(Object contextNode, ContextSupport support) 
+      throws UnsupportedAxisException {
+        return support.getNavigator().getChildAxisIterator(contextNode);
+    }
+
+    /**
+     * Gets an iterator for the child XPath axis that supports named access.
+     * 
+     * @param contextNode  the current context node to work from
+     * @param support  the additional context information
+     * @param localName  the local name of the children to return
+     * @param namespacePrefix  the prefix of the namespace of the children to return
+     * @param namespaceURI  the URI of the namespace of the children to return
+     * @return an iterator over the children of the context node
+     * @throws UnsupportedAxisException if the child axis is not supported by the model
+     */
+    public Iterator namedAccessIterator(
+        Object contextNode,
+        ContextSupport support,
+        String localName,
+        String namespacePrefix,
+        String namespaceURI)
+            throws UnsupportedAxisException {
+                
+        NamedAccessNavigator nav = (NamedAccessNavigator) support.getNavigator();
+        return nav.getChildAxisIterator(contextNode, localName, namespacePrefix, namespaceURI);
+    }
+
+    /**
+     * Does this axis support named access?
+     * 
+     * @param support the additional context information
+     * @return true if named access supported. If not iterator() will be used
+     */
+    public boolean supportsNamedAccess(ContextSupport support) {
+        return (support.getNavigator() instanceof NamedAccessNavigator);
+    }
+
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/iter/IterableDescendantAxis.java b/libjaxen-java/src/java/main/org/jaxen/expr/iter/IterableDescendantAxis.java
new file mode 100644
index 0000000..3dcdbbc
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/iter/IterableDescendantAxis.java
@@ -0,0 +1,73 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/iter/IterableDescendantAxis.java,v 1.7 2006/06/03 20:47:22 elharo Exp $
+ * $Revision: 1.7 $
+ * $Date: 2006/06/03 20:47:22 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: IterableDescendantAxis.java,v 1.7 2006/06/03 20:47:22 elharo Exp $
+ */
+
+
+package org.jaxen.expr.iter;
+
+import java.util.Iterator;
+
+import org.jaxen.ContextSupport;
+import org.jaxen.UnsupportedAxisException;
+
+public class IterableDescendantAxis extends IterableAxis
+{
+    /**
+     * 
+     */
+    private static final long serialVersionUID = 7286715505909806723L;
+
+    public IterableDescendantAxis(int value)
+    {
+        super( value );
+    }
+
+    public Iterator iterator(Object contextNode,
+                             ContextSupport support) throws UnsupportedAxisException
+    {
+        return support.getNavigator().getDescendantAxisIterator( contextNode );
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/iter/IterableDescendantOrSelfAxis.java b/libjaxen-java/src/java/main/org/jaxen/expr/iter/IterableDescendantOrSelfAxis.java
new file mode 100644
index 0000000..26e1eb5
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/iter/IterableDescendantOrSelfAxis.java
@@ -0,0 +1,73 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/iter/IterableDescendantOrSelfAxis.java,v 1.7 2006/06/03 20:47:22 elharo Exp $
+ * $Revision: 1.7 $
+ * $Date: 2006/06/03 20:47:22 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: IterableDescendantOrSelfAxis.java,v 1.7 2006/06/03 20:47:22 elharo Exp $
+ */
+
+
+package org.jaxen.expr.iter;
+
+import java.util.Iterator;
+
+import org.jaxen.ContextSupport;
+import org.jaxen.UnsupportedAxisException;
+
+public class IterableDescendantOrSelfAxis extends IterableAxis
+{
+    /**
+     * 
+     */
+    private static final long serialVersionUID = 2956703237251023850L;
+
+    public IterableDescendantOrSelfAxis(int value)
+    {
+        super( value );
+    }
+
+    public Iterator iterator(Object contextNode,
+                             ContextSupport support) throws UnsupportedAxisException
+    {
+        return support.getNavigator().getDescendantOrSelfAxisIterator( contextNode );
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/iter/IterableFollowingAxis.java b/libjaxen-java/src/java/main/org/jaxen/expr/iter/IterableFollowingAxis.java
new file mode 100644
index 0000000..71f4347
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/iter/IterableFollowingAxis.java
@@ -0,0 +1,73 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/iter/IterableFollowingAxis.java,v 1.7 2006/06/03 20:47:22 elharo Exp $
+ * $Revision: 1.7 $
+ * $Date: 2006/06/03 20:47:22 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: IterableFollowingAxis.java,v 1.7 2006/06/03 20:47:22 elharo Exp $
+ */
+
+
+package org.jaxen.expr.iter;
+
+import java.util.Iterator;
+
+import org.jaxen.ContextSupport;
+import org.jaxen.UnsupportedAxisException;
+
+public class IterableFollowingAxis extends IterableAxis
+{
+    /**
+     * 
+     */
+    private static final long serialVersionUID = -7100245752300813209L;
+
+    public IterableFollowingAxis(int value)
+    {
+        super( value );
+    }
+
+    public Iterator iterator(Object contextNode,
+                             ContextSupport support) throws UnsupportedAxisException
+    {
+        return support.getNavigator().getFollowingAxisIterator( contextNode );
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/iter/IterableFollowingSiblingAxis.java b/libjaxen-java/src/java/main/org/jaxen/expr/iter/IterableFollowingSiblingAxis.java
new file mode 100644
index 0000000..172914f
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/iter/IterableFollowingSiblingAxis.java
@@ -0,0 +1,73 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/iter/IterableFollowingSiblingAxis.java,v 1.7 2006/06/03 20:47:22 elharo Exp $
+ * $Revision: 1.7 $
+ * $Date: 2006/06/03 20:47:22 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: IterableFollowingSiblingAxis.java,v 1.7 2006/06/03 20:47:22 elharo Exp $
+ */
+
+
+package org.jaxen.expr.iter;
+
+import java.util.Iterator;
+
+import org.jaxen.ContextSupport;
+import org.jaxen.UnsupportedAxisException;
+
+public class IterableFollowingSiblingAxis extends IterableAxis
+{
+    /**
+     * 
+     */
+    private static final long serialVersionUID = 4412705219546610009L;
+
+    public IterableFollowingSiblingAxis(int value)
+    {
+        super( value );
+    }
+
+    public Iterator iterator(Object contextNode,
+                             ContextSupport support) throws UnsupportedAxisException
+    {
+        return support.getNavigator().getFollowingSiblingAxisIterator( contextNode );
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/iter/IterableNamespaceAxis.java b/libjaxen-java/src/java/main/org/jaxen/expr/iter/IterableNamespaceAxis.java
new file mode 100644
index 0000000..0b8d356
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/iter/IterableNamespaceAxis.java
@@ -0,0 +1,73 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/iter/IterableNamespaceAxis.java,v 1.7 2006/06/03 20:47:22 elharo Exp $
+ * $Revision: 1.7 $
+ * $Date: 2006/06/03 20:47:22 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: IterableNamespaceAxis.java,v 1.7 2006/06/03 20:47:22 elharo Exp $
+ */
+
+
+package org.jaxen.expr.iter;
+
+import java.util.Iterator;
+
+import org.jaxen.ContextSupport;
+import org.jaxen.UnsupportedAxisException;
+
+public class IterableNamespaceAxis extends IterableAxis
+{
+    /**
+     * 
+     */
+    private static final long serialVersionUID = -8022585664651357087L;
+
+    public IterableNamespaceAxis(int value)
+    {
+        super( value );
+    }
+
+    public Iterator iterator(Object contextNode,
+                             ContextSupport support) throws UnsupportedAxisException
+    {
+        return support.getNavigator().getNamespaceAxisIterator( contextNode );
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/iter/IterableParentAxis.java b/libjaxen-java/src/java/main/org/jaxen/expr/iter/IterableParentAxis.java
new file mode 100644
index 0000000..374315e
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/iter/IterableParentAxis.java
@@ -0,0 +1,73 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/iter/IterableParentAxis.java,v 1.7 2006/06/03 20:47:22 elharo Exp $
+ * $Revision: 1.7 $
+ * $Date: 2006/06/03 20:47:22 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: IterableParentAxis.java,v 1.7 2006/06/03 20:47:22 elharo Exp $
+ */
+
+
+package org.jaxen.expr.iter;
+
+import java.util.Iterator;
+
+import org.jaxen.ContextSupport;
+import org.jaxen.UnsupportedAxisException;
+
+public class IterableParentAxis extends IterableAxis
+{
+    /**
+     * 
+     */
+    private static final long serialVersionUID = -7521574185875636490L;
+
+    public IterableParentAxis(int value)
+    {
+        super( value );
+    }
+
+    public Iterator iterator(Object contextNode,
+                             ContextSupport support) throws UnsupportedAxisException
+    {
+        return support.getNavigator().getParentAxisIterator( contextNode );
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/iter/IterablePrecedingAxis.java b/libjaxen-java/src/java/main/org/jaxen/expr/iter/IterablePrecedingAxis.java
new file mode 100644
index 0000000..ae435d4
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/iter/IterablePrecedingAxis.java
@@ -0,0 +1,73 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/iter/IterablePrecedingAxis.java,v 1.7 2006/06/03 20:47:22 elharo Exp $
+ * $Revision: 1.7 $
+ * $Date: 2006/06/03 20:47:22 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: IterablePrecedingAxis.java,v 1.7 2006/06/03 20:47:22 elharo Exp $
+ */
+
+
+package org.jaxen.expr.iter;
+
+import java.util.Iterator;
+
+import org.jaxen.ContextSupport;
+import org.jaxen.UnsupportedAxisException;
+
+public class IterablePrecedingAxis extends IterableAxis
+{
+    /**
+     * 
+     */
+    private static final long serialVersionUID = 587333938258540052L;
+
+    public IterablePrecedingAxis(int value)
+    {
+        super( value );
+    }
+
+    public Iterator iterator(Object contextNode,
+                             ContextSupport support) throws UnsupportedAxisException
+    {
+        return support.getNavigator().getPrecedingAxisIterator( contextNode );
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/iter/IterablePrecedingSiblingAxis.java b/libjaxen-java/src/java/main/org/jaxen/expr/iter/IterablePrecedingSiblingAxis.java
new file mode 100644
index 0000000..81a5b20
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/iter/IterablePrecedingSiblingAxis.java
@@ -0,0 +1,73 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/iter/IterablePrecedingSiblingAxis.java,v 1.7 2006/06/03 20:47:22 elharo Exp $
+ * $Revision: 1.7 $
+ * $Date: 2006/06/03 20:47:22 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: IterablePrecedingSiblingAxis.java,v 1.7 2006/06/03 20:47:22 elharo Exp $
+ */
+
+
+package org.jaxen.expr.iter;
+
+import java.util.Iterator;
+
+import org.jaxen.ContextSupport;
+import org.jaxen.UnsupportedAxisException;
+
+public class IterablePrecedingSiblingAxis extends IterableAxis
+{
+    /**
+     * 
+     */
+    private static final long serialVersionUID = -3140080721715120745L;
+
+    public IterablePrecedingSiblingAxis(int value)
+    {
+        super( value );
+    }
+
+    public Iterator iterator(Object contextNode,
+                             ContextSupport support) throws UnsupportedAxisException
+    {
+        return support.getNavigator().getPrecedingSiblingAxisIterator( contextNode );
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/iter/IterableSelfAxis.java b/libjaxen-java/src/java/main/org/jaxen/expr/iter/IterableSelfAxis.java
new file mode 100644
index 0000000..115c4d6
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/iter/IterableSelfAxis.java
@@ -0,0 +1,73 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/expr/iter/IterableSelfAxis.java,v 1.7 2006/06/03 20:47:22 elharo Exp $
+ * $Revision: 1.7 $
+ * $Date: 2006/06/03 20:47:22 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: IterableSelfAxis.java,v 1.7 2006/06/03 20:47:22 elharo Exp $
+ */
+
+
+package org.jaxen.expr.iter;
+
+import java.util.Iterator;
+
+import org.jaxen.ContextSupport;
+import org.jaxen.UnsupportedAxisException;
+
+public class IterableSelfAxis extends IterableAxis
+{
+    /**
+     * 
+     */
+    private static final long serialVersionUID = 8292222516706760134L;
+
+    public IterableSelfAxis(int value)
+    {
+        super( value );
+    }
+
+    public Iterator iterator(Object contextNode,
+                             ContextSupport support) throws UnsupportedAxisException
+    {
+        return support.getNavigator().getSelfAxisIterator( contextNode );
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/iter/package.html b/libjaxen-java/src/java/main/org/jaxen/expr/iter/package.html
new file mode 100644
index 0000000..94b9194
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/iter/package.html
@@ -0,0 +1,13 @@
+<html>
+	<head>
+		<title>
+			org.jaxen.expr.iter.*
+		</title>
+	</head>
+
+	<body>
+		<p>
+			Axis iterator creation functors.
+		</p>
+	</body>
+</html>
diff --git a/libjaxen-java/src/java/main/org/jaxen/expr/package.html b/libjaxen-java/src/java/main/org/jaxen/expr/package.html
new file mode 100644
index 0000000..1130cf6
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/expr/package.html
@@ -0,0 +1,14 @@
+<html>
+	<head>
+		<title>
+			org.jaxen.expr.*
+		</title>
+	</head>
+
+	<body>
+		<p>
+			Interfaces and default implementations for
+			XPath expression components.
+		</p>
+	</body>
+</html>
diff --git a/libjaxen-java/src/java/main/org/jaxen/function/BooleanFunction.java b/libjaxen-java/src/java/main/org/jaxen/function/BooleanFunction.java
new file mode 100644
index 0000000..c81a310
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/function/BooleanFunction.java
@@ -0,0 +1,200 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/function/BooleanFunction.java,v 1.17 2006/02/05 21:47:41 elharo Exp $
+ * $Revision: 1.17 $
+ * $Date: 2006/02/05 21:47:41 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: BooleanFunction.java,v 1.17 2006/02/05 21:47:41 elharo Exp $
+ */
+
+
+package org.jaxen.function;
+
+import java.util.List;
+
+import org.jaxen.Context;
+import org.jaxen.Function;
+import org.jaxen.FunctionCallException;
+import org.jaxen.Navigator;
+
+/**
+ * <p>
+ * <b>4.3</b> <code><i>boolean</i> boolean(<i>object</i>)</code>
+ * </p>
+ * 
+ * <blockquote
+ * src="http://www.w3.org/TR/xpath#section-Boolean-Functions">
+ * <p>
+ * The <b><a href="http://www.w3.org/TR/xpath#function-boolean" target="_top">boolean</a></b>
+ * function converts its argument to a boolean as follows:
+ * </p>
+ * 
+ * <ul>
+ * 
+ * <li>
+ * <p>
+ * a number is true if and only if it is neither positive or negative
+ * zero nor NaN
+ * </p>
+ * </li>
+ * 
+ * <li>
+ * <p>
+ * a node-set is true if and only if it is non-empty
+ * </p>
+ * </li>
+ * 
+ * <li>
+ * <p>
+ * a string is true if and only if its length is non-zero
+ * </p>
+ * </li>
+ * 
+ * <li>
+ * 
+ * <p>
+ * an object of a type other than the four basic types is converted to a
+ * boolean in a way that is dependent on that type
+ * </p></li></ul>
+ * </blockquote>
+ * 
+ * @author bob mcwhirter (bob @ werken.com)
+ * @see <a href="http://www.w3.org/TR/xpath#function-boolean">Section 4.3 of the XPath Specification</a>
+ */
+public class BooleanFunction implements Function
+{
+
+
+    /**
+     * Create a new <code>BooleanFunction</code> object.
+     */
+    public BooleanFunction() {}
+    
+    /** Convert the argument to a <code>Boolean</code>
+     *
+     * @param context the context at the point in the
+     *         expression when the function is called
+     * @param args a list with exactly one item which will be converted to a 
+     *     <code>Boolean</code>
+     * 
+     * @return the result of evaluating the function; 
+     *     <code>Boolean.TRUE</code> or <code>Boolean.FALSE</code>
+     * 
+     * @throws FunctionCallException if <code>args</code> has more or less than one item
+     */
+    public Object call(Context context,
+                       List args) throws FunctionCallException
+    {
+        if ( args.size() == 1 )
+        {
+            return evaluate( args.get(0), context.getNavigator() );
+        }
+
+        throw new FunctionCallException("boolean() requires one argument");
+    }
+
+    /** 
+     * <p>Convert the argument <code>obj</code> to a <code>Boolean</code> 
+     * according to the following rules:</p>
+     *
+     * <ul>
+     * <li>Lists are false if they're empty; true if they're not.</li>
+     * <li>Booleans are false if they're false; true if they're true.</li>
+     * <li>Strings are false if they're empty; true if they're not.</li>
+     * <li>Numbers are false if they're 0 or NaN; true if they're not.</li>
+     * <li>All other objects are true.</li>
+     * </ul>
+     * 
+     * @param obj the object to convert to a boolean
+     * @param nav ignored
+     * 
+     * @return <code>Boolean.TRUE</code> or <code>Boolean.FALSE</code>
+     */
+    public static Boolean evaluate(Object obj, Navigator nav)
+    {
+        if ( obj instanceof List )
+        {
+            List list = (List) obj;
+            
+            // if it's an empty list, then we have a null node-set -> false            
+            if (list.size() == 0)
+            {
+                return Boolean.FALSE;
+            }
+     
+            // otherwise, unwrap the list and check the primitive
+            obj = list.get(0);
+        }
+        
+        // now check for primitive types
+        // otherwise a non-empty node-set is true
+
+        // if it's a Boolean, let it decide
+        if ( obj instanceof Boolean )
+        {
+            return (Boolean) obj;
+        }
+        // if it's a Number, != 0 -> true
+        else if ( obj instanceof Number )
+        {
+            double d = ((Number) obj).doubleValue();
+            if ( d == 0 || Double.isNaN(d) )
+            {
+                return Boolean.FALSE;
+            }
+            return Boolean.TRUE;
+        }
+        // if it's a String, "" -> false
+        else if ( obj instanceof String )
+        {
+            return ( ((String)obj).length() > 0
+                     ? Boolean.TRUE
+                     : Boolean.FALSE );
+        }
+        else 
+        {
+            // assume it's a node so that this node-set is non-empty 
+            // and so it's true
+            return ( obj != null ) ? Boolean.TRUE : Boolean.FALSE;
+        }
+
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/function/CeilingFunction.java b/libjaxen-java/src/java/main/org/jaxen/function/CeilingFunction.java
new file mode 100644
index 0000000..60c50d8
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/function/CeilingFunction.java
@@ -0,0 +1,131 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/function/CeilingFunction.java,v 1.11 2006/02/05 21:47:41 elharo Exp $
+ * $Revision: 1.11 $
+ * $Date: 2006/02/05 21:47:41 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: CeilingFunction.java,v 1.11 2006/02/05 21:47:41 elharo Exp $
+ */
+
+
+package org.jaxen.function;
+
+import java.util.List;
+
+import org.jaxen.Context;
+import org.jaxen.Function;
+import org.jaxen.FunctionCallException;
+import org.jaxen.Navigator;
+
+/**
+ *  <p><b>4.4</b> <code><i>number</i> ceiling(<i>number</i>)</code> 
+ * <blockquote src="http://www.w3.org/TR/xpath">
+ * <p>
+ *
+ * <p><q>The ceiling function returns the smallest 
+ *   (closest to negative infinity) number that is not less 
+ *   than the argument and that is an integer....If the argument 
+ *   is NaN, then NaN is returned. If the argument is positive infinity, 
+ *   then positive infinity is returned. If the argument is negative infinity, 
+ *   then negative infinity is returned. If the argument is positive zero, 
+ *   then positive zero is returned. 
+ *   If the argument is negative zero, then negative zero is returned. 
+ *   If the argument is less than zero, but greater than -1, 
+ *   then negative zero is returned.</q>
+ * </p>
+ * 
+ *  @author bob mcwhirter (bob @ werken.com)
+ *  
+ *  @see <a href="http://www.w3.org/TR/xpath#function-ceiling">Section 4.4 of the XPath Specification</a>
+ *  @see <a href="http://www.w3.org/1999/11/REC-xpath-19991116-errata/">XPath Specification Errata</a>
+ *  
+ */
+public class CeilingFunction implements Function
+{
+
+    /**
+     * Create a new <code>CeilingFunction</code> object.
+     */
+    public CeilingFunction() {}
+    
+    /** Returns the smallest integer greater than or equal to a number.
+     *
+     * @param context the context at the point in the
+     *         expression when the function is called
+     * @param args a list with exactly one item which will be converted to a 
+     *     <code>Double</code> as if by the XPath <code>number()</code> function
+     * 
+     * @return a <code>Double</code> containing the smallest integer greater than or equal
+     *     <code>args.get(0)</code>
+     * 
+     * @throws FunctionCallException if <code>args</code> has more or less than one item
+     */
+    public Object call(Context context,
+                       List args) throws FunctionCallException
+    {
+        if (args.size() == 1)
+        {
+            return evaluate( args.get(0),
+                             context.getNavigator() );
+        }
+
+        throw new FunctionCallException("ceiling() requires one argument.");
+    }
+
+    /** Returns the smallest integer greater than or equal to the argument.
+     * If necessary, the argument is first converted to a <code>Double</code>
+     * as if by the XPath <code>number()</code> function.
+     * 
+     * @param obj the object whose ceiling is returned
+     * @param nav ignored
+     * 
+     * @return a <code>Double</code> containing the smallest integer 
+     *     greater than or equal to <code>obj</code>
+     */
+    public static Double evaluate(Object obj,
+                                  Navigator nav)
+    {
+        Double value = NumberFunction.evaluate( obj,
+                                                nav );
+
+        return new Double( Math.ceil( value.doubleValue() ) );
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/function/ConcatFunction.java b/libjaxen-java/src/java/main/org/jaxen/function/ConcatFunction.java
new file mode 100644
index 0000000..c662298
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/function/ConcatFunction.java
@@ -0,0 +1,127 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/function/ConcatFunction.java,v 1.9 2006/02/05 21:47:41 elharo Exp $
+ * $Revision: 1.9 $
+ * $Date: 2006/02/05 21:47:41 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: ConcatFunction.java,v 1.9 2006/02/05 21:47:41 elharo Exp $
+ */
+
+
+package org.jaxen.function;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.jaxen.Context;
+import org.jaxen.Function;
+import org.jaxen.FunctionCallException;
+import org.jaxen.Navigator;
+
+/**
+ * <b>4.2</b> <code><i>string</i> concat(<i>string</i>,<i>string</i>,<i>string*</i>)</code> 
+ * <p>
+ * Concatenates its arguments and returns the resulting string.
+ * </p>
+ *  
+ *  @author bob mcwhirter (bob at werken.com)
+ * 
+ * @see <a href="http://www.w3.org/TR/xpath#function-concat">Section 4.2 of the XPath Specification</a>
+ */
+public class ConcatFunction implements Function
+{
+
+    /**
+     * Create a new <code>ConcatFunction</code> object.
+     */
+    public ConcatFunction() {}
+    
+    /** 
+     * Concatenates the arguments and returns the resulting string.
+     * Non-string items are first converted to strings as if by the 
+     * XPath <code>string()<code> function.
+     *
+     * @param context the context at the point in the
+     *         expression when the function is called
+     * @param args the list of strings to be concatenated
+     * 
+     * @return a <code>String</code> containing the concatenation of the items 
+     *     of <code>args</code>
+     * 
+     * @throws FunctionCallException if <code>args</code> has less than two items
+     */
+    public Object call(Context context,
+                       List args) throws FunctionCallException
+    {
+        if ( args.size() >= 2 )
+        {
+            return evaluate( args,
+                             context.getNavigator() );
+        }
+
+        throw new FunctionCallException("concat() requires at least two arguments");
+    }
+
+    /** 
+     * Converts each item in the list to a string and returns the 
+     * concatenation of these strings.
+     * If necessary, each item is first converted to a <code>String</code>
+     * as if by the XPath <code>string()</code> function.
+     * 
+     * @param list the items to be concatenated
+     * @param nav ignored
+     * 
+     * @return the concatenation of the arguments
+     */
+   public static String evaluate(List list,
+                                  Navigator nav)
+    {
+        StringBuffer result = new StringBuffer();
+        Iterator argIter = list.iterator();
+        while ( argIter.hasNext() )
+        {
+            result.append( StringFunction.evaluate( argIter.next(),
+                                                    nav ) );
+        }
+    
+        return result.toString();
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/function/ContainsFunction.java b/libjaxen-java/src/java/main/org/jaxen/function/ContainsFunction.java
new file mode 100644
index 0000000..857b06f
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/function/ContainsFunction.java
@@ -0,0 +1,136 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/function/ContainsFunction.java,v 1.10 2006/02/05 21:47:41 elharo Exp $
+ * $Revision: 1.10 $
+ * $Date: 2006/02/05 21:47:41 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: ContainsFunction.java,v 1.10 2006/02/05 21:47:41 elharo Exp $
+ */
+
+package org.jaxen.function;
+
+import java.util.List;
+
+import org.jaxen.Context;
+import org.jaxen.Function;
+import org.jaxen.FunctionCallException;
+import org.jaxen.Navigator;
+
+/**
+ *  <p><b>4.2</b> <code><i>boolean</i> contains(<i>string</i>,<i>string</i>)</code></p>
+ *  
+ * <blockquote src="http://www.w3.org/TR/xpath">
+ * The <b>contains</b> function returns true if the first argument 
+ * string contains the second argument string, and otherwise returns false.
+ * </blockquote>
+ * 
+ * @author bob mcwhirter (bob @ werken.com)
+ * 
+ * @see <a href="http://www.w3.org/TR/xpath#function-contains">Section 4.2 of the XPath Specification</a>
+ */
+public class ContainsFunction implements Function
+{
+
+    /**
+     * Create a new <code>ContainsFunction</code> object.
+     */
+    public ContainsFunction() {}
+    
+    /** 
+     * <p>
+     *  Returns true if the string-value of the 
+     *  first item in <code>args</code> contains string-value of the second 
+     *  item; false otherwise.
+     *  If necessary one or both items are converted to a string as if by the XPath
+     *  <code>string()</code> function.
+     * </p>
+     *
+     * @param context the context at the point in the
+     *         expression when the function is called
+     * @param args a list containing exactly two items
+     * 
+     * @return the result of evaluating the function; 
+     *     <code>Boolean.TRUE</code> or <code>Boolean.FALSE</code>
+     * 
+     * @throws FunctionCallException if <code>args</code> does not have exactly two items
+     */
+    public Object call(Context context,
+                       List args) throws FunctionCallException
+    {
+        if (args.size() == 2)
+        {
+            return evaluate(args.get(0),
+                            args.get(1),
+                            context.getNavigator() );
+        }
+
+        throw new FunctionCallException("contains() requires two arguments.");
+    }
+
+    /** 
+     * <p>Returns true if the first string contains the second string; false otherwise.
+     * If necessary one or both arguments are converted to a string as if by the XPath
+     * <code>string()</code> function.
+     * </p>
+     * 
+     * @param strArg the containing string
+     * @param matchArg the contained string
+     * @param nav used to calculate the string-values of the first two arguments
+     * 
+     * @return <code>Boolean.TRUE</code> if true if the first string contains 
+     *     the second string; <code>Boolean.FALSE</code> otherwise.
+     */
+    public static Boolean evaluate(Object strArg,
+                                   Object matchArg,
+                                   Navigator nav) 
+    {
+        String str   = StringFunction.evaluate( strArg,
+                                                nav );
+
+        String match = StringFunction.evaluate( matchArg,
+                                                nav );
+
+        return ( ( str.indexOf(match) >= 0)
+                 ? Boolean.TRUE
+                 : Boolean.FALSE
+                 );
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/function/CountFunction.java b/libjaxen-java/src/java/main/org/jaxen/function/CountFunction.java
new file mode 100644
index 0000000..11fc295
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/function/CountFunction.java
@@ -0,0 +1,117 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/function/CountFunction.java,v 1.14 2006/02/05 21:47:41 elharo Exp $
+ * $Revision: 1.14 $
+ * $Date: 2006/02/05 21:47:41 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: CountFunction.java,v 1.14 2006/02/05 21:47:41 elharo Exp $
+ */
+
+package org.jaxen.function;
+
+import java.util.List;
+
+import org.jaxen.Context;
+import org.jaxen.Function;
+import org.jaxen.FunctionCallException;
+
+/**
+ *  <p><b>4.1</b> <code><i>number</i> count(<i>node-set</i>)</code></p> 
+ *  
+ * <blockquote src="http://www.w3.org/TR/xpath#function-count">
+ * The <b>count</b> function returns the number of nodes in the argument node-set.
+ * </blockquote>
+ * @author bob mcwhirter (bob @ werken.com)
+ * @see <a href="http://www.w3.org/TR/xpath#function-count">Section 4.1 of the XPath Specification</a>
+ */
+public class CountFunction implements Function
+{
+
+    /**
+     * Create a new <code>CountFunction</code> object.
+     */
+    public CountFunction() {}
+    
+    /**
+     * <p>
+     * Returns the number of nodes in the specified node-set.
+     * </p>
+     * @param context ignored
+     * @param args the function arguments
+     * 
+     * @return a <code>Double</code> giving the integral number of items in the first argument
+     * 
+     * @throws FunctionCallException if args does not have exactly one 
+     *     item; or that item is not a <code>List</code>
+     */
+    public Object call(Context context,
+                       List args) throws FunctionCallException
+    {
+        if (args.size() == 1)
+        {
+            return evaluate( args.get(0) );
+        }
+
+        throw new FunctionCallException( "count() requires one argument." );
+    }
+
+    /**
+     * <p>
+     * Returns the number of nodes in the specified node-set.
+     * </p>
+     * 
+     * @param obj a <code>List</code> of nodes
+     * @return the integral number of items in the list
+     * @throws FunctionCallException if obj is not a <code>List</code>
+     */
+    public static Double evaluate(Object obj) throws FunctionCallException
+    {
+      
+        if (obj instanceof List)
+        {
+            return new Double( ((List) obj).size() );
+        }
+      
+        throw new FunctionCallException("count() function can only be used for node-sets");
+        
+    }
+    
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/function/FalseFunction.java b/libjaxen-java/src/java/main/org/jaxen/function/FalseFunction.java
new file mode 100644
index 0000000..d8c9267
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/function/FalseFunction.java
@@ -0,0 +1,104 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/function/FalseFunction.java,v 1.11 2006/02/05 21:47:41 elharo Exp $
+ * $Revision: 1.11 $
+ * $Date: 2006/02/05 21:47:41 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: FalseFunction.java,v 1.11 2006/02/05 21:47:41 elharo Exp $
+ */
+
+
+package org.jaxen.function;
+
+import java.util.List;
+
+import org.jaxen.Context;
+import org.jaxen.Function;
+import org.jaxen.FunctionCallException;
+
+/**
+ * <p><b>4.3</b> <code><i>boolean</i> false()</code> 
+ * 
+ * <p>Returns false.</p>
+ * 
+ * @author bob mcwhirter (bob @ werken.com)
+ * 
+ * @see <a href="http://www.w3.org/TR/xpath#function-false">Section 4.3 of the XPath Specification</a>
+ */
+public class FalseFunction implements Function
+{
+
+    /**
+     * Create a new <code>FalseFunction</code> object.
+     */
+    public FalseFunction() {}
+    
+    /** Returns <code>Boolean.FALSE</code>
+     *
+     * @param context the context at the point in the
+     *         expression when the function is called
+     * @param args an empty list
+     * 
+     * @return <code>Boolean.FALSE</code>
+     * 
+     * @throws FunctionCallException if <code>args</code> is not empty
+     */
+    public Object call(Context context,
+                       List args) throws FunctionCallException
+    {
+        if (args.size() == 0)
+        {
+            return evaluate();
+        }
+
+        throw new FunctionCallException( "false() requires no arguments." );
+    }
+
+    /**
+     * Returns false.
+     * 
+     * @return <code>Boolean.FALSE</code>
+     */
+    public static Boolean evaluate()
+    {
+        return Boolean.FALSE;
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/function/FloorFunction.java b/libjaxen-java/src/java/main/org/jaxen/function/FloorFunction.java
new file mode 100644
index 0000000..551bd00
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/function/FloorFunction.java
@@ -0,0 +1,129 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/function/FloorFunction.java,v 1.11 2006/02/05 21:47:41 elharo Exp $
+ * $Revision: 1.11 $
+ * $Date: 2006/02/05 21:47:41 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: FloorFunction.java,v 1.11 2006/02/05 21:47:41 elharo Exp $
+ */
+
+
+package org.jaxen.function;
+
+import java.util.List;
+
+import org.jaxen.Context;
+import org.jaxen.Function;
+import org.jaxen.FunctionCallException;
+import org.jaxen.Navigator;
+
+/**
+ * <p><b>4.4</b> <code><i>number</i> floor(<i>number</i>)</code></p> 
+ * 
+ * 
+ * <blockquote src="http://www.w3.org/TR/xpath">
+ * The floor function returns the largest (closest to positive infinity) 
+ * number that is not greater than the argument and that is an integer....
+ * If the argument is NaN, then NaN is returned. 
+ * If the argument is positive infinity, then positive infinity is returned. 
+ * If the argument is negative infinity, then negative infinity is returned. 
+ * If the argument is positive zero, then positive zero is returned. 
+ * If the argument is negative zero, then negative zero is returned. 
+ * If the argument is greater than zero, but less than 1, then positive zero is returned.
+ * </blockquote>
+ * 
+ * @author bob mcwhirter (bob @ werken.com)
+ * 
+ * @see <a href="http://www.w3.org/TR/xpath#function-floor" target="_top">Section 4.4 of the XPath Specification</a>
+ * @see <a href="http://www.w3.org/1999/11/REC-xpath-19991116-errata/"  target="_top">XPath Errata</a>
+ */
+public class FloorFunction implements Function
+{
+
+    /**
+     * Create a new <code>FloorFunction</code> object.
+     */
+    public FloorFunction() {}
+    
+    /** Returns the largest integer less than or equal to a number.
+     *
+     * @param context the context at the point in the
+     *         expression when the function is called
+     * @param args a list with exactly one item which will be converted to a 
+     *     <code>Double</code> as if by the XPath <code>number()</code> function
+     * 
+     * @return a <code>Double</code> containing the largest integer less than or equal
+     *     to <code>args.get(0)</code>
+     * 
+     * @throws FunctionCallException if <code>args</code> has more or less than one item
+     */
+    public Object call(Context context,
+                       List args) throws FunctionCallException
+    {
+        if (args.size() == 1)
+        {
+            return evaluate( args.get(0),
+                             context.getNavigator() );
+        }
+
+        throw new FunctionCallException( "floor() requires one argument." );
+    }
+
+    /** Returns the largest integer less than or equal to the argument.
+     * If necessary, the argument is first converted to a <code>Double</code>
+     * as if by the XPath <code>number()</code> function.
+     * 
+     * @param obj the object whose floor is returned
+     * @param nav ignored
+     * 
+     * @return a <code>Double</code> containing the largest integer less 
+     *     than or equal to <code>obj</code>
+     */
+    public static Double evaluate(Object obj,
+                                  Navigator nav)
+    {
+        Double value = NumberFunction.evaluate( obj,
+                                                nav );
+
+        return new Double( Math.floor( value.doubleValue() ) );
+    }
+}
+
diff --git a/libjaxen-java/src/java/main/org/jaxen/function/IdFunction.java b/libjaxen-java/src/java/main/org/jaxen/function/IdFunction.java
new file mode 100644
index 0000000..4638f17
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/function/IdFunction.java
@@ -0,0 +1,159 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/function/IdFunction.java,v 1.13 2006/02/05 21:47:41 elharo Exp $
+ * $Revision: 1.13 $
+ * $Date: 2006/02/05 21:47:41 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: IdFunction.java,v 1.13 2006/02/05 21:47:41 elharo Exp $
+ */
+
+package org.jaxen.function;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.StringTokenizer;
+
+import org.jaxen.Context;
+import org.jaxen.Function;
+import org.jaxen.FunctionCallException;
+import org.jaxen.Navigator;
+
+/**
+ * <p><b>4.1</b> <code><i>node-set</i> id(<i>object</i>)</code> </p>
+ *  
+ * <p>The <b>id</b> function returns a <code>List</code>
+ * of all the elements in the context document that have an ID
+ * matching one of a specified list of IDs. How an attribute is determined
+ * to be of type ID depends on the navigator, but it normally requires that
+ * the attribute be declared to have type ID in the DTD. 
+ * </p>
+ * 
+ * <p>
+ * There should be no more than one element in any document with a 
+ * certain ID. However, if there are multiple such elements--i.e. if 
+ * there are duplicate IDs--then this function selects only the first element 
+ * in document order with the specified ID. 
+ * </p>
+ * 
+ * @author Erwin Bolwidt (ejb @ klomp.org)
+ * @author J\u00e9r\u00f4me N\u00e8gre (jerome.negre @ e-xmlmedia.fr)
+ * 
+ * @see <a href="http://www.w3.org/TR/xpath#function-id" target="_top">Section 4.1 of the XPath Specification</a>
+ */
+public class IdFunction implements Function
+{
+
+    /**
+     * Create a new <code>IdFunction</code> object.
+     */
+    public IdFunction() {}
+    
+    /** 
+     * Returns a list of the nodes with the specified IDs.
+     *
+     * @param context the context at the point in the
+     *         expression when the function is called
+     * @param args a list with exactly one item which is either a string
+     *     a node-set
+     * 
+     * @return a <code>List</code> containing the first node in document 
+     *     with each of the specified IDs; or 
+     *     an empty list if there are no such nodes
+     * 
+     * @throws FunctionCallException if <code>args</code> has more or less than one item
+     */
+    public Object call(Context context, List args) throws FunctionCallException
+    {
+        if ( args.size() == 1 ) {
+            return evaluate( context.getNodeSet(),
+                             args.get(0), context.getNavigator() );
+        }
+
+        throw new FunctionCallException( "id() requires one argument" );
+    }
+
+    /** 
+     * Returns a list of the nodes with the specified IDs.
+     * 
+     * @param contextNodes the context node-set. The first item in this list
+     *     determines the document in which the search is performed.
+     * @param arg the ID or IDs to search for
+     * @param nav the navigator used to calculate string-values and search
+     *     by ID
+     * 
+     * @return a <code>List</code> containing the first node in document 
+     *     with each of the specified IDs; or 
+     *     an empty list if there are no such nodes
+     * 
+     */
+    public static List evaluate(List contextNodes, Object arg, Navigator nav)
+    {
+        if (contextNodes.size() == 0) return Collections.EMPTY_LIST;
+      
+        List nodes = new ArrayList();
+
+        Object contextNode = contextNodes.get(0);
+
+        if (arg instanceof List) {
+            Iterator iter = ((List)arg).iterator();
+            while (iter.hasNext()) {
+                String id = StringFunction.evaluate(iter.next(), nav);
+                nodes.addAll( evaluate( contextNodes, id, nav ) );
+            }
+        } 
+        else {
+            String ids = StringFunction.evaluate(arg, nav);
+            StringTokenizer tok = new StringTokenizer(ids, " \t\n\r");
+            while (tok.hasMoreTokens()) {
+                String id = tok.nextToken();
+                Object node = nav.getElementById(contextNode, id);
+                if (node != null) {
+                    nodes.add(node);
+                }
+            }
+        }
+        return nodes;
+    }
+    
+}
+
diff --git a/libjaxen-java/src/java/main/org/jaxen/function/LangFunction.java b/libjaxen-java/src/java/main/org/jaxen/function/LangFunction.java
new file mode 100644
index 0000000..2f24c52
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/function/LangFunction.java
@@ -0,0 +1,194 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/function/LangFunction.java,v 1.13 2006/02/05 21:47:41 elharo Exp $
+ * $Revision: 1.13 $
+ * $Date: 2006/02/05 21:47:41 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: LangFunction.java,v 1.13 2006/02/05 21:47:41 elharo Exp $
+ */
+
+
+package org.jaxen.function;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.jaxen.Context;
+import org.jaxen.Function;
+import org.jaxen.FunctionCallException;
+import org.jaxen.Navigator;
+import org.jaxen.UnsupportedAxisException;
+
+/**
+ * <p>
+ * <b>4.3</b> <code><i>boolean</i> lang(<i>string</i>)</code>
+ * </p>
+ * 
+ * <blockquote src="http://www.w3.org/TR/xpath#function-lang">
+ * <p>
+ * The <b>lang</b> function returns true or false depending on whether
+ * the language of the context node as specified by
+ * <code>xml:lang</code> attributes is the same as or is a sublanguage
+ * of the language specified by the argument string. The language of the
+ * context node is determined by the value of the <code>xml:lang</code>
+ * 
+ * attribute on the context node, or, if the context node has no
+ * <code>xml:lang</code> attribute, by the value of the
+ * <code>xml:lang</code> attribute on the nearest ancestor of the
+ * context node that has an <code>xml:lang</code> attribute. If there
+ * is no such attribute, then <b><a href="#function-lang">lang</a></b>
+ * returns false. If there is such an attribute, then <b><a
+ * href="#function-lang">lang</a></b> returns true if the attribute
+ * value is equal to the argument ignoring case, or if there is some
+ * suffix starting with <code>-</code> such that the attribute value
+ * is equal to the argument ignoring that suffix of the attribute value
+ * and ignoring case. For example, <code>lang("en")</code> would
+ * return true if the context node is any of these five elements:
+ * </p>
+ * 
+ * <pre>
+ *  <para xml:lang="en"/>
+ *  <div xml:lang="en"><para/></div>
+ *  <para xml:lang="EN"/>
+ *  <para xml:lang="en-us"/>
+ * </pre>
+ * 
+ * </blockquote>
+ * 
+ * @author Attila Szegedi (szegedia @ freemail.hu)
+ * @see <a href="http://www.w3.org/TR/xpath#function-lang"
+ *      target="_top">XPath Specification</a>
+ */
+public class LangFunction implements Function
+{
+    private static final String LANG_LOCALNAME = "lang";
+    private static final String XMLNS_URI = 
+        "http://www.w3.org/XML/1998/namespace";
+    
+
+    /**
+     * Create a new <code>LangFunction</code> object.
+     */
+    public LangFunction() {}
+    
+    
+    /**
+     * <p>
+     * Determines whether or not the context node is written in the language specified
+     * by the XPath string-value of <code>args.get(0)</code>,
+     * as determined by the nearest <code>xml:lang</code> attribute in scope. 
+     * </p>
+     * 
+     * @param context the context in which to evaluate the <code>lang()</code> function
+     * @param args the arguments to the lang function
+     * @return a <code>Boolean</code> indicating whether the context node is written in
+     *     the specified language
+     * @throws FunctionCallException if <code>args</code> does not have length one
+     * 
+     */
+    public Object call(Context context,
+                       List args) throws FunctionCallException
+    {
+        if (args.size() != 1) {
+            throw new FunctionCallException("lang() requires exactly one argument.");   
+        }
+        
+        Object arg = args.get(0);
+            
+        try {
+            return evaluate(context.getNodeSet(), arg, context.getNavigator() );
+        }
+        catch(UnsupportedAxisException e) {
+            throw new FunctionCallException("Can't evaluate lang()", 
+                                                 e);
+        }
+       
+    }
+
+    private static Boolean evaluate(List contextNodes, Object lang, Navigator nav)
+      throws UnsupportedAxisException
+    {
+        return evaluate(contextNodes.get(0), 
+            StringFunction.evaluate(lang, nav), nav)
+            ? Boolean.TRUE : Boolean.FALSE;
+    }
+
+    private static boolean evaluate(Object node, String lang, Navigator nav)
+      throws UnsupportedAxisException
+    {
+        
+        Object element = node;
+        if (! nav.isElement(element)) {
+            element = nav.getParentNode(node);
+        }
+        while (element != null && nav.isElement(element)) 
+        {
+            Iterator attrs = nav.getAttributeAxisIterator(element);
+            while(attrs.hasNext())
+            {
+                Object attr = attrs.next();
+                if(LANG_LOCALNAME.equals(nav.getAttributeName(attr)) && 
+                   XMLNS_URI.equals(nav.getAttributeNamespaceUri(attr)))
+                {
+                    return 
+                        isSublang(nav.getAttributeStringValue(attr), lang);
+                }
+            }
+            element = nav.getParentNode(element);
+        }
+        return false;
+    }
+    
+    private static boolean isSublang(String sublang, String lang)
+    {
+        if(sublang.equalsIgnoreCase(lang))
+        {
+            return true;
+        }
+        int ll = lang.length();
+        return 
+            sublang.length() > ll && 
+            sublang.charAt(ll) == '-' && 
+            sublang.substring(0, ll).equalsIgnoreCase(lang);
+    }
+    
+}
+
diff --git a/libjaxen-java/src/java/main/org/jaxen/function/LastFunction.java b/libjaxen-java/src/java/main/org/jaxen/function/LastFunction.java
new file mode 100644
index 0000000..d6f7f8c
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/function/LastFunction.java
@@ -0,0 +1,114 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/function/LastFunction.java,v 1.10 2006/02/05 21:47:41 elharo Exp $
+ * $Revision: 1.10 $
+ * $Date: 2006/02/05 21:47:41 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: LastFunction.java,v 1.10 2006/02/05 21:47:41 elharo Exp $
+ */
+
+package org.jaxen.function;
+
+import java.util.List;
+
+import org.jaxen.Context;
+import org.jaxen.Function;
+import org.jaxen.FunctionCallException;
+
+/**
+ * <p><b>4.1</b> <code><i>number</i> last()</code> </p>
+ * 
+ * <blockquote src="http://www.w3.org/TR/xpath#function-last">
+ * The <b>last</b> function returns a number equal to 
+ * the context size from the expression evaluation context.
+ * </blockquote>
+ * 
+ * @author bob mcwhirter (bob @ werken.com)
+ * @see <a href="http://www.w3.org/TR/xpath#function-last" target="_top">Section 4.1 of the XPath Specification</a>
+ */
+public class LastFunction implements Function
+{
+
+    /**
+     * Create a new <code>LastFunction</code> object.
+     */
+    public LastFunction() {}
+    
+    /**
+     * Returns the number of nodes in the context node-set.
+     * 
+     * @param context the context at the point in the
+     *         expression where the function is called
+     * @param args an empty list
+     * 
+     * @return a <code>Double</code> containing the context size
+     * 
+     * @throws FunctionCallException if <code>args</code> is not empty
+     * 
+     * @see Context#getSize()
+     */
+    public Object call(Context context,
+                       List args) throws FunctionCallException
+    {
+        if (args.size() == 0)
+        {
+            return evaluate( context );
+        }
+      
+        throw new FunctionCallException( "last() requires no arguments." );
+    }
+
+    /**
+     * Returns the number of nodes in the context node-set.
+     * 
+     * @param context the context at the point in the
+     *         expression where the function is called
+     * 
+     * @return the context size
+     * 
+     * @see Context#getSize()
+     */
+    public static Double evaluate(Context context)
+    {
+        return new Double( context.getSize() );
+    }
+    
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/function/LocalNameFunction.java b/libjaxen-java/src/java/main/org/jaxen/function/LocalNameFunction.java
new file mode 100644
index 0000000..be05a77
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/function/LocalNameFunction.java
@@ -0,0 +1,170 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/function/LocalNameFunction.java,v 1.14 2006/02/05 21:47:41 elharo Exp $
+ * $Revision: 1.14 $
+ * $Date: 2006/02/05 21:47:41 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: LocalNameFunction.java,v 1.14 2006/02/05 21:47:41 elharo Exp $
+ */
+
+
+package org.jaxen.function;
+
+import java.util.List;
+
+import org.jaxen.Context;
+import org.jaxen.Function;
+import org.jaxen.FunctionCallException;
+import org.jaxen.Navigator;
+
+/**
+ *   <p><b>4.1</b> <code><i>string</i> local-name(<i>node-set?</i>)</code></p> 
+ *  
+ * 
+ * <blockquote src="http://www.w3.org/TR/xpath">
+ * The <b>local-name</b> function returns the local part of the 
+ * expanded-name of the node in the argument node-set that is first in document order. 
+ * If the argument node-set is empty or the first node has no expanded-name, an 
+ * empty string is returned. If the argument is omitted, it defaults to a node-set with the context node as its only member.
+ *
+ * </blockquote>
+ * 
+ * @author bob mcwhirter (bob @ werken.com)
+ * @see <a href="http://www.w3.org/TR/xpath#function-local-name" target="_top">Section 4.1 of the XPath Specification</a>
+ */
+public class LocalNameFunction implements Function
+{
+    
+    /**
+     * Create a new <code>LocalNameFunction</code> object.
+     */
+    public LocalNameFunction() {}
+    
+    /**
+     * Returns the local-name of the specified node or the context node if 
+     * no arguments are provided.
+     * 
+     * @param context the context at the point in the
+     *         expression where the function is called
+     * @param args a <code>List</code> containing zero or one items
+     * 
+     * @return a <code>String</code> containing the local-name
+     * 
+     * @throws FunctionCallException if <code>args</code> has more than one item
+     */
+    public Object call(Context context,
+                       List args) throws FunctionCallException
+    {
+        if ( args.size() == 0 )
+        {
+            return evaluate( context.getNodeSet(),
+                             context.getNavigator() ); 
+        }
+
+        if ( args.size() == 1 )
+        {
+            return evaluate( args,
+                             context.getNavigator() );
+        }
+
+        throw new FunctionCallException( "local-name() requires zero or one argument." );
+    }
+
+    /**
+     * Returns the local-name of <code>list.get(0)</code>
+     * 
+     * @param list a list of nodes
+     * @param nav the <code>Navigator</code> used to retrieve the local name
+     * 
+     * @return the local-name of <code>list.get(0)</code>
+     * 
+     * @throws FunctionCallException if <code>list.get(0)</code> is not a node
+     */
+    public static String evaluate(List list,
+                                  Navigator nav) throws FunctionCallException
+    {
+        if ( ! list.isEmpty() )
+        {            
+            Object first = list.get(0);
+
+            if (first instanceof List)
+            {
+                return evaluate( (List) first,
+                                 nav );
+            }
+            else if ( nav.isElement( first ) )
+            {
+                return nav.getElementName( first );
+            }
+            else if ( nav.isAttribute( first ) )
+            {
+                return nav.getAttributeName( first );
+            }
+            else if ( nav.isProcessingInstruction( first ) )
+            {
+                return nav.getProcessingInstructionTarget( first );
+            }
+            else if ( nav.isNamespace( first ) )
+            {
+                return nav.getNamespacePrefix( first );
+            }
+            else if ( nav.isDocument( first ) )
+            {
+                return "";
+            }
+            else if ( nav.isComment( first ) )
+            {
+                return "";
+            }
+            else if ( nav.isText( first ) )
+            {
+                return "";
+            }
+            else {
+                throw new FunctionCallException("The argument to the local-name function must be a node-set");   
+            }
+        }
+
+        return "";
+    }
+    
+}
+
diff --git a/libjaxen-java/src/java/main/org/jaxen/function/NameFunction.java b/libjaxen-java/src/java/main/org/jaxen/function/NameFunction.java
new file mode 100644
index 0000000..8d1fa1f
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/function/NameFunction.java
@@ -0,0 +1,175 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/function/NameFunction.java,v 1.11 2006/02/05 21:47:41 elharo Exp $
+ * $Revision: 1.11 $
+ * $Date: 2006/02/05 21:47:41 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: NameFunction.java,v 1.11 2006/02/05 21:47:41 elharo Exp $
+ */
+
+
+package org.jaxen.function;
+
+import java.util.List;
+
+import org.jaxen.Context;
+import org.jaxen.Function;
+import org.jaxen.FunctionCallException;
+import org.jaxen.Navigator;
+
+/**
+ * <p><b>4.1</b> <code><i>string</i> name(<i>node-set?</i>)</code> </p>
+ *  
+ * 
+ * <blockquote src="http://www.w3.org/TR/xpath">
+ * The <b>name</b> function returns a string containing a QName representing 
+ * the expanded-name of the node in the argument node-set that is first in document order. 
+ * The QName must represent the expanded-name with respect to the namespace declarations 
+ * in effect on the node whose expanded-name is being represented. Typically, this will 
+ * be the QName that occurred in the XML source....If 
+ * the argument node-set is empty or the first node has 
+ * no expanded-name, an empty string is returned. 
+ * If the argument it omitted, it defaults to a node-set with the context node as its only member.
+ * </blockquote>
+ * 
+ * @author bob mcwhirter (bob @ werken.com)
+ * 
+ * @see <a href="http://www.w3.org/TR/xpath#function-name" target="_top">Section 4.1 of the XPath Specification</a>
+ */
+public class NameFunction implements Function
+{
+    
+    
+    /**
+     * Create a new <code>NameFunction</code> object.
+     */
+    public NameFunction() {}
+    
+    /**
+     * Returns the name of the specified node or the name of the context node if 
+     * no arguments are provided.
+     * 
+     * @param context the context at the point in the
+     *         expression where the function is called
+     * @param args a <code>List</code> containing zero or one items
+     * 
+     * @return a <code>String</code> containing the name
+     * 
+     * @throws FunctionCallException if <code>args</code> has more than one item
+     */
+    public Object call(Context context,
+                       List args) throws FunctionCallException
+    {
+        if ( args.size() == 0 )
+        {
+            return evaluate( context.getNodeSet(),
+                             context.getNavigator() );
+        }
+
+        if ( args.size() == 1 )
+        {
+            return evaluate( args,
+                             context.getNavigator() );
+        }
+
+        throw new FunctionCallException( "name() requires zero or one argument." );
+    }
+
+    /**
+     * Returns the name of <code>list.get(0)</code>
+     * 
+     * @param list a list of nodes
+     * @param nav the <code>Navigator</code> used to retrieve the name
+     * 
+     * @return the name of <code>list.get(0)</code>
+     * 
+     * @throws FunctionCallException if <code>list.get(0)</code> is not a node
+     */
+    public static String evaluate(List list,
+                                  Navigator nav) throws FunctionCallException
+    {
+        if ( ! list.isEmpty() )
+        {            
+            Object first = list.get(0);
+
+            if (first instanceof List)
+            {
+                return evaluate( (List) first,
+                                 nav );
+            }
+            else if ( nav.isElement( first ) )
+            {
+                return nav.getElementQName( first );
+            }
+            else if ( nav.isAttribute( first ) )
+            {
+                return nav.getAttributeQName( first );
+            }
+            else if ( nav.isProcessingInstruction( first ) )
+            {
+                return nav.getProcessingInstructionTarget( first );
+            }
+            else if ( nav.isNamespace( first ) )
+            {
+                return nav.getNamespacePrefix( first );
+            }
+            else if ( nav.isDocument( first ) )
+            {
+                return "";
+            }
+            else if ( nav.isComment( first ) )
+            {
+                return "";
+            }
+            else if ( nav.isText( first ) )
+            {
+                return "";
+            }
+            else {
+                throw new FunctionCallException("The argument to the name function must be a node-set");   
+            }
+        }
+
+        return "";
+
+    }
+    
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/function/NamespaceUriFunction.java b/libjaxen-java/src/java/main/org/jaxen/function/NamespaceUriFunction.java
new file mode 100644
index 0000000..e80f10b
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/function/NamespaceUriFunction.java
@@ -0,0 +1,188 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/function/NamespaceUriFunction.java,v 1.13 2006/02/05 21:47:41 elharo Exp $
+ * $Revision: 1.13 $
+ * $Date: 2006/02/05 21:47:41 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: NamespaceUriFunction.java,v 1.13 2006/02/05 21:47:41 elharo Exp $
+ */
+
+
+package org.jaxen.function;
+
+import java.util.List;
+
+import org.jaxen.Context;
+import org.jaxen.Function;
+import org.jaxen.FunctionCallException;
+import org.jaxen.Navigator;
+
+/**
+ * <p>
+ * <b>4.1</b>
+ * <code><i>string</i> namespace-uri(<i>node-set?</i>)</code>
+ * </p>
+ * 
+ * <blockquote src="http://www.w3.org/TR/xpath">
+ * <p>
+ * The <b>namespace-uri</b>
+ * function returns the namespace URI of the <a
+ * href="http://www.w3.org/TR/xpath#dt-expanded-name" target="_top">expanded-name</a> of the node in the
+ * argument node-set that is first in <a
+ * href="http://www.w3.org/TR/xpath#dt-document-order" target="_top">document order</a>. If the argument
+ * node-set is empty, the first node has no <a
+ * href="http://www.w3.org/TR/xpath#dt-expanded-name" target="_top">expanded-name</a>, or the namespace URI of
+ * the <a href="http://www.w3.org/TR/xpath#dt-expanded-name" target="_top">expanded-name</a> is null, an empty
+ * string is returned. If the argument is omitted, it defaults to a
+ * node-set with the context node as its only member.
+ * </p>
+ * 
+ * <blockquote> <b>NOTE: </b>The string returned by the <b>namespace-uri</b> function will
+ * be empty except for element nodes and attribute nodes.</blockquote>
+ * 
+ * </blockquote>
+ * 
+ * @author bob mcwhirter (bob @ werken.com)
+ * @see <a href="http://www.w3.org/TR/xpath#function-namespace-uri"
+ *      target="_top">Section 4.1 of the XPath Specification</a>
+ */
+public class NamespaceUriFunction implements Function
+{
+
+    /**
+     * Create a new <code>NamespaceUriFunction</code> object.
+     */
+    public NamespaceUriFunction() {}
+
+    /**
+     * Returns the namespace URI of the specified node or the namespace URI of the context node if 
+     * no arguments are provided.
+     * 
+     * @param context the context at the point in the
+     *         expression where the function is called
+     * @param args a <code>List</code> containing zero or one items
+     * 
+     * @return a <code>String</code> containing the namespace URI
+     * 
+     * @throws FunctionCallException if <code>args</code> has more than one item
+     */
+    public Object call(Context context,
+                       List args) throws FunctionCallException
+    {
+        if (args.size() == 0)
+        {
+            return evaluate( context.getNodeSet(),
+                             context.getNavigator() );
+        }
+
+        if ( args.size() == 1 )
+        {
+            return evaluate( args,
+                             context.getNavigator() );
+        }
+
+        throw new FunctionCallException( "namespace-uri() requires zero or one argument." );
+    }
+
+    /**
+     * Returns the namespace URI of <code>list.get(0)</code>
+     * 
+     * @param list a list of nodes
+     * @param nav the <code>Navigator</code> used to retrieve the namespace
+     * 
+     * @return the namespace URI of <code>list.get(0)</code>
+     * 
+     * @throws FunctionCallException if <code>list.get(0)</code> is not a node
+     */
+    public static String evaluate(List list,
+                                  Navigator nav) throws FunctionCallException
+    {
+        if ( ! list.isEmpty() )
+        {
+            Object first = list.get(0);
+
+            if ( first instanceof List )
+            {
+                return evaluate( (List) first,
+                                 nav );
+            }
+            else if ( nav.isElement( first ) )
+            {
+                return nav.getElementNamespaceUri( first );
+            }
+            else if ( nav.isAttribute( first ) )
+            {
+                String uri = nav.getAttributeNamespaceUri( first );
+                if (uri == null) return "";
+                return uri;
+            }
+            else if ( nav.isProcessingInstruction( first ) )
+            {
+                return "";
+            }
+            else if ( nav.isNamespace( first ) )
+            {
+                return "";
+            }
+            else if ( nav.isDocument( first ) )
+            {
+                return "";
+            }
+            else if ( nav.isComment( first ) )
+            {
+                return "";
+            }
+            else if ( nav.isText( first ) )
+            {
+                return "";
+            }
+            else {
+                throw new FunctionCallException(
+                  "The argument to the namespace-uri function must be a node-set");   
+            }
+
+        }
+
+        return "";
+
+    }
+}
+
diff --git a/libjaxen-java/src/java/main/org/jaxen/function/NormalizeSpaceFunction.java b/libjaxen-java/src/java/main/org/jaxen/function/NormalizeSpaceFunction.java
new file mode 100644
index 0000000..f906e1e
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/function/NormalizeSpaceFunction.java
@@ -0,0 +1,174 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/function/NormalizeSpaceFunction.java,v 1.17 2006/02/05 21:47:41 elharo Exp $
+ * $Revision: 1.17 $
+ * $Date: 2006/02/05 21:47:41 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: NormalizeSpaceFunction.java,v 1.17 2006/02/05 21:47:41 elharo Exp $
+ */
+
+
+package org.jaxen.function;
+
+import java.util.List;
+
+import org.jaxen.Context;
+import org.jaxen.Function;
+import org.jaxen.FunctionCallException;
+import org.jaxen.Navigator;
+
+/**
+ * <p>
+ * <b>4.2</b> <code><i>string</i> normalize-space(<i>string</i>)</code>
+ * </p>
+ * 
+ * <blockquote src="http://www.w3.org/TR/xpath#function-normalize-space"> 
+ * The <b>normalize-space</b> function
+ * returns the argument string with whitespace normalized by stripping
+ * leading and trailing whitespace and replacing sequences of whitespace
+ * characters by a single space. Whitespace characters are the same as
+ * those allowed by the <a href="http://www.w3.org/TR/REC-xml#NT-S" target="_top">S</a>
+ * production in XML. If the argument is omitted, it defaults to the
+ * context node converted to a string, in other words the <a
+ * href="http://www.w3.org/TR/xpath#dt-string-value"  
+ * target="_top">string-value</a> of the context node.
+ * </blockquote>
+ * 
+ * @author James Strachan (james at metastuff.com)
+ * @see <a href="http://www.w3.org/TR/xpath#function-normalize-space"
+ *      target="_top">Section 4.2 of the XPath Specification</a>
+ */
+public class NormalizeSpaceFunction implements Function
+{
+
+
+    /**
+     * Create a new <code>NormalizeSpaceFunction</code> object.
+     */
+    public NormalizeSpaceFunction() {}
+    
+    /** 
+     * Returns the string-value of the first item in <code>args</code>
+     * after removing all leading and trailing white space, and 
+     * replacing each other sequence of whitespace by a single space.
+     * Whitespace consists of the characters space (0x32), carriage return (0x0D),
+     * linefeed (0x0A), and tab (0x09).
+     *
+     * @param context the context at the point in the
+     *         expression when the function is called
+     * @param args a list that contains exactly one item
+     * 
+     * @return a normalized <code>String</code>
+     * 
+     * @throws FunctionCallException if <code>args</code> does not have length one
+     */
+    public Object call(Context context,
+                       List args) throws FunctionCallException
+    {
+        
+        if (args.size() == 0) {
+            return evaluate( context.getNodeSet(),
+                             context.getNavigator() );
+        }
+        else if (args.size() == 1)
+        {
+            return evaluate( args.get(0),
+                             context.getNavigator() );
+        }
+    
+        throw new FunctionCallException( "normalize-space() cannot have more than one argument" );
+    }
+
+    /** 
+     * Returns the string-value of <code>strArg</code> after removing
+     * all leading and trailing white space, and 
+     * replacing each other sequence of whitespace by a single space.
+     * Whitespace consists of the characters space (0x32), carriage return (0x0D),
+     * linefeed (0x0A), and tab (0x09).
+     *
+     * @param strArg the object whose string-value is normalized
+     * @param nav the context at the point in the
+     *         expression when the function is called
+     * 
+     * @return the normalized string-value
+     */
+    public static String evaluate(Object strArg,
+                                  Navigator nav) 
+    {
+        String str = StringFunction.evaluate( strArg,
+                                              nav );
+
+        char[] buffer = str.toCharArray();
+        int write = 0;
+        int lastWrite = 0;
+        boolean wroteOne = false;
+        int read = 0;
+        while (read < buffer.length)
+        {
+            if (isXMLSpace(buffer[read]))
+            {
+                if (wroteOne)
+                {
+                    buffer[write++] = ' ';
+                }
+                do
+                {
+                    read++;
+                }
+                while(read < buffer.length && isXMLSpace(buffer[read]));
+            }
+            else
+            {
+                buffer[write++] = buffer[read++];
+                wroteOne = true;
+                lastWrite = write;
+            }
+        }
+
+        return new String(buffer, 0, lastWrite);
+    }
+    
+    
+    private static boolean isXMLSpace(char c) {
+        return c == ' ' || c == '\n' || c == '\r' || c == '\t';
+    }
+    
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/function/NotFunction.java b/libjaxen-java/src/java/main/org/jaxen/function/NotFunction.java
new file mode 100644
index 0000000..69ad342
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/function/NotFunction.java
@@ -0,0 +1,122 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/function/NotFunction.java,v 1.9 2006/02/05 21:47:41 elharo Exp $
+ * $Revision: 1.9 $
+ * $Date: 2006/02/05 21:47:41 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: NotFunction.java,v 1.9 2006/02/05 21:47:41 elharo Exp $
+ */
+
+package org.jaxen.function;
+
+import java.util.List;
+
+import org.jaxen.Context;
+import org.jaxen.Function;
+import org.jaxen.FunctionCallException;
+import org.jaxen.Navigator;
+
+/**
+ * <p><b>4.3</b> <code><i>boolean</i> not(<i>boolean</i>)</code> </p>
+ * 
+ * 
+ * <blockquote src="http://www.w3.org/TR/xpath#function-not">
+ * The <b>not</b> function returns true if its argument is false, and false otherwise.
+ * </blockquote>
+ * 
+ * @author bob mcwhirter (bob @ werken.com)
+ * @see <a href="http://www.w3.org/TR/xpath#function-not" target="_top">Section 4.3 of the XPath Specification</a>
+ */
+public class NotFunction implements Function
+{
+
+    /**
+     * Create a new <code>NotFunction</code> object.
+     */
+    public NotFunction() {}
+    
+    /**
+     * Returns <code>Boolean.TRUE</code> if the boolean value of 
+     * <code>args.get(0)</code> is false, and <code>Boolean.FALSE</code> otherwise.
+     * The boolean value is calculated as if by the XPath <code>boolean</code>
+     * function. 
+     * 
+     * @param context the context at the point in the
+     *         expression where the function is called
+     * @param args a single element list
+     * 
+     * @return <code>Boolean.TRUE</code> if the boolean value of 
+     * <code>obj</code> is false, and <code>Boolean.FALSE</code> otherwise
+     * 
+     * @throws FunctionCallException if <code>args</code> does not have exactly one argument
+     */
+    public Object call(Context context,
+                       List args) throws FunctionCallException
+    {
+        if (args.size() == 1)
+        {
+            return evaluate( args.get(0), context.getNavigator() );
+        }
+
+        throw new FunctionCallException( "not() requires one argument." );
+    }
+
+    /**
+     * Returns <code>Boolean.TRUE</code> if the boolean value of 
+     * <code>obj</code> is false, and <code>Boolean.FALSE</code> otherwise.
+     * The boolean value is calculated as if by the XPath <code>boolean</code>
+     * function. 
+     * 
+     * @param obj the object whose boolean value is inverted
+     * @param nav the <code>Navigator</code> used to calculate the boolean value of <code>obj</code>
+     * 
+     * @return <code>Boolean.TRUE</code> if the boolean value of 
+     * <code>obj</code> is false, and <code>Boolean.FALSE</code> otherwise
+     */
+    public static Boolean evaluate(Object obj, Navigator nav)
+    {
+        return ( ( BooleanFunction.evaluate( obj, nav ).booleanValue() )
+                 ? Boolean.FALSE
+                 : Boolean.TRUE
+                 );
+    }
+    
+}
\ No newline at end of file
diff --git a/libjaxen-java/src/java/main/org/jaxen/function/NumberFunction.java b/libjaxen-java/src/java/main/org/jaxen/function/NumberFunction.java
new file mode 100644
index 0000000..3ef1003
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/function/NumberFunction.java
@@ -0,0 +1,240 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/function/NumberFunction.java,v 1.18 2006/02/05 21:47:41 elharo Exp $
+ * $Revision: 1.18 $
+ * $Date: 2006/02/05 21:47:41 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: NumberFunction.java,v 1.18 2006/02/05 21:47:41 elharo Exp $
+ */
+
+package org.jaxen.function;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.jaxen.Context;
+import org.jaxen.Function;
+import org.jaxen.FunctionCallException;
+import org.jaxen.Navigator;
+
+/**
+ * <p>
+ * <b>4.4</b> <code><i>number</i> number(<i>object</i>)</code>
+ * 
+ * 
+ * <blockquote src="http://www.w3.org/TR/xpath#function-number">
+ * <p>
+ * The <b>number</b> function converts
+ * its argument to a number as follows:
+ * </p>
+ * 
+ * <ul>
+ * 
+ * <li>
+ * <p>
+ * a string that consists of optional whitespace followed by an optional
+ * minus sign followed by a <a href="#NT-Number">Number</a> followed by
+ * whitespace is converted to the IEEE 754 number that is nearest
+ * (according to the IEEE 754 round-to-nearest rule) to the mathematical
+ * value represented by the string; any other string is converted to NaN
+ * </p>
+ * </li>
+ * 
+ * <li>
+ * <p>
+ * boolean true is converted to 1; boolean false is converted to 0
+ * </p>
+ * </li>
+ * 
+ * <li>
+ * 
+ * <p>
+ * a node-set is first converted to a string as if by a call to the <b><a
+ * href="http://www.w3.org/TR/xpath#function-string" target="_top">string</a></b> function and then converted
+ * in the same way as a string argument
+ * </p>
+ * 
+ * </li>
+ * 
+ * <li>
+ * <p>
+ * an object of a type other than the four basic types is converted to a
+ * number in a way that is dependent on that type
+ * </p>
+ * </li>
+ * 
+ * </ul>
+ * 
+ * <p>
+ * If the argument is omitted, it defaults to a node-set with the
+ * context node as its only member.
+ * </p>
+ * 
+ * <blockquote> <b>NOTE: </b>The <b>number</b>
+ * function should not be used for conversion of numeric data occurring
+ * in an element in an XML document unless the element is of a type that
+ * represents numeric data in a language-neutral format (which would
+ * typically be transformed into a language-specific format for
+ * presentation to a user). In addition, the <b>number</b> function cannot be used
+ * unless the language-neutral format used by the element is consistent
+ * with the XPath syntax for a <a href="http://www.w3.org/TR/xpath#NT-Number">Number</a>.</blockquote>
+ * 
+ * </blockquote>
+ * 
+ * @author bob mcwhirter (bob @ werken.com)
+ * 
+ * @see <a href="http://www.w3.org/TR/xpath#function-number"
+ *      target="_top">Section 4.4 of the XPath Specification</a>
+ */
+public class NumberFunction implements Function
+{
+
+    private final static Double NaN = new Double( Double.NaN );
+    
+    
+    /**
+     * Create a new <code>NumberFunction</code> object.
+     */
+    public NumberFunction() {}
+
+    /** 
+     * Returns the number value of <code>args.get(0)</code>,
+     * or the number value of the context node if <code>args</code>
+     * is empty.
+     *
+     * @param context the context at the point in the
+     *         expression when the function is called
+     * @param args a list containing the single item to be converted to a 
+     *     <code>Double</code>
+     * 
+     * @return a <code>Double</code>
+     * 
+     * @throws FunctionCallException if <code>args</code> has more than one item
+     */
+    public Object call(Context context, List args) throws FunctionCallException
+    {
+        if (args.size() == 1)
+        {
+            return evaluate( args.get(0), context.getNavigator() );
+        }
+        else if (args.size() == 0)
+        {
+            return evaluate( context.getNodeSet(), context.getNavigator() );
+        }
+    
+        throw new FunctionCallException( "number() takes at most one argument." );
+    }
+
+    /** 
+     * Returns the number value of <code>obj</code>.
+     *
+     * @param obj the object to be converted to a number
+     * @param nav the <code>Navigator</code> used to calculate the string-value
+     *     of node-sets
+     * 
+     * @return a <code>Double</code>
+     */
+    public static Double evaluate(Object obj, Navigator nav)
+    {
+        if( obj instanceof Double )
+        {
+            return (Double) obj;
+        }
+        else if ( obj instanceof String )
+        {
+            String str = (String) obj;
+            try
+            {
+                Double doubleValue = new Double( str );        
+                return doubleValue;
+            }
+            catch (NumberFormatException e)
+            {
+                return NaN;
+            }
+        }
+        else if ( obj instanceof List || obj instanceof Iterator )
+        {
+          return evaluate( StringFunction.evaluate( obj, nav ), nav );
+        }
+        else if ( nav.isElement( obj ) || nav.isAttribute( obj ) )
+        {
+            return evaluate( StringFunction.evaluate( obj, nav ), nav );
+        }
+        else if ( obj instanceof Boolean )
+          {
+          if ( obj == Boolean.TRUE )
+          {
+              return new Double( 1 );
+          }
+          else
+          {
+              return new Double( 0 );
+          }
+        }    
+        return NaN;
+    }
+  
+  /**
+   * Determines whether the argument is not a number (NaN) as defined
+   * by IEEE 754.
+   * 
+   * @param val the double to test
+   * @return true if the value is NaN, false otherwise
+   */
+    public static boolean isNaN( double val )
+    {
+        return Double.isNaN(val);
+    }
+  
+  /**
+   * Determines whether the argument is not a number (NaN) as defined
+   * by IEEE 754.
+   * 
+   * @param val the <code>Double</code> to test
+   * @return true if the value is NaN, false otherwise
+   */
+    public static boolean isNaN( Double val )
+    {
+        return val.equals( NaN );
+    }  
+  
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/function/PositionFunction.java b/libjaxen-java/src/java/main/org/jaxen/function/PositionFunction.java
new file mode 100644
index 0000000..3b95064
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/function/PositionFunction.java
@@ -0,0 +1,115 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/function/PositionFunction.java,v 1.11 2006/02/05 21:47:41 elharo Exp $
+ * $Revision: 1.11 $
+ * $Date: 2006/02/05 21:47:41 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: PositionFunction.java,v 1.11 2006/02/05 21:47:41 elharo Exp $
+ */
+
+
+package org.jaxen.function;
+
+import java.util.List;
+
+import org.jaxen.Context;
+import org.jaxen.Function;
+import org.jaxen.FunctionCallException;
+
+/**
+ * <p><b>4.1</b> <code><i>number</i> position()</code></p>
+ *
+ * 
+ * <blockquote src="http://www.w3.org/TR/xpath">
+ * The position function returns a number equal to the context position from the expression evaluation context.
+ * </blockquote>
+ * 
+ * @author bob mcwhirter (bob @ werken.com)
+ * @see <a href="http://www.w3.org/TR/xpath#function-position" target="_top">Section 4.1 of the XPath Specification</a>
+ */
+public class PositionFunction implements Function
+{
+    
+    /**
+     * Create a new <code>PositionFunction</code> object.
+     */
+    public PositionFunction() {}
+    
+    /**
+     * Returns the position of the context node in the context node-set.
+     * 
+     * @param context the context at the point in the
+     *         expression where the function is called
+     * @param args an empty list
+     * 
+     * @return a <code>Double</code> containing the context position
+     * 
+     * @throws FunctionCallException if <code>args</code> is not empty
+     * 
+     * @see Context#getSize()
+     */
+    public Object call(Context context, List args) throws FunctionCallException 
+    {
+        if ( args.size() == 0 )
+        {
+            return evaluate( context );
+        }
+        
+        throw new FunctionCallException( "position() does not take any arguments." );
+    }
+    
+    /**
+     * 
+     * Returns the position of the context node in the context node-set.
+     * 
+     * @param context the context at the point in the
+     *         expression where the function is called
+     * 
+     * @return a <code>Double</code> containing the context position
+     * 
+     * @see Context#getPosition()
+     */
+    public static Double evaluate(Context context)
+    {
+        return new Double( context.getPosition() );
+    }
+    
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/function/RoundFunction.java b/libjaxen-java/src/java/main/org/jaxen/function/RoundFunction.java
new file mode 100644
index 0000000..763fa34
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/function/RoundFunction.java
@@ -0,0 +1,133 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/function/RoundFunction.java,v 1.12 2006/02/05 21:47:41 elharo Exp $
+ * $Revision: 1.12 $
+ * $Date: 2006/02/05 21:47:41 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: RoundFunction.java,v 1.12 2006/02/05 21:47:41 elharo Exp $
+ */
+
+
+package org.jaxen.function;
+
+import java.util.List;
+
+import org.jaxen.Context;
+import org.jaxen.Function;
+import org.jaxen.FunctionCallException;
+import org.jaxen.Navigator;
+
+/**
+ * <p><b>4.4</b> <code><i>number</i> round(<i>number</i>)</code> </p>
+ * 
+ * 
+ * <blockquote src="http://www.w3.org/TR/xpath">
+ * The <b>round</b> function returns the number that is closest to the argument and that is an integer. 
+ * If there are two such numbers, then the one that is closest to positive infinity is returned. 
+ * If the argument is NaN, then NaN is returned. If the argument is positive infinity, then positive infinity is returned. 
+ * If the argument is negative infinity, then negative infinity is returned. 
+ * If the argument is positive zero, then positive zero is returned. 
+ * If the argument is negative zero, then negative zero is returned. 
+ * If the argument is less than zero, but greater than or equal to -0.5, then negative zero is returned.
+ * </blockquote>
+ * 
+ * @author bob mcwhirter (bob @ werken.com)
+ * 
+ * @see <a href="http://www.w3.org/TR/xpath#function-round" target="_top">Section 4.4 of the XPath Specification</a>
+ */
+public class RoundFunction implements Function
+{
+ 
+    /**
+     * Create a new <code>RoundFunction</code> object.
+     */
+    public RoundFunction() {}
+    
+    
+    /** Returns the nearest integer to the number.
+     *
+     * @param context the context at the point in the
+     *         expression when the function is called
+     * @param args a list with exactly one item which will be converted to a 
+     *     <code>Double</code> as if by the XPath <code>number()</code> function
+     * 
+     * @return a <code>Double</code> containing the integer nearest to
+     *     <code>args.get(0)</code>
+     * 
+     * @throws FunctionCallException if <code>args</code> has more or less than one item
+     */
+    public Object call(Context context,
+                       List args) throws FunctionCallException
+    {
+        if (args.size() == 1)
+        {
+            return evaluate( args.get(0),
+                             context.getNavigator() );
+        }
+
+        throw new FunctionCallException( "round() requires one argument." );
+    }
+
+    /** 
+     * Returns the integer nearest to the argument.
+     * If necessary, the argument is first converted to a <code>Double</code>
+     * as if by the XPath <code>number()</code> function.
+     * 
+     * @param obj the object to be rounded
+     * @param nav ignored
+     * 
+     * @return the integer nearest to <code>obj</code>
+     */
+    public static Double evaluate(Object obj,
+                                  Navigator nav)
+    {
+        Double d  = NumberFunction.evaluate( obj,
+                                            nav );
+
+        if (d.isNaN() || d.isInfinite())
+        {
+            return d;
+        }
+
+        double value = d.doubleValue();
+        return new Double( Math.round( value ) );
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/function/StartsWithFunction.java b/libjaxen-java/src/java/main/org/jaxen/function/StartsWithFunction.java
new file mode 100644
index 0000000..4c60c8d
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/function/StartsWithFunction.java
@@ -0,0 +1,136 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/function/StartsWithFunction.java,v 1.11 2006/02/05 21:47:41 elharo Exp $
+ * $Revision: 1.11 $
+ * $Date: 2006/02/05 21:47:41 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: StartsWithFunction.java,v 1.11 2006/02/05 21:47:41 elharo Exp $
+ */
+
+
+package org.jaxen.function;
+
+import java.util.List;
+
+import org.jaxen.Context;
+import org.jaxen.Function;
+import org.jaxen.FunctionCallException;
+import org.jaxen.Navigator;
+
+/**
+ * <p><b>4.2</b> <code><i>boolean</i> starts-with(<i>string</i>,<i>string</i>)</code></p> 
+ * 
+ * 
+ * <blockquote src="http://www.w3.org/TR/xpath">
+ * The <b>starts-with</b> function returns true if the first argument string starts 
+ * with the second argument string, and otherwise returns false.
+ * </blockquote>
+ * 
+ * @author bob mcwhirter (bob @ werken.com)
+ * @see <a href="http://www.w3.org/TR/xpath#function-starts-with" target="_top">Section 4.2 of the XPath Specification</a>
+ */
+public class StartsWithFunction implements Function
+{
+    
+    /**
+     * Create a new <code>StartsWithFunction</code> object.
+     */
+    public StartsWithFunction() {}
+    
+    /** 
+     * Returns true if the string-value of the first item in <code>args</code>
+     * starts with the string-value of the second item in <code>args</code>. 
+     * Otherwise it returns false.
+     *
+     * @param context the context at the point in the
+     *         expression when the function is called
+     * @param args a list that contains two items
+     * 
+     * @return <code>Boolean.TRUE</code> if the first item in <code>args</code>
+     *     starts with the string-value of the second item in <code>args</code>;
+     *     otherwise <code>Boolean.FALSE</code>
+     * 
+     * @throws FunctionCallException if <code>args</code> does not have length two
+     */
+    public Object call(Context context,
+                       List args) throws FunctionCallException
+    {
+        if (args.size() == 2)
+        {
+            return evaluate( args.get(0),
+                             args.get(1),
+                             context.getNavigator() );
+        }
+
+        throw new FunctionCallException( "starts-with() requires two arguments." );
+    }
+
+    /** 
+     * Returns true if the string-value of <code>strArg</code>
+     * starts with the string-value of <code>matchArg</code>. 
+     * Otherwise it returns false.
+     * 
+     * @param strArg the object whose string-value searched for the prefix
+     * @param matchArg the object whose string-value becomes the prefix string to compare against
+     * @param nav the navigator used to calculate the string-values of the arguments
+     * 
+     * @return <code>Boolean.TRUE</code> if the string-value of <code>strArg</code>
+     *     starts with the string-value of <code>matchArg</code>;
+     *     otherwise <code>Boolean.FALSE</code>
+     * 
+     */
+    public static Boolean evaluate(Object strArg,
+                                   Object matchArg,
+                                   Navigator nav)
+    {
+        String str   = StringFunction.evaluate( strArg,
+                                                nav );
+
+        String match = StringFunction.evaluate( matchArg,
+                                                nav );
+
+        return ( str.startsWith(match)
+                 ? Boolean.TRUE
+                 : Boolean.FALSE
+                 );
+    }
+     
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/function/StringFunction.java b/libjaxen-java/src/java/main/org/jaxen/function/StringFunction.java
new file mode 100644
index 0000000..4743e69
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/function/StringFunction.java
@@ -0,0 +1,355 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/function/StringFunction.java,v 1.33 2006/02/05 21:47:41 elharo Exp $
+ * $Revision: 1.33 $
+ * $Date: 2006/02/05 21:47:41 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: StringFunction.java,v 1.33 2006/02/05 21:47:41 elharo Exp $
+ */
+
+
+package org.jaxen.function;
+
+import org.jaxen.Context;
+import org.jaxen.Function;
+import org.jaxen.FunctionCallException;
+import org.jaxen.Navigator;
+import org.jaxen.UnsupportedAxisException;
+import org.jaxen.JaxenRuntimeException;
+
+import java.text.DecimalFormat;
+import java.text.NumberFormat;
+import java.text.DecimalFormatSymbols;
+import java.util.List;
+import java.util.Iterator;
+import java.util.Locale;
+
+/**
+ * <p>
+ * <b>4.2</b> <code><i>string</i> string(<i>object</i>)</code>
+ * </p>
+ * 
+ * 
+ * <blockquote src="http://www.w3.org/TR/xpath">
+ * <p>
+ * The <b>string</b> function converts
+ * an object to a string as follows:
+ * </p>
+ * 
+ * <ul>
+ * 
+ * <li>
+ * <p>
+ * A node-set is converted to a string by returning the <a
+ * href="http://www.w3.org/TR/xpath#dt-string-value" target="_top">string-value</a> of the node in the node-set
+ * that is first in <a href="http://www.w3.org/TR/xpath#dt-document-order" target="_top">document order</a>. If
+ * the node-set is empty, an empty string is returned.
+ * </p>
+ * </li>
+ * 
+ * <li>
+ * <p>
+ * A number is converted to a string as follows
+ * </p>
+ * 
+ * <ul>
+ * 
+ * <li>
+ * <p>
+ * NaN is converted to the string <code>NaN</code>
+ * </p>
+ * </li>
+ * 
+ * <li>
+ * <p>
+ * positive zero is converted to the string <code>0</code>
+ * </p>
+ * </li>
+ * 
+ * <li>
+ * 
+ * <p>
+ * negative zero is converted to the string <code>0</code>
+ * </p>
+ * </li>
+ * 
+ * <li>
+ * <p>
+ * positive infinity is converted to the string <code>Infinity</code>
+ * </p>
+ * </li>
+ * 
+ * <li>
+ * <p>
+ * negative infinity is converted to the string <code>-Infinity</code>
+ * 
+ * </p>
+ * </li>
+ * 
+ * <li>
+ * <p>
+ * if the number is an integer, the number is represented in decimal
+ * form as a <a href="http://www.w3.org/TR/xpath#NT-Number" target="_top">Number</a> with no decimal point and
+ * no leading zeros, preceded by a minus sign (<code>-</code>) if
+ * the number is negative
+ * </p>
+ * </li>
+ * 
+ * <li>
+ * <p>
+ * otherwise, the number is represented in decimal form as a Number including a decimal point with at least
+ * one digit before the decimal point and at least one digit after the
+ * decimal point, preceded by a minus sign (<code>-</code>) if the
+ * number is negative; there must be no leading zeros before the decimal
+ * point apart possibly from the one required digit immediately before
+ * the decimal point; beyond the one required digit after the decimal
+ * point there must be as many, but only as many, more digits as are
+ * needed to uniquely distinguish the number from all other IEEE 754
+ * numeric values.
+ * </p>
+ * 
+ * </li>
+ * 
+ * </ul>
+ * 
+ * </li>
+ * 
+ * <li>
+ * <p>
+ * The boolean false value is converted to the string <code>false</code>.
+ * The boolean true value is converted to the string <code>true</code>.
+ * </p>
+ * </li>
+ * 
+ * <li>
+ * <p>
+ * An object of a type other than the four basic types is converted to a
+ * string in a way that is dependent on that type.
+ * </p>
+ * 
+ * </li>
+ * 
+ * </ul>
+ * 
+ * <p>
+ * If the argument is omitted, it defaults to a node-set with the
+ * context node as its only member.
+ * </p>
+ * 
+ * </blockquote>
+ * 
+ * @author bob mcwhirter (bob @ werken.com)
+ * @see <a href="http://www.w3.org/TR/xpath#function-string"
+ *      target="_top">Section 4.2 of the XPath Specification</a>
+ */
+public class StringFunction implements Function
+{
+
+    private static DecimalFormat format = (DecimalFormat) NumberFormat.getInstance(Locale.ENGLISH);
+    
+    static {
+        DecimalFormatSymbols symbols = new DecimalFormatSymbols(Locale.ENGLISH);
+        symbols.setNaN("NaN");
+        symbols.setInfinity("Infinity");
+        format.setGroupingUsed(false);
+        format.setMaximumFractionDigits(32);
+        format.setDecimalFormatSymbols(symbols);
+    }
+
+    /**
+     * Create a new <code>StringFunction</code> object.
+     */
+    public StringFunction() {}
+    
+    /**
+     * Returns the string-value of <code>args.get(0)</code> 
+     * or of the context node if <code>args</code> is empty.
+     * 
+     * @param context the context at the point in the
+     *         expression where the function is called
+     * @param args list with zero or one element
+     * 
+     * @return a <code>String</code> 
+     * 
+     * @throws FunctionCallException if <code>args</code> has more than one item
+     */    
+    public Object call(Context context,
+                       List args) throws FunctionCallException
+    {
+        int size = args.size();
+
+        if ( size == 0 )
+        {
+            return evaluate( context.getNodeSet(),
+                             context.getNavigator() );
+        }
+        else if ( size == 1 )
+        {
+            return evaluate( args.get(0),
+                             context.getNavigator() );
+        }
+
+        throw new FunctionCallException( "string() takes at most argument." );
+    }
+    
+    /**
+     * Returns the XPath string-value of <code>obj</code>.
+     * This operation is only defined if obj is a node, node-set,
+     * <code>String</code>, <code>Number</code>, or 
+     * <code>Boolean</code>. For other types this function
+     * returns the empty string. 
+     * 
+     * @param obj the node, node-set, string, number, or boolean
+     *      whose string-value is calculated
+     * @param nav the navigator used to calculate the string-value
+     * 
+     * @return a <code>String</code>. May be empty but is never null.
+     */    
+    public static String evaluate(Object obj,
+                                  Navigator nav)
+    {
+        try
+        {
+            // Workaround because XOM uses lists for Text nodes
+            // so we need to check for that first
+            if (nav != null && nav.isText(obj))
+            {
+                return nav.getTextStringValue(obj);
+            }
+            
+            if (obj instanceof List)
+            {
+                List list = (List) obj;
+                if (list.isEmpty())
+                {
+                    return "";
+                }
+                // do not recurse: only first list should unwrap
+                obj = list.get(0);
+            }
+            
+            if (nav != null) {
+                // This stack of instanceof really suggests there's 
+                // a failure to take advantage of polymorphism here
+                if (nav.isElement(obj))
+                {
+                    return nav.getElementStringValue(obj);
+                }
+                else if (nav.isAttribute(obj))
+                {
+                    return nav.getAttributeStringValue(obj);
+                }
+    
+                else if (nav.isDocument(obj))
+                {
+                    Iterator childAxisIterator = nav.getChildAxisIterator(obj);
+                    while (childAxisIterator.hasNext())
+                    {
+                        Object descendant = childAxisIterator.next();
+                        if (nav.isElement(descendant))
+                        {
+                            return nav.getElementStringValue(descendant);
+                        }
+                    }
+                }
+                else if (nav.isProcessingInstruction(obj))
+                {
+                    return nav.getProcessingInstructionData(obj);
+                }
+                else if (nav.isComment(obj))
+                {
+                    return nav.getCommentStringValue(obj);
+                }
+                else if (nav.isText(obj))
+                {
+                    return nav.getTextStringValue(obj);
+                }
+                else if (nav.isNamespace(obj))
+                {
+                    return nav.getNamespaceStringValue(obj);
+                }
+            }
+            
+            if (obj instanceof String)
+            {
+                return (String) obj;
+            }
+            else if (obj instanceof Boolean)
+            {
+                return stringValue(((Boolean) obj).booleanValue());
+            }
+            else if (obj instanceof Number)
+            {
+                return stringValue(((Number) obj).doubleValue());
+            }
+            
+        }
+        catch (UnsupportedAxisException e)
+        {
+            throw new JaxenRuntimeException(e);
+        }
+        
+        return "";
+
+    }
+
+    private static String stringValue(double value)
+    {
+        
+        // DecimalFormat formats negative zero as "-0".
+        // Therefore we need to test for zero explicitly here.
+        if (value == 0) return "0";
+        
+        // need to synchronize object for thread-safety
+        String result = null;
+        synchronized (format) {
+            result = format.format(value);
+        }
+        return result;
+        
+    }
+
+    private static String stringValue(boolean value)
+    {
+        return value ? "true" : "false";
+    }
+
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/function/StringLengthFunction.java b/libjaxen-java/src/java/main/org/jaxen/function/StringLengthFunction.java
new file mode 100644
index 0000000..8ae897f
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/function/StringLengthFunction.java
@@ -0,0 +1,156 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/function/StringLengthFunction.java,v 1.12 2006/02/05 21:47:41 elharo Exp $
+ * $Revision: 1.12 $
+ * $Date: 2006/02/05 21:47:41 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: StringLengthFunction.java,v 1.12 2006/02/05 21:47:41 elharo Exp $
+ */
+
+
+package org.jaxen.function;
+
+import java.util.List;
+
+import org.jaxen.Context;
+import org.jaxen.Function;
+import org.jaxen.FunctionCallException;
+import org.jaxen.Navigator;
+
+/**
+ * <p><b>4.2</b> <code><i>number</i> string-length(<i>string</i>)</code></p> 
+ * 
+ * <p>
+ * The <b>string-length</b> function returns the number of <strong>Unicode characters</strong>
+ * in its argument. This is <strong>not</strong> necessarily 
+ * the same as the number <strong>Java chars</strong>
+ * in the corresponding Java string. In particular, if the Java <code>String</code>
+ * contains surrogate pairs each such pair will be counted as only one character
+ * by this function. If the argument is omitted, 
+ * it returns the length of the string-value of the context node.
+ * </p>
+ * 
+ * @author bob mcwhirter (bob @ werken.com)
+ * @see <a href="http://www.w3.org/TR/xpath#function-string-length" target="_top">Section 
+ *      4.2 of the XPath Specification</a>
+ */
+public class StringLengthFunction implements Function
+{
+
+    
+    /**
+     * Create a new <code>StringLengthFunction</code> object.
+     */
+    public StringLengthFunction() {}
+    
+    
+    /**
+     * <p>
+     * Returns the number of Unicode characters in the string-value of the argument.
+     * </p>
+     * 
+     * @param context the context at the point in the
+     *         expression when the function is called
+     * @param args a list containing the item whose string-value is to be counted.
+     *     If empty, the length of the context node's string-value is returned.
+     * 
+     * @return a <code>Double</code> giving the number of Unicode characters
+     * 
+     * @throws FunctionCallException if args has more than one item
+     */
+    public Object call(Context context,
+                       List args) throws FunctionCallException
+    {
+        if (args.size() == 0)
+        {
+            return evaluate( context.getNodeSet(),
+                             context.getNavigator() );
+        } 
+        else if (args.size() == 1)
+        {
+            return evaluate( args.get(0),
+                             context.getNavigator() );
+        }
+
+        throw new FunctionCallException( "string-length() requires one argument." );
+    }
+
+    /**
+     * <p>
+     * Returns the number of Unicode characters in the string-value of 
+     * an object.
+     * </p>
+     * 
+     * @param obj the object whose string-value is counted
+     * @param nav used to calculate the string-values of the first two arguments
+     * 
+     * @return a <code>Double</code> giving the number of Unicode characters
+     * 
+     * @throws FunctionCallException if the string contains mismatched surrogates
+     */
+    public static Double evaluate(Object obj, Navigator nav) throws FunctionCallException
+    {
+        String str = StringFunction.evaluate( obj, nav );
+        // String.length() counts UTF-16 code points; not Unicode characters
+        char[] data = str.toCharArray();
+        int length = 0;
+        for (int i = 0; i < data.length; i++) {
+            char c = data[i];
+            length++;
+            // if this is a high surrogate; assume the next character is
+            // is a low surrogate and skip it
+            if (c >= 0xD800) {
+                try {
+                    char low = data[i+1];
+                    if (low < 0xDC00 || low > 0xDFFF) {
+                        throw new FunctionCallException("Bad surrogate pair in string " + str);
+                    }
+                    i++; // increment past low surrogate
+                }
+                catch (ArrayIndexOutOfBoundsException ex) {
+                    throw new FunctionCallException("Bad surrogate pair in string " + str);
+                }
+            }
+        }
+        return new Double(length);
+    }
+    
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/function/SubstringAfterFunction.java b/libjaxen-java/src/java/main/org/jaxen/function/SubstringAfterFunction.java
new file mode 100644
index 0000000..5933ea3
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/function/SubstringAfterFunction.java
@@ -0,0 +1,145 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/function/SubstringAfterFunction.java,v 1.11 2006/02/05 21:47:41 elharo Exp $
+ * $Revision: 1.11 $
+ * $Date: 2006/02/05 21:47:41 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: SubstringAfterFunction.java,v 1.11 2006/02/05 21:47:41 elharo Exp $
+ */
+
+
+package org.jaxen.function;
+
+import java.util.List;
+
+import org.jaxen.Context;
+import org.jaxen.Function;
+import org.jaxen.FunctionCallException;
+import org.jaxen.Navigator;
+
+/**
+ * <p><b>4.2</b> <code><i>string</i> substring-after(<i>string</i>,<i>string</i>)</code></p> 
+ * 
+ * 
+ * <blockquote src="http://www.w3.org/TR/xpath">
+ * The <b>substring-after</b> function returns the substring of the first argument string 
+ * that follows the first occurrence of the second argument string in the first 
+ * argument string, or the empty string if the first argument string does not contain the second argument string. 
+ * For example, substring-after("1999/04/01","/") returns 04/01, 
+ * and substring-after("1999/04/01","19") returns 99/04/01.
+ * </blockquote>
+ * 
+ * @author bob mcwhirter (bob @ werken.com)
+ * @see <a href="http://www.w3.org/TR/xpath#function-substring-after" target="_top">Section 4.2 of the XPath Specification</a>
+ */
+public class SubstringAfterFunction implements Function
+{
+
+    /**
+     * Create a new <code>SubstringAfterFunction</code> object.
+     */
+    public SubstringAfterFunction() {}
+
+
+    /** 
+     * Returns the part of the string-value of the first item in <code>args</code>
+     * that follows the string-value of the second item in <code>args</code>;
+     * or the empty string if the second string is not a substring of the first string.
+     *
+     * @param context the context at the point in the
+     *         expression when the function is called
+     * @param args a list that contains two items
+     * 
+     * @return a <code>String</code> containing that 
+     *     part of the string-value of the first item in <code>args</code>
+     *     that comes before the string-value of the second item in <code>args</code>
+     * 
+     * @throws FunctionCallException if <code>args</code> does not have length two
+     */
+    public Object call(Context context,
+                       List args) throws FunctionCallException
+    {
+        if (args.size() == 2)
+        {
+            return evaluate( args.get(0),
+                             args.get(1),
+                             context.getNavigator() );
+        }
+
+        throw new FunctionCallException( "substring-after() requires two arguments." );
+    }
+
+
+    /** 
+     * Returns the part of <code>strArg</code> that follows the first occurence 
+     * of <code>matchArg</code>; or the empty string if the 
+     * <code>strArg</code> does not contain <code>matchArg</code>
+     * 
+     * @param strArg the string from which the substring is extracted
+     * @param matchArg the string that marks the boundary of the substring
+     * @param nav the <code>Navigator</code> used to calculate the string-values of
+     *     the first two arguments
+     * 
+     * @return a <code>String</code> containing
+     *     the part of <code>strArg</code> that precedes the first occurence 
+     *     of <code>matchArg</code>
+     * 
+     */
+    public static String evaluate(Object strArg,
+                                  Object matchArg,
+                                  Navigator nav)
+    {
+        String str   = StringFunction.evaluate( strArg,
+                                                nav );
+
+        String match = StringFunction.evaluate( matchArg,
+                                                nav );
+    
+        int loc = str.indexOf(match);
+
+        if ( loc < 0 )
+        {
+            return "";
+        }
+
+        return str.substring(loc+match.length());
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/function/SubstringBeforeFunction.java b/libjaxen-java/src/java/main/org/jaxen/function/SubstringBeforeFunction.java
new file mode 100644
index 0000000..21725cc
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/function/SubstringBeforeFunction.java
@@ -0,0 +1,146 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/function/SubstringBeforeFunction.java,v 1.10 2006/02/05 21:47:41 elharo Exp $
+ * $Revision: 1.10 $
+ * $Date: 2006/02/05 21:47:41 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: SubstringBeforeFunction.java,v 1.10 2006/02/05 21:47:41 elharo Exp $
+ */
+
+
+package org.jaxen.function;
+
+import java.util.List;
+
+import org.jaxen.Context;
+import org.jaxen.Function;
+import org.jaxen.FunctionCallException;
+import org.jaxen.Navigator;
+
+/**
+ * <p><b>4.2</b> <code><i>string</i> substring-before(<i>string</i>,<i>string</i>)</code></p>
+ * 
+ * 
+ * <blockquote src="http://www.w3.org/TR/xpath#function-substring-before">
+ * The substring-before function returns the substring of the first argument 
+ * string that precedes the first occurrence of the second argument string 
+ * in the first argument string, or the empty string if the 
+ * first argument string does not contain the second argument string. 
+ * For example, substring-before("1999/04/01","/") returns 1999.
+ * </blockquote>
+ * 
+ * @author bob mcwhirter (bob @ werken.com)
+ * 
+ * @see <a href="http://www.w3.org/TR/xpath#function-substring-before" target="_top">Section 4.2 of the XPath Specification</a>
+ */
+public class SubstringBeforeFunction implements Function
+{
+
+    
+    /**
+     * Create a new <code>SubstringBeforeFunction</code> object.
+     */
+    public SubstringBeforeFunction() {}
+    
+    
+    /** 
+     * Returns the part of the string-value of the first item in <code>args</code>
+     * that comes before the string-value of the second item in <code>args</code>;
+     * or the empty string if the second string is not a substring of the first string.
+     *
+     * @param context the context at the point in the
+     *         expression when the function is called
+     * @param args a list that contains two items
+     * 
+     * @return a <code>String</code> containing that 
+     *     part of the string-value of the first item in <code>args</code>
+     *     that comes before the string-value of the second item in <code>args</code>
+     * 
+     * @throws FunctionCallException if <code>args</code> does not have length two
+     */
+    public Object call(Context context,
+                       List args) throws FunctionCallException
+    {
+        if (args.size() == 2)
+        {
+            return evaluate( args.get(0),
+                             args.get(1),
+                             context.getNavigator() );
+        }
+
+        throw new FunctionCallException( "substring-before() requires two arguments." );
+    }
+
+    /** 
+     * Returns the part of <code>strArg</code> that precedes the first occurence 
+     * of <code>matchArg</code>; or the empty string if the 
+     * <code>strArg</code> does not contain <code>matchArg</code>
+     * 
+     * @param strArg the string from which the substring is extracted
+     * @param matchArg the string that marks the boundary of the substring
+     * @param nav the <code>Navigator</code> used to calculate the string-values of
+     *     the first two arguments
+     * 
+     * @return a <code>String</code> containing the part of <code>strArg</code> that precedes the first occurence 
+     * of <code>matchArg</code>
+     * 
+     */
+    public static String evaluate(Object strArg,
+                                  Object matchArg,
+                                  Navigator nav)
+    {
+        String str   = StringFunction.evaluate( strArg,
+                                                nav );
+
+        String match = StringFunction.evaluate( matchArg,
+                                                nav );
+
+        int loc = str.indexOf(match);
+
+        if ( loc < 0 )
+        {
+            return "";
+        }
+
+        return str.substring(0, loc);
+
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/function/SubstringFunction.java b/libjaxen-java/src/java/main/org/jaxen/function/SubstringFunction.java
new file mode 100644
index 0000000..82fbccd
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/function/SubstringFunction.java
@@ -0,0 +1,250 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/function/SubstringFunction.java,v 1.16 2006/02/05 21:47:41 elharo Exp $
+ * $Revision: 1.16 $
+ * $Date: 2006/02/05 21:47:41 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Jaxen Project and was originally
+ * created by bob mcwhirter <bob at werken.com> and
+ * James Strachan <jstrachan at apache.org>.  For more information on the
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ *
+ */
+package org.jaxen.function;
+
+import java.util.List;
+
+import org.jaxen.Context;
+import org.jaxen.Function;
+import org.jaxen.FunctionCallException;
+import org.jaxen.Navigator;
+/**
+ * <p>
+ * <b>4.2</b>
+ * <code><i>string</i> substring(<i>string</i>,<i>number</i>,<i>number?</i>)</code>
+ * </p>
+ * 
+ * <blockquote src="http://www.w3.org/TR/xpath"> 
+ * <p>The <b>substring</b> function returns the
+ * substring of the first argument starting at the position specified in
+ * the second argument with length specified in the third argument. For
+ * example,
+ * 
+ * <code>substring("12345",2,3)</code> returns <code>"234"</code>.
+ * If the third argument is not specified, it returns the substring
+ * starting at the position specified in the second argument and
+ * continuing to the end of the string. For example,
+ * <code>substring("12345",2)</code> returns <code>"2345"</code>.
+ * </p>
+ * 
+ * <p>
+ * More precisely, each character in the string (see <a
+ * href="http://www.w3.org/TR/xpath#strings">[<b>3.6 Strings</b>]</a>) is considered to have a
+ * numeric position: the position of the first character is 1, the
+ * position of the second character is 2 and so on.
+ * </p>
+ * 
+ * <blockquote> <b>NOTE: </b>This differs from Java and ECMAScript, in
+ * which the <code>String.substring</code> method treats the position
+ * of the first character as 0.</blockquote>
+ * 
+ * <p>
+ * The returned substring contains those characters for which the
+ * position of the character is greater than or equal to the rounded
+ * value of the second argument and, if the third argument is specified,
+ * less than the sum of the rounded value of the second argument and the
+ * rounded value of the third argument; the comparisons and addition
+ * used for the above follow the standard IEEE 754 rules; rounding is
+ * done as if by a call to the <b><a href="#function-round">round</a></b>
+ * function. The following examples illustrate various unusual cases:
+ * </p>
+ * 
+ * <ul>
+ * 
+ * <li>
+ * <p>
+ * <code>substring("12345", 1.5, 2.6)</code> returns
+ * <code>"234"</code>
+ * </p>
+ * </li>
+ * 
+ * <li>
+ * <p>
+ * <code>substring("12345", 0, 3)</code> returns <code>"12"</code>
+ * 
+ * </p>
+ * </li>
+ * 
+ * <li>
+ * <p>
+ * <code>substring("12345", 0 div 0, 3)</code> returns <code>""</code>
+ * </p>
+ * </li>
+ * 
+ * <li>
+ * <p>.
+ * <code>substring("12345", 1, 0 div 0)</code> returns
+ * 
+ * <code>""</code>
+ * </p>
+ * </li>
+ * 
+ * <li>
+ * <p>
+ * <code>substring("12345", -42, 1 div 0)</code> returns
+ * <code>"12345"</code>
+ * </p>
+ * </li>
+ * 
+ * <li>
+ * <p>
+ * 
+ * <code>substring("12345", -1 div 0, 1 div 0)</code> returns
+ * <code>""</code> </blockquote>
+ * 
+ * @author bob mcwhirter (bob @ werken.com)
+ * 
+ * @see <a href="http://www.w3.org/TR/xpath#function-substring"
+ *      target="_top">Section 4.2 of the XPath Specification</a>
+ */
+public class SubstringFunction implements Function
+{
+
+    /**
+     * Create a new <code>SubstringFunction</code> object.
+     */
+    public SubstringFunction() {}
+
+    
+    /** Returns a substring of an XPath string-value by character index.
+     *
+     * @param context the context at the point in the
+     *         expression when the function is called
+     * @param args a list that contains two or three items
+     * 
+     * @return a <code>String</code> containing the specifed character subsequence of 
+     *     the original string or the string-value of the context node
+     * 
+     * @throws FunctionCallException if <code>args</code> has more than three
+     *     or less than two items
+     */
+    public Object call(Context context,
+                       List args) throws FunctionCallException
+    {
+        final int argc = args.size();
+        if (argc < 2 || argc > 3){
+            throw new FunctionCallException( "substring() requires two or three arguments." );
+        }
+
+        final Navigator nav = context.getNavigator();
+
+        final String str = StringFunction.evaluate(args.get(0), nav );
+        // The spec doesn't really address this case
+        if (str == null) {
+            return "";
+        }
+
+        final int stringLength = (StringLengthFunction.evaluate(args.get(0), nav )).intValue();
+
+        if (stringLength == 0) {
+            return "";
+        }
+
+        Double d1 = NumberFunction.evaluate(args.get(1), nav);
+
+        if (d1.isNaN()){
+            return "";
+        }
+        // Round the value and subtract 1 as Java strings are zero based
+        int start = RoundFunction.evaluate(d1, nav).intValue() - 1;
+
+        int substringLength = stringLength;
+        if (argc == 3){
+            Double d2 = NumberFunction.evaluate(args.get(2), nav);
+
+            if (!d2.isNaN()){
+                substringLength = RoundFunction.evaluate(d2, nav ).intValue();
+            }
+            else {
+                substringLength = 0;
+            }
+        }
+        
+        if (substringLength < 0) return "";
+
+        int end = start + substringLength;
+        if (argc == 2) end = stringLength;
+            
+        // negative start is treated as 0
+        if ( start < 0){
+            start = 0;
+        }
+        else if (start > stringLength){
+            return "";
+        }
+
+        if (end > stringLength){
+            end = stringLength;
+        }
+        else if (end < start) return "";
+        
+        if (stringLength == str.length()) {
+            // easy case; no surrogate pairs
+            return str.substring(start, end);
+        }
+        else {
+            return unicodeSubstring(str, start, end);
+        }
+        
+    }
+
+    private static String unicodeSubstring(String s, int start, int end) {
+
+        StringBuffer result = new StringBuffer(s.length());
+        for (int jChar = 0, uChar=0; uChar < end; jChar++, uChar++) {
+            char c = s.charAt(jChar);
+            if (uChar >= start) result.append(c);
+            if (c >= 0xD800) { // get the low surrogate
+                // ???? we could check here that this is indeed a low surroagte
+                // we could also catch StringIndexOutOfBoundsException
+                jChar++;
+                if (uChar >= start) result.append(s.charAt(jChar));
+            }
+        }
+        return result.toString();
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/function/SumFunction.java b/libjaxen-java/src/java/main/org/jaxen/function/SumFunction.java
new file mode 100644
index 0000000..f43de5a
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/function/SumFunction.java
@@ -0,0 +1,137 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/function/SumFunction.java,v 1.11 2006/02/05 21:47:41 elharo Exp $
+ * $Revision: 1.11 $
+ * $Date: 2006/02/05 21:47:41 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: SumFunction.java,v 1.11 2006/02/05 21:47:41 elharo Exp $
+ */
+
+
+package org.jaxen.function;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.jaxen.Context;
+import org.jaxen.Function;
+import org.jaxen.FunctionCallException;
+import org.jaxen.Navigator;
+
+/**
+ * <p><b>4.4</b> <code><i>number</i> sum(<i>node-set</i>)</code> </p>
+ * 
+ * <blockquote src="http://www.w3.org/TR/xpath#function-sum">
+ * The sum function returns the sum, for each node in the argument node-set, 
+ * of the result of converting the string-values of the node to a number.
+ * </blockquote>
+ * 
+ * @author bob mcwhirter (bob @ werken.com)
+ * @see <a href="http://www.w3.org/TR/xpath#function-sum" target="_top">Section 4.4 of the XPath Specification</a>
+ */
+public class SumFunction implements Function
+{
+
+    /**
+     * Create a new <code>SumFunction</code> object.
+     */
+    public SumFunction() {}
+    
+    /** Returns the sum of its arguments.
+     *
+     * @param context the context at the point in the
+     *         expression when the function is called
+     * @param args a list that contains exactly one item, also a <code>List</code>
+     * 
+     * @return a <code>Double</code> containing the sum of the items in <code>args.get(0)</code>
+     * 
+     * @throws FunctionCallException if <code>args</code> has more or less than one item;
+     *     or if the first argument is not a <code>List</code>
+     */
+    public Object call(Context context,
+                       List args) throws FunctionCallException
+    {
+
+        if (args.size() == 1)
+        {
+            return evaluate( args.get(0),
+                             context.getNavigator() );
+        }
+
+        throw new FunctionCallException( "sum() requires one argument." );
+    }
+
+    /** 
+     * Returns the sum of the items in a list.
+     * If necessary, each item in the list is first converted to a <code>Double</code>
+     * as if by the XPath <code>number()</code> function.
+     * 
+     * @param obj a <code>List</code> of numbers to be summed
+     * @param nav ignored
+     * 
+     * @return the sum of the list
+     * 
+     * @throws FunctionCallException if <code>obj</code> is not a <code>List</code>
+     */
+    public static Double evaluate(Object obj,
+                                  Navigator nav) throws FunctionCallException
+    {
+        double sum  = 0;
+
+        if (obj instanceof List)
+        {
+            Iterator nodeIter = ((List)obj).iterator();
+            while ( nodeIter.hasNext() )
+            {
+                double term = NumberFunction.evaluate( nodeIter.next(),
+                                                nav ).doubleValue();
+                sum += term;
+            }
+        }
+        else
+        {
+            throw new FunctionCallException("The argument to the sum function must be a node-set");
+        }
+
+        return new Double(sum);
+    }
+    
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/function/TranslateFunction.java b/libjaxen-java/src/java/main/org/jaxen/function/TranslateFunction.java
new file mode 100644
index 0000000..4da8285
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/function/TranslateFunction.java
@@ -0,0 +1,253 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/function/TranslateFunction.java,v 1.10 2006/02/05 21:47:41 elharo Exp $
+ * $Revision: 1.10 $
+ * $Date: 2006/02/05 21:47:41 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: TranslateFunction.java,v 1.10 2006/02/05 21:47:41 elharo Exp $
+ */
+
+
+package org.jaxen.function;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.jaxen.Context;
+import org.jaxen.Function;
+import org.jaxen.FunctionCallException;
+import org.jaxen.Navigator;
+
+/**
+ * <p>
+ * <b>4.2</b>
+ * <code><i>string</i> translate(<i>string</i>,<i>string</i>,<i>string</i>)</code>
+ * </p>
+ * 
+ * <blockquote src="http://www.w3.org/TR/xpath#function-translate">
+ * <p>
+ * The <b><a href="http://www.w3.org/TR/xpath#function-translate">translate</a></b> function
+ * returns the first argument string with occurrences of characters in
+ * the second argument string replaced by the character at the
+ * corresponding position in the third argument string. For example,
+ * <code>translate("bar","abc","ABC")</code> returns the string
+ * <code>BAr</code>. If there is a character in the second argument
+ * string with no character at a corresponding position in the third
+ * argument string (because the second argument string is longer than
+ * the third argument string), then occurrences of that character in the
+ * first argument string are removed. For example,
+ * <code>translate("--aaa--","abc-","ABC")</code> returns
+ * <code>"AAA"</code>. If a character occurs more than once in the
+ * second argument string, then the first occurrence determines the
+ * replacement character. If the third argument string is longer than
+ * the second argument string, then excess characters are ignored.
+ * </p>
+ * 
+ * <blockquote> <b>NOTE: </b>The <b>translate</b> function is not a
+ * sufficient solution for case conversion in all languages. A future
+ * version of XPath may provide additional functions for case
+ * conversion.</blockquote>
+ * 
+ * </blockquote>
+ * 
+ * @author Jan Dvorak ( jan.dvorak @ mathan.cz )
+ * 
+ * @see <a href="http://www.w3.org/TR/xpath#function-translate"
+ *      target="_top">Section 4.2 of the XPath Specification</a>
+ */
+public class TranslateFunction implements Function
+{
+
+     /* The translation is done thru a HashMap. Performance tip (for anyone
+      * who needs to improve the performance of this particular function):
+      * Cache the HashMaps, once they are constructed. */
+    
+    /**
+     * Create a new <code>TranslateFunction</code> object.
+     */
+    public TranslateFunction() {}
+    
+    
+    /** Returns a copy of the first argument in which
+     * characters found in the second argument are replaced by
+     * corresponding characters from the third argument.
+     *
+     * @param context the context at the point in the
+     *         expression when the function is called
+     * @param args a list that contains exactly three items
+     * 
+     * @return a <code>String</code> built from <code>args.get(0)</code> 
+     *     in which occurrences of characters in <code>args.get(1)</code> 
+     *     are replaced by the corresponding characters in <code>args.get(2)</code> 
+     * 
+     * @throws FunctionCallException if <code>args</code> does not have exactly three items
+     */
+    public Object call(Context context,
+                       List args) throws FunctionCallException
+    {
+        if (args.size() == 3) {
+            return evaluate( args.get(0),
+                             args.get(1),
+                             args.get(2),
+                             context.getNavigator() );
+        }
+
+        throw new FunctionCallException( "translate() requires three arguments." );
+    }
+
+    /** 
+     * Returns a copy of <code>strArg</code> in which
+     * characters found in <code>fromArg</code> are replaced by
+     * corresponding characters from <code>toArg</code>.
+     * If necessary each argument is first converted to it string-value
+     * as if by the XPath <code>string()</code> function.
+     * 
+     * @param strArg the base string
+     * @param fromArg the characters to be replaced
+     * @param toArg the characters they will be replaced by
+     * @param nav the <code>Navigator</code> used to calculate the string-values of the arguments.
+     * 
+     * @return a copy of <code>strArg</code> in which
+     *  characters found in <code>fromArg</code> are replaced by
+     *  corresponding characters from <code>toArg</code>
+     *  
+     * @throws FunctionCallException if one of the arguments is a malformed Unicode string;
+     *     that is, if surrogate characters don't line up properly
+     * 
+     */
+    public static String evaluate(Object strArg,
+                                  Object fromArg,
+                                  Object toArg,
+                                  Navigator nav) throws FunctionCallException
+    {
+        String inStr = StringFunction.evaluate( strArg, nav );
+        String fromStr = StringFunction.evaluate( fromArg, nav );
+        String toStr = StringFunction.evaluate( toArg, nav );
+    
+        // Initialize the mapping in a HashMap
+        Map characterMap = new HashMap();
+        String[] fromCharacters = toUnicodeCharacters(fromStr);
+        String[] toCharacters = toUnicodeCharacters(toStr);
+        int fromLen = fromCharacters.length;
+        int toLen = toCharacters.length;
+        for ( int i = 0; i < fromLen; i++ ) {
+            String cFrom = fromCharacters[i];
+            if ( characterMap.containsKey( cFrom ) ) {
+                // We've seen the character before, ignore
+                continue;
+            }
+            
+            if ( i < toLen ) {
+                // Will change
+                characterMap.put( cFrom, toCharacters[i] );
+            } 
+            else {
+                // Will delete
+                characterMap.put( cFrom, null );
+            }
+        }
+
+        // Process the input string thru the map
+        StringBuffer outStr = new StringBuffer( inStr.length() );
+        String[] inCharacters = toUnicodeCharacters(inStr);
+        int inLen = inCharacters.length;
+        for ( int i = 0; i < inLen; i++ ) {
+            String cIn = inCharacters[i];
+            if ( characterMap.containsKey( cIn ) ) {
+                String cTo = (String) characterMap.get( cIn );
+                if ( cTo != null ) {
+                    outStr.append( cTo );
+                }
+            } 
+            else {
+                outStr.append( cIn );
+            }
+        }
+    
+        return outStr.toString();
+    }
+
+    private static String[] toUnicodeCharacters(String s) throws FunctionCallException {
+
+        String[] result = new String[s.length()];
+        int stringLength = 0;
+        for (int i = 0; i < s.length(); i++) {
+            char c1 = s.charAt(i);
+            if (isHighSurrogate(c1)) {
+                try {
+                    char c2 = s.charAt(i+1);
+                    if (isLowSurrogate(c2)) {
+                        result[stringLength] = (c1 + "" + c2).intern();
+                        i++;
+                    }
+                    else {
+                        throw new FunctionCallException("Mismatched surrogate pair in translate function");
+                    }
+                }
+                catch (StringIndexOutOfBoundsException ex) {
+                    throw new FunctionCallException("High surrogate without low surrogate at end of string passed to translate function");
+                }
+            }
+            else {
+                result[stringLength]=String.valueOf(c1).intern();
+            }
+            stringLength++;
+        }
+        
+        if (stringLength == result.length) return result;
+        
+        // trim array
+        String[] trimmed = new String[stringLength];
+        System.arraycopy(result, 0, trimmed, 0, stringLength);
+        return trimmed;
+        
+    }
+
+    private static boolean isHighSurrogate(char c) {
+        return c >= 0xD800 && c <= 0xDBFF;
+    }
+     
+    private static boolean isLowSurrogate(char c) {
+        return c >= 0xDC00 && c <= 0xDFFF;
+    }
+     
+}
\ No newline at end of file
diff --git a/libjaxen-java/src/java/main/org/jaxen/function/TrueFunction.java b/libjaxen-java/src/java/main/org/jaxen/function/TrueFunction.java
new file mode 100644
index 0000000..5d6b754
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/function/TrueFunction.java
@@ -0,0 +1,104 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/function/TrueFunction.java,v 1.9 2006/02/05 21:47:41 elharo Exp $
+ * $Revision: 1.9 $
+ * $Date: 2006/02/05 21:47:41 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: TrueFunction.java,v 1.9 2006/02/05 21:47:41 elharo Exp $
+ */
+
+
+package org.jaxen.function;
+
+import java.util.List;
+
+import org.jaxen.Context;
+import org.jaxen.Function;
+import org.jaxen.FunctionCallException;
+
+/**
+ * <p><b>4.3</b> <code><i>boolean</i> true()</code></p>
+ * 
+ * <p>Returns true.</p>
+ * 
+ * @author bob mcwhirter (bob @ werken.com)
+ * 
+ * @see <a href="http://www.w3.org/TR/xpath#function-true">XPath Specification</a>
+ */
+public class TrueFunction implements Function
+{
+
+    /**
+     * Create a new <code>TrueFunction</code> object.
+     */
+    public TrueFunction() {}
+
+    
+    /** Returns <code>Boolean.TRUE</code>
+     *
+     * @param context ignored
+     * @param args an empty list
+     * 
+     * @return <code>Boolean.TRUE</code>
+     * 
+     * @throws FunctionCallException if <code>args</code> is not empty
+     */
+    public Object call(Context context,
+                       List args) throws FunctionCallException
+    {
+        if (args.size() == 0)
+        {
+            return evaluate();
+        }
+
+        throw new FunctionCallException( "true() requires no arguments." );
+    }
+
+    /**
+     * Returns true.
+     * 
+     * @return <code>Boolean.TRUE</code>
+     */
+    public static Boolean evaluate()
+    {
+        return Boolean.TRUE;
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/function/ext/EndsWithFunction.java b/libjaxen-java/src/java/main/org/jaxen/function/ext/EndsWithFunction.java
new file mode 100644
index 0000000..71b4a00
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/function/ext/EndsWithFunction.java
@@ -0,0 +1,94 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/function/ext/EndsWithFunction.java,v 1.7 2006/02/05 21:47:42 elharo Exp $
+ * $Revision: 1.7 $
+ * $Date: 2006/02/05 21:47:42 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: EndsWithFunction.java,v 1.7 2006/02/05 21:47:42 elharo Exp $
+ */
+
+package org.jaxen.function.ext;
+
+import java.util.List;
+
+import org.jaxen.Context;
+import org.jaxen.Function;
+import org.jaxen.FunctionCallException;
+import org.jaxen.Navigator;
+import org.jaxen.function.StringFunction;
+
+/**
+ * <p><code><i>boolean</i> ends-with(<i>string</i>,<i>string</i>)</code>
+ *
+ * @author mark wilson (markw @ wilsoncom.de)
+ */
+public class EndsWithFunction implements Function
+{
+
+    public Object call(Context context,
+                       List args) throws FunctionCallException
+    {
+        if (args.size() == 2)
+        {
+            return evaluate( args.get(0),
+                             args.get(1),
+                             context.getNavigator() );
+        }
+
+        throw new FunctionCallException( "ends-with() requires two arguments." );
+    }
+
+    public static Boolean evaluate(Object strArg,
+                                   Object matchArg,
+                                   Navigator nav)
+    {
+        String str   = StringFunction.evaluate( strArg,
+                                                nav );
+
+        String match = StringFunction.evaluate( matchArg,
+                                                nav );
+
+        return ( str.endsWith(match)
+                 ? Boolean.TRUE
+                 : Boolean.FALSE
+                 );
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/function/ext/EvaluateFunction.java b/libjaxen-java/src/java/main/org/jaxen/function/ext/EvaluateFunction.java
new file mode 100644
index 0000000..e1da212
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/function/ext/EvaluateFunction.java
@@ -0,0 +1,107 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/function/ext/EvaluateFunction.java,v 1.10 2006/02/05 21:47:42 elharo Exp $
+ * $Revision: 1.10 $
+ * $Date: 2006/02/05 21:47:42 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: EvaluateFunction.java,v 1.10 2006/02/05 21:47:42 elharo Exp $
+ */
+
+package org.jaxen.function.ext;
+
+import java.util.Collections;
+import java.util.List;
+
+import org.jaxen.Context;
+import org.jaxen.ContextSupport;
+import org.jaxen.Function;
+import org.jaxen.FunctionCallException;
+import org.jaxen.Navigator;
+import org.jaxen.XPath;
+import org.jaxen.function.StringFunction;
+
+/**
+ * <code><i>node-set</i> evaluate(<i>string</i>)</code> 
+ *  
+ * @author Erwin Bolwidt (ejb @ klomp.org)
+ */
+public class EvaluateFunction implements Function
+{
+    public Object call( Context context, List args )
+        throws FunctionCallException
+    {
+        if ( args.size() == 1 ) {
+            return evaluate( context, args.get(0));
+        }
+
+        throw new FunctionCallException( "evaluate() requires one argument" );
+    }
+
+    public static List evaluate (Context context, Object arg)
+        throws FunctionCallException
+    {
+        List contextNodes = context.getNodeSet();
+        
+        if (contextNodes.size() == 0)
+            return Collections.EMPTY_LIST;
+      
+        Navigator nav = context.getNavigator();
+
+        String xpathString;
+        if ( arg instanceof String )
+            xpathString = (String)arg;
+        else
+            xpathString = StringFunction.evaluate(arg, nav);
+
+        try {
+            XPath xpath = nav.parseXPath(xpathString);
+            ContextSupport support = context.getContextSupport();
+            xpath.setVariableContext( support.getVariableContext() );
+            xpath.setFunctionContext( support.getFunctionContext() );
+            xpath.setNamespaceContext( support.getNamespaceContext() );
+            return xpath.selectNodes( context.duplicate() );
+        }
+        catch ( org.jaxen.saxpath.SAXPathException e ) {
+            throw new FunctionCallException(e.toString());
+        }
+    }
+}
+
diff --git a/libjaxen-java/src/java/main/org/jaxen/function/ext/LocaleFunctionSupport.java b/libjaxen-java/src/java/main/org/jaxen/function/ext/LocaleFunctionSupport.java
new file mode 100644
index 0000000..6c16768
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/function/ext/LocaleFunctionSupport.java
@@ -0,0 +1,169 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/function/ext/LocaleFunctionSupport.java,v 1.10 2006/02/05 21:47:42 elharo Exp $
+ * $Revision: 1.10 $
+ * $Date: 2006/02/05 21:47:42 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: LocaleFunctionSupport.java,v 1.10 2006/02/05 21:47:42 elharo Exp $
+ */
+
+package org.jaxen.function.ext;
+
+import java.util.List;
+import java.util.Locale;
+import java.util.StringTokenizer;
+
+import org.jaxen.Function;
+import org.jaxen.Navigator;
+import org.jaxen.function.StringFunction;
+
+/**
+ * <p>An abstract base class for Locale-specific extension 
+ * functions. This class provides convenience methods that
+ * can be inherited, specifically to find a Locale from
+ * an XPath function argument value.
+ * </p>
+ *
+ * @author <a href="mailto:jstrachan at apache.org">James Strachan</a>
+ */
+public abstract class LocaleFunctionSupport implements Function
+{
+
+    /** 
+     * Attempts to convert the given function argument value 
+     * into a Locale either via casting, extracting it from a List
+     * or looking up the named Locale using reflection.
+     *
+     * @param value is either a Locale, a List containing a Locale
+     *      or a String containing the name of a Locale
+     *      as defined by the Locale static members.
+     *
+     * @return the Locale for the value or null if one could 
+     *      not be deduced
+     */
+    protected Locale getLocale(Object value, Navigator navigator) 
+    {
+        if (value instanceof Locale)
+        {
+            return (Locale) value;
+        }
+        else if(value instanceof List)
+        {
+            List list = (List) value;
+            if ( ! list.isEmpty() ) 
+            {
+                return getLocale( list.get(0), navigator );
+            }
+        }
+        else {
+            String text = StringFunction.evaluate( value, navigator );
+            if (text != null && text.length() > 0) 
+            {
+                return findLocale( text );
+            }
+        }
+        return null;
+    }
+    
+    /** 
+     * Tries to find a Locale instance by name using 
+     * <a href="http://www.ietf.org/rfc/rfc3066.txt" target="_top">RFC 3066</a>
+     * language tags such as 'en', 'en-US', 'en-US-Brooklyn'.
+     *
+     * @param localeText the RFC 3066 language tag
+     * @return the locale for the given text or null if one could not
+     *      be found 
+     */
+    protected Locale findLocale(String localeText) {
+        StringTokenizer tokens = new StringTokenizer( localeText, "-" );
+        if (tokens.hasMoreTokens())
+        {
+            String language = tokens.nextToken();
+            if (! tokens.hasMoreTokens())
+            {                
+                return findLocaleForLanguage(language);
+            }
+            else 
+            {
+                String country = tokens.nextToken();
+                if (! tokens.hasMoreTokens())
+                {
+                    return new Locale(language, country);
+                }
+                else 
+                {
+                    String variant = tokens.nextToken();
+                    return new Locale(language, country, variant);
+                }
+            }
+        }
+        return null;
+    }
+    
+    /** 
+     * Finds the locale with the given language name with no country
+     * or variant, such as Locale.ENGLISH or Locale.FRENCH
+     *
+     * @param language the language code to look for
+     * @return the locale for the given language or null if one could not
+     *      be found 
+     */
+    protected Locale findLocaleForLanguage(String language) {
+        Locale[] locales = Locale.getAvailableLocales();
+        for ( int i = 0, size = locales.length; i < size; i++ ) 
+        {
+            Locale locale = locales[i];
+            if ( language.equals( locale.getLanguage() ) ) 
+            {
+                String country = locale.getCountry();
+                if ( country == null || country.length() == 0 ) 
+                {
+                    String variant = locale.getVariant();
+                    if ( variant == null || variant.length() == 0 ) 
+                    {
+                        return locale;
+                    }
+                }
+            }
+        }    
+        return null;
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/function/ext/LowerFunction.java b/libjaxen-java/src/java/main/org/jaxen/function/ext/LowerFunction.java
new file mode 100644
index 0000000..123e15c
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/function/ext/LowerFunction.java
@@ -0,0 +1,117 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/function/ext/LowerFunction.java,v 1.11 2006/02/05 21:47:42 elharo Exp $
+ * $Revision: 1.11 $
+ * $Date: 2006/02/05 21:47:42 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: LowerFunction.java,v 1.11 2006/02/05 21:47:42 elharo Exp $
+ */
+
+package org.jaxen.function.ext;
+
+import java.util.List;
+import java.util.Locale;
+
+import org.jaxen.Context;
+import org.jaxen.FunctionCallException;
+import org.jaxen.Navigator;
+import org.jaxen.function.StringFunction;
+
+/**
+ * <p><code><i>string</i> lower-case(<i>string</i>)</code>
+ *
+ * This function can take a second parameter of the 
+ * <code>Locale</code> to use for the String conversion.
+ * </p>
+ *
+ * <p>
+ * For example
+ *
+ * <code>lower-case( /foo/bar )</code>
+ * <code>lower-case( /foo/@name, $myLocale )</code>
+ * </p>
+ *
+ * @author mark wilson (markw at wilsoncom.de)
+ * @author <a href="mailto:jstrachan at apache.org">James Strachan</a>
+ */
+public class LowerFunction extends LocaleFunctionSupport
+{
+
+    public Object call(Context context,
+                       List args) throws FunctionCallException
+    {
+        Navigator navigator = context.getNavigator();
+        int size = args.size();
+        if (size > 0)
+        {
+            Object text = args.get(0);
+            Locale locale = null;
+            if (size > 1)
+            {  
+                locale = getLocale( args.get(1), navigator );
+            }
+            return evaluate( text, locale, navigator );
+        }
+        throw new FunctionCallException( "lower-case() requires at least one argument." );
+    }
+
+    /**
+     * Converts the given string value to lower case using an optional Locale
+     * 
+     * @param strArg the value which gets converted to a String
+     * @param locale the Locale to use for the conversion or null
+     *        English should be used
+     * @param nav the Navigator to use
+     */
+    public static String evaluate(Object strArg,
+                                  Locale locale,
+                                  Navigator nav)
+    {
+
+        String str   = StringFunction.evaluate( strArg,
+                                                nav );
+        // it might be possible to use the xml:lang attribute to
+        // pick a default locale
+        if (locale == null) locale = Locale.ENGLISH;
+        return str.toLowerCase(locale);
+        
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/function/ext/MatrixConcatFunction.java b/libjaxen-java/src/java/main/org/jaxen/function/ext/MatrixConcatFunction.java
new file mode 100644
index 0000000..1cc62ba
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/function/ext/MatrixConcatFunction.java
@@ -0,0 +1,165 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/function/ext/MatrixConcatFunction.java,v 1.6 2006/02/05 21:47:42 elharo Exp $
+ * $Revision: 1.6 $
+ * $Date: 2006/02/05 21:47:42 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: MatrixConcatFunction.java,v 1.6 2006/02/05 21:47:42 elharo Exp $
+ */
+
+package org.jaxen.function.ext;
+
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.List;
+
+import org.jaxen.Context;
+import org.jaxen.Function;
+import org.jaxen.Navigator;
+import org.jaxen.function.StringFunction;
+
+/** <p><b>Extension Function</b> <code><i>boolean</i> matrix-concat(<i>nodeSet</i>,<i>nodeSet</i>,<i>nodeSet*</i>)</code> 
+  * 
+  * @author James Pereira (JPereira at CT.BBD.CO.ZA)
+  */
+
+public class MatrixConcatFunction implements Function {
+    
+    public Object call(Context context, List args) {
+        if ( args.size() >= 2 ) {
+            return evaluate(args, context.getNavigator());
+        }
+        return null;
+    }
+    
+    public static Object evaluate(List list, Navigator nav) {        
+        ArrayList matrix = new ArrayList();       
+        
+        Iterator argIter = list.iterator();
+
+        while (argIter.hasNext()) {
+            ArrayList v = new ArrayList();
+            Object obj = argIter.next();
+            if (obj instanceof List) {
+                List args = (List) obj;
+                for ( int i = 0, size = args.size(); i < size; i++ ) {
+                    v.add( StringFunction.evaluate( args.get(i), nav ) );
+                }
+            }
+            else {
+                v.add( StringFunction.evaluate( obj, nav ) );
+            }
+            matrix.add(v);
+        }
+        
+        ArrayList result = new ArrayList();
+        Enumeration elemList = new MatrixEnum( matrix );
+        while (elemList.hasMoreElements()) {
+            Object obj = elemList.nextElement();
+            if (obj instanceof List) {
+                StringBuffer text = new StringBuffer(127);
+                List args = (List) obj;
+                for (Iterator it = args.iterator(); it.hasNext(); ) {
+                    text.append(it.next());
+                }
+                result.add( text.toString() );
+            }
+            else {
+                result.add( obj );
+            }
+        }
+        return result;
+    }
+    
+    public static class MatrixEnum implements Enumeration {
+        private ArrayList m_source;
+        private int m_maxSize = 0;
+        private int m_currIdx = -1;
+        
+        public MatrixEnum (ArrayList _source) {
+            m_source = _source;
+            
+            for ( Iterator iter = m_source.iterator(); iter.hasNext(); ) {
+                ArrayList element = (ArrayList) iter.next();
+                int size = element.size();
+                if (size > m_maxSize) {
+                    m_maxSize = size;
+                }
+            }
+        }
+        
+        public MatrixEnum (ArrayList _source, int _maxSize) {
+            m_source = _source;
+            m_maxSize = _maxSize;
+        }
+        
+        public boolean hasMoreElements() {
+            if ((m_maxSize != 0) && (++m_currIdx < m_maxSize)) {
+                return true;
+            }
+            else {
+                return false;
+            }
+        }
+        
+        public Object nextElement() {
+            ArrayList result = new ArrayList();
+            for ( Iterator iter = m_source.iterator(); iter.hasNext(); ) {
+                ArrayList element = (ArrayList) iter.next();
+                int size = element.size();
+                if ( m_currIdx < size ) {
+                    result.add( element.get( m_currIdx ) );
+                }
+                else {
+                    if ( size > 0 ) {
+                        result.add( element.get( size - 1 ) );
+                    }
+                    else {
+                        // XXXX: what to do now?
+                        result.add( "" );
+                    }
+                }
+            }
+            return result;
+        }
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/function/ext/UpperFunction.java b/libjaxen-java/src/java/main/org/jaxen/function/ext/UpperFunction.java
new file mode 100644
index 0000000..b69032c
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/function/ext/UpperFunction.java
@@ -0,0 +1,115 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/function/ext/UpperFunction.java,v 1.11 2006/02/05 21:47:42 elharo Exp $
+ * $Revision: 1.11 $
+ * $Date: 2006/02/05 21:47:42 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: UpperFunction.java,v 1.11 2006/02/05 21:47:42 elharo Exp $
+ */
+
+package org.jaxen.function.ext;
+
+import java.util.List;
+import java.util.Locale;
+
+import org.jaxen.Context;
+import org.jaxen.FunctionCallException;
+import org.jaxen.Navigator;
+import org.jaxen.function.StringFunction;
+
+/**
+ * <p><code><i>string</i> upper-case(<i>string</i>)</code>
+ *
+ * This function can take a second parameter of the 
+ * <code>Locale</code> to use for the String conversion.
+ * </p>
+ *
+ * <p>
+ * For example
+ *
+ * <code>upper-case( /foo/bar )</code>
+ * <code>upper-case( /foo/@name, $myLocale )</code>
+ * </p>
+ *
+ * @author mark wilson (markw at wilsoncom.de)
+ * @author <a href="mailto:jstrachan at apache.org">James Strachan</a>
+ */
+public class UpperFunction extends LocaleFunctionSupport
+{
+    public Object call(Context context,
+                       List args) throws FunctionCallException
+    {
+        Navigator navigator = context.getNavigator();
+        int size = args.size();
+        if (size > 0)
+        {
+            Object text = args.get(0);
+            Locale locale = null;
+            if (size > 1)
+            {  
+                locale = getLocale( args.get(1), navigator );
+            }
+            return evaluate( text, locale, navigator );
+        }
+        throw new FunctionCallException( "upper-case() requires at least one argument." );
+    }
+
+    /**
+     * Converts the given string value to upper case using an optional Locale
+     * 
+     * @param strArg the value which gets converted to a String
+     * @param locale the Locale to use for the conversion or null if
+     *        English should be used
+     * @param nav the Navigator to use
+     */
+    public static String evaluate(Object strArg,
+                                  Locale locale,
+                                  Navigator nav)
+    {
+
+        String str   = StringFunction.evaluate( strArg,
+                                                nav );
+        // it might be possible to use the xml:lang attribute to
+        // pick a default locale
+        if (locale == null) locale = Locale.ENGLISH;
+        return str.toUpperCase(locale);
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/function/ext/package.html b/libjaxen-java/src/java/main/org/jaxen/function/ext/package.html
new file mode 100644
index 0000000..86c2538
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/function/ext/package.html
@@ -0,0 +1,13 @@
+<html>
+	<head>
+		<title>
+			org.jaxen.function.ext.*
+		</title>
+	</head>
+
+	<body>
+		<p>
+			Extension functions to the standard XPath function library.
+		</p>
+	</body>
+</html>
diff --git a/libjaxen-java/src/java/main/org/jaxen/function/package.html b/libjaxen-java/src/java/main/org/jaxen/function/package.html
new file mode 100644
index 0000000..7f5bf23
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/function/package.html
@@ -0,0 +1,13 @@
+<html>
+	<head>
+		<title>
+			org.jaxen.function.*
+		</title>
+	</head>
+
+	<body>
+		<p>
+			Standard XPath function library.
+		</p>
+	</body>
+</html>
diff --git a/libjaxen-java/src/java/main/org/jaxen/function/xslt/DocumentFunction.java b/libjaxen-java/src/java/main/org/jaxen/function/xslt/DocumentFunction.java
new file mode 100644
index 0000000..9dab6fa
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/function/xslt/DocumentFunction.java
@@ -0,0 +1,89 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/function/xslt/DocumentFunction.java,v 1.6 2006/02/05 21:47:42 elharo Exp $
+ * $Revision: 1.6 $
+ * $Date: 2006/02/05 21:47:42 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: DocumentFunction.java,v 1.6 2006/02/05 21:47:42 elharo Exp $
+ */
+
+
+package org.jaxen.function.xslt;
+
+import java.util.List;
+
+import org.jaxen.Context;
+import org.jaxen.Function;
+import org.jaxen.FunctionCallException;
+import org.jaxen.Navigator;
+import org.jaxen.function.StringFunction;
+
+/**
+ * Implements the XSLT document() function
+ *
+ *  @author <a href="mailto:jstrachan at apache.org">James Strachan</a>
+ */
+public class DocumentFunction implements Function
+{
+
+    public Object call(Context context,
+                       List args) throws FunctionCallException
+    {
+        if (args.size() == 1)
+        {
+            Navigator nav = context.getNavigator();
+
+            String    url = StringFunction.evaluate( args.get( 0 ),
+                                                     nav );
+
+            return evaluate( url,
+                             nav );
+        }
+
+        throw new FunctionCallException( "document() requires one argument." );
+    }
+
+    public static Object evaluate(String url,
+                                  Navigator nav) throws FunctionCallException
+    {
+        return nav.getDocument( url );
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/function/xslt/package.html b/libjaxen-java/src/java/main/org/jaxen/function/xslt/package.html
new file mode 100644
index 0000000..e276b63
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/function/xslt/package.html
@@ -0,0 +1,13 @@
+<html>
+	<head>
+		<title>
+			org.jaxen.function.xslt.*
+		</title>
+	</head>
+
+	<body>
+		<p>
+			XPath functions which are defined in XSLT.
+		</p>
+	</body>
+</html>
diff --git a/libjaxen-java/src/java/main/org/jaxen/javabean/DocumentNavigator.java b/libjaxen-java/src/java/main/org/jaxen/javabean/DocumentNavigator.java
new file mode 100644
index 0000000..5cda34e
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/javabean/DocumentNavigator.java
@@ -0,0 +1,374 @@
+/*
+ $Id: DocumentNavigator.java,v 1.8 2006/06/03 20:35:31 elharo Exp $
+
+ Copyright 2003 The Werken Company. All Rights Reserved.
+ 
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+  * Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+
+  * Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+
+  * Neither the name of the Jaxen Project nor the names of its
+    contributors may be used to endorse or promote products derived 
+    from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ */
+package org.jaxen.javabean;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.InvocationTargetException;
+import java.util.Iterator;
+import java.util.Collection;
+
+import org.jaxen.DefaultNavigator;
+import org.jaxen.FunctionCallException;
+import org.jaxen.NamedAccessNavigator;
+import org.jaxen.Navigator;
+import org.jaxen.XPath;
+import org.jaxen.JaxenConstants;
+import org.jaxen.util.SingleObjectIterator;
+
+/** 
+ * Interface for navigating around a JavaBean object model.
+ *
+ * <p>
+ * This class is not intended for direct usage, but is
+ * used by the Jaxen engine during evaluation.
+ * </p>
+ *
+ * @see XPath
+ *
+ * @author <a href="mailto:bob at werken.com">bob mcwhirter</a>
+ */
+public class DocumentNavigator
+    extends DefaultNavigator
+    implements NamedAccessNavigator
+{
+
+    /**
+     * 
+     */
+    private static final long serialVersionUID = -1768605107626726499L;
+
+    /** Empty Class array. */
+    private static final Class[] EMPTY_CLASS_ARRAY = new Class[0];
+
+    /** Empty Object array. */
+    private static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];
+
+    /** Singleton implementation.
+     */
+    private static final DocumentNavigator instance = new DocumentNavigator();
+
+    /** Retrieve the singleton instance of this <code>DocumentNavigator</code>.
+     */
+    public static Navigator getInstance()
+    {
+        return instance;
+    }
+
+    public boolean isElement(Object obj)
+    {
+        return (obj instanceof Element);
+    }
+
+    public boolean isComment(Object obj)
+    {
+        return false;
+    }
+
+    public boolean isText(Object obj)
+    {
+        return ( obj instanceof String );
+    }
+
+    public boolean isAttribute(Object obj)
+    {
+        return false;
+    }
+
+    public boolean isProcessingInstruction(Object obj)
+    {
+        return false;
+    }
+
+    public boolean isDocument(Object obj)
+    {
+        return false;
+    }
+
+    public boolean isNamespace(Object obj)
+    {
+        return false;
+    }
+
+    public String getElementName(Object obj)
+    {
+        return ((Element)obj).getName();
+    }
+
+    public String getElementNamespaceUri(Object obj)
+    {
+        return "";
+    }
+
+    public String getElementQName(Object obj)
+    {
+        return "";
+    }
+
+    public String getAttributeName(Object obj)
+    {
+        return "";
+    }
+
+    public String getAttributeNamespaceUri(Object obj)
+    {
+        return "";
+    }
+
+    public String getAttributeQName(Object obj)
+    {
+        return "";
+    }
+
+    public Iterator getChildAxisIterator(Object contextNode)
+    {
+        return JaxenConstants.EMPTY_ITERATOR;
+    }
+
+    /**
+     * Retrieves an <code>Iterator</code> over the child elements that
+     * match the supplied name.
+     *
+     * @param contextNode  the origin context node
+     * @param localName  the local name of the children to return, always present
+     * @param namespacePrefix  the prefix of the namespace of the children to return
+     * @param namespaceURI  the namespace URI of the children to return
+     * @return an Iterator that traverses the named children, or null if none
+     */
+    public Iterator getChildAxisIterator(Object contextNode,
+                                         String localName,
+                                         String namespacePrefix,
+                                         String namespaceURI)
+    {
+        Class cls = ((Element)contextNode).getObject().getClass();
+
+        String methodName = javacase( localName );
+
+        Method method = null;
+        
+        try
+        {
+            method = cls.getMethod( "get" + methodName, EMPTY_CLASS_ARRAY );
+        }
+        catch (NoSuchMethodException e)
+        {
+            try
+            {
+                method = cls.getMethod( "get" + methodName + "s", EMPTY_CLASS_ARRAY );
+            }
+            catch (NoSuchMethodException ee)
+            {
+                try
+                {
+                    method = cls.getMethod( localName, EMPTY_CLASS_ARRAY );
+                }
+                catch (NoSuchMethodException eee)
+                {
+                    method = null;
+                }
+            }
+        }
+
+        if ( method == null )
+        {
+            return JaxenConstants.EMPTY_ITERATOR;
+        }
+
+        try
+        {
+            Object result = method.invoke( ((Element)contextNode).getObject(), EMPTY_OBJECT_ARRAY );
+            
+            if ( result == null )
+            {
+                return JaxenConstants.EMPTY_ITERATOR;
+            } 
+            
+            if ( result instanceof Collection )
+            {
+                return new ElementIterator( (Element) contextNode, localName, ((Collection)result).iterator() );
+            }
+            
+            if ( result.getClass().isArray() )
+            {
+                return JaxenConstants.EMPTY_ITERATOR;
+            }
+            
+            return new SingleObjectIterator( new Element( (Element) contextNode, localName, result ) );
+        }
+        catch (IllegalAccessException e)
+        {
+            // swallow
+        }
+        catch (InvocationTargetException e)
+        {
+            // swallow
+        }
+
+        return JaxenConstants.EMPTY_ITERATOR;
+    }
+
+    public Iterator getParentAxisIterator(Object contextNode)
+    {
+        if ( contextNode instanceof Element )
+        {
+            return new SingleObjectIterator( ((Element)contextNode).getParent() );
+        }
+
+        return JaxenConstants.EMPTY_ITERATOR;
+    }
+
+    public Iterator getAttributeAxisIterator(Object contextNode)
+    {
+        return JaxenConstants.EMPTY_ITERATOR;
+    }
+
+    /**
+     * Retrieves an <code>Iterator</code> over the attribute elements that
+     * match the supplied name.
+     *
+     * @param contextNode  the origin context node
+     * @param localName  the local name of the attributes to return, always present
+     * @param namespacePrefix  the prefix of the namespace of the attributes to return
+     * @param namespaceURI  the namespace URI of the attributes to return
+     * @return an Iterator that traverses the named attributes, not null
+     */
+    public Iterator getAttributeAxisIterator(Object contextNode,
+                                             String localName,
+                                             String namespacePrefix,
+                                             String namespaceURI) {
+        return JaxenConstants.EMPTY_ITERATOR;
+    }
+        
+    public Iterator getNamespaceAxisIterator(Object contextNode)
+    {
+        return JaxenConstants.EMPTY_ITERATOR;
+    }
+
+    public Object getDocumentNode(Object contextNode)
+    {
+        return null;
+    }
+
+    public Object getParentNode(Object contextNode)
+    {
+        if ( contextNode instanceof Element )
+        {
+            return ((Element)contextNode).getParent();
+        }
+
+        return JaxenConstants.EMPTY_ITERATOR;
+    }
+
+    public String getTextStringValue(Object obj)
+    {
+        if ( obj instanceof Element )
+        {
+            return ((Element)obj).getObject().toString();
+        }
+        return obj.toString();
+    }
+
+    public String getElementStringValue(Object obj)
+    {
+        if ( obj instanceof Element )
+        {
+            return ((Element)obj).getObject().toString();
+        }
+        return obj.toString();
+    }
+
+    public String getAttributeStringValue(Object obj)
+    {
+        return obj.toString();
+    }
+
+    public String getNamespaceStringValue(Object obj)
+    {
+        return obj.toString();
+    }
+
+    public String getNamespacePrefix(Object obj)
+    {
+        return null;
+    }
+
+    public String getCommentStringValue(Object obj)
+    {
+        return null;
+    }
+    
+    public String translateNamespacePrefixToUri(String prefix, Object context)
+    {
+        return null;
+    }
+    
+    public short getNodeType(Object node) 
+    {
+        return 0;
+    }
+    
+    public Object getDocument(String uri) throws FunctionCallException
+    {
+        return null;
+    }
+
+    public String getProcessingInstructionTarget(Object obj)
+    {
+        return null;
+    }
+
+    public String getProcessingInstructionData(Object obj)
+    {
+        return null;
+    }
+
+    public XPath parseXPath(String xpath)
+        throws org.jaxen.saxpath.SAXPathException
+    {
+        return new JavaBeanXPath( xpath );
+    }
+
+    protected String javacase(String name)
+    {
+        if ( name.length() == 0 )
+        {
+            return name;
+        }
+        else if ( name.length() == 1 )
+        {
+            return name.toUpperCase();
+        } 
+
+        return name.substring( 0, 1 ).toUpperCase() + name.substring( 1 );
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/javabean/Element.java b/libjaxen-java/src/java/main/org/jaxen/javabean/Element.java
new file mode 100644
index 0000000..5df348d
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/javabean/Element.java
@@ -0,0 +1,32 @@
+package org.jaxen.javabean;
+
+public class Element
+{
+    private Element parent;
+    private String name;
+    private Object object;
+
+    public Element(Element parent,
+                   String name,
+                   Object object)
+    {
+        this.parent = parent;
+        this.name   = name;
+        this.object = object;
+    }
+
+    public Element getParent()
+    {
+        return this.parent;
+    }
+
+    public String getName()
+    {
+        return this.name;
+    }
+
+    public Object getObject()
+    {
+        return this.object;
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/javabean/ElementIterator.java b/libjaxen-java/src/java/main/org/jaxen/javabean/ElementIterator.java
new file mode 100644
index 0000000..c31a60f
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/javabean/ElementIterator.java
@@ -0,0 +1,37 @@
+package org.jaxen.javabean;
+
+import java.util.Iterator;
+
+public class ElementIterator
+    implements Iterator
+{
+    private Element parent;
+    private String name;
+    private Iterator iterator;
+
+    public ElementIterator(Element parent,
+                           String name,
+                           Iterator iterator)
+    {
+        this.parent    = parent;
+        this.name     = name;
+        this.iterator = iterator;
+    }
+
+    public boolean hasNext()
+    {
+        return this.iterator.hasNext();
+    }
+
+    public Object next()
+    {
+        return new Element( parent,
+                            this.name,
+                            this.iterator.next() );
+    }
+
+    public void remove()
+    {
+        throw new UnsupportedOperationException();
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/javabean/JavaBeanXPath.java b/libjaxen-java/src/java/main/org/jaxen/javabean/JavaBeanXPath.java
new file mode 100644
index 0000000..cfac8ae
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/javabean/JavaBeanXPath.java
@@ -0,0 +1,158 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/javabean/JavaBeanXPath.java,v 1.6 2006/06/03 20:36:00 elharo Exp $
+ * $Revision: 1.6 $
+ * $Date: 2006/06/03 20:36:00 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: JavaBeanXPath.java,v 1.6 2006/06/03 20:36:00 elharo Exp $
+ */
+
+package org.jaxen.javabean;
+
+import org.jaxen.Context;
+import org.jaxen.BaseXPath;
+import org.jaxen.JaxenException;
+
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+
+/** An XPath implementation for JavaBeans.
+ *
+ * <p>This is the main entry point for matching an XPath against a JavaBean
+ * tree.  You create a compiled XPath object, then match it against
+ * one or more context nodes using the {@link #selectNodes(Object)}
+ * method, as in the following example:</p>
+ *
+ * <pre>
+ * Node node = ...;
+ * XPath path = new JavaBeanXPath("a/b/c");
+ * List results = path.selectNodes(node);
+ * </pre>
+ *
+ * @see BaseXPath
+ *
+ * @author <a href="mailto:bob at werken.com">bob mcwhirter</a>
+ *
+ * @version $Revision: 1.6 $
+ */
+public class JavaBeanXPath extends BaseXPath
+{
+    /**
+     * 
+     */
+    private static final long serialVersionUID = -1567521943360266313L;
+
+    /** Construct given an XPath expression string.
+     *
+     *  @param xpathExpr The XPath expression.
+     *
+     *  @throws JaxenException if there is a syntax error while
+     *          parsing the expression
+     */
+    public JavaBeanXPath(String xpathExpr) throws JaxenException
+    {
+        super( xpathExpr, DocumentNavigator.getInstance() );
+    }
+
+    protected Context getContext(Object node)
+    {
+        if ( node instanceof Context )
+        {
+            return (Context) node;
+        }
+
+        if ( node instanceof Element )
+        {
+            return super.getContext( node );
+        }
+
+        if ( node instanceof List )
+        {
+            List newList = new ArrayList();
+
+            for ( Iterator listIter = ((List)node).iterator();
+                  listIter.hasNext(); )
+            {
+                newList.add( new Element( null, "root", listIter.next() ) );
+            }
+
+            return super.getContext( newList );
+        }
+
+        return super.getContext( new Element( null, "root", node ) );
+    }
+
+    public Object evaluate(Object node)
+        throws JaxenException
+    {
+        Object result = super.evaluate( node );
+
+        if ( result instanceof Element )
+        {
+            return ((Element)result).getObject();
+        }
+        else if ( result instanceof Collection )
+        {
+            List newList = new ArrayList();
+
+            for ( Iterator listIter = ((Collection)result).iterator();
+                  listIter.hasNext(); )
+            {
+                Object member = listIter.next();
+
+                if ( member instanceof Element )
+                {
+                    newList.add( ((Element)member).getObject() );
+                }
+                else
+                {
+                    newList.add( member );
+                }
+            }
+
+            return newList;
+        }
+
+        return result;
+    }
+} 
diff --git a/libjaxen-java/src/java/main/org/jaxen/javabean/package.html b/libjaxen-java/src/java/main/org/jaxen/javabean/package.html
new file mode 100644
index 0000000..e7db732
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/javabean/package.html
@@ -0,0 +1,13 @@
+<html>
+	<head>
+		<title>
+			org.jaxen.javabean.*
+		</title>
+	</head>
+
+	<body>
+		<p>
+			Navigation for JavaBeans.
+		</p>
+	</body>
+</html>
diff --git a/libjaxen-java/src/java/main/org/jaxen/jdom/DocumentNavigator.java b/libjaxen-java/src/java/main/org/jaxen/jdom/DocumentNavigator.java
new file mode 100644
index 0000000..c6f30fb
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/jdom/DocumentNavigator.java
@@ -0,0 +1,583 @@
+package org.jaxen.jdom;
+
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/jdom/DocumentNavigator.java,v 1.36 2006/09/21 11:48:05 elharo Exp $
+ * $Revision: 1.36 $
+ * $Date: 2006/09/21 11:48:05 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2005 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Jaxen Project and was originally
+ * created by bob mcwhirter <bob at werken.com> and
+ * James Strachan <jstrachan at apache.org>.  For more information on the
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ *
+ * $Id: DocumentNavigator.java,v 1.36 2006/09/21 11:48:05 elharo Exp $
+*/
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.jaxen.DefaultNavigator;
+import org.jaxen.FunctionCallException;
+import org.jaxen.NamedAccessNavigator;
+import org.jaxen.Navigator;
+import org.jaxen.XPath;
+import org.jaxen.JaxenConstants;
+import org.jaxen.saxpath.SAXPathException;
+import org.jaxen.util.SingleObjectIterator;
+import org.jdom.Attribute;
+import org.jdom.CDATA;
+import org.jdom.Comment;
+import org.jdom.Document;
+import org.jdom.Element;
+import org.jdom.Namespace;
+import org.jdom.ProcessingInstruction;
+import org.jdom.Text;
+import org.jdom.input.SAXBuilder;
+
+/** 
+ * Interface for navigating around the JDOM object model.
+ *
+ * <p>
+ * This class is not intended for direct usage, but is
+ * used by the Jaxen engine during evaluation.
+ * </p>
+ *
+ * @see XPath
+ *
+ * @author <a href="mailto:bob at werken.com">bob mcwhirter</a>
+ * @author Stephen Colebourne
+ */
+public class DocumentNavigator extends DefaultNavigator implements NamedAccessNavigator
+{
+    /**
+     * 
+     */
+    private static final long serialVersionUID = -1636727587303584165L;
+
+    /** Singleton implementation.
+     */
+    private static class Singleton
+    {
+        /** Singleton instance.
+         */
+        private static DocumentNavigator instance = new DocumentNavigator();
+    }
+
+    public static Navigator getInstance()
+    {
+        return Singleton.instance;
+    }
+
+    public boolean isElement(Object obj)
+    {
+        return obj instanceof Element;
+    }
+
+    public boolean isComment(Object obj)
+    {
+        return obj instanceof Comment;
+    }
+
+    public boolean isText(Object obj)
+    {
+        return ( obj instanceof Text
+                 ||
+                 obj instanceof CDATA );
+    }
+
+    public boolean isAttribute(Object obj)
+    {
+        return obj instanceof Attribute;
+    }
+
+    public boolean isProcessingInstruction(Object obj)
+    {
+        return obj instanceof ProcessingInstruction;
+    }
+
+    public boolean isDocument(Object obj)
+    {
+        return obj instanceof Document;
+    }
+
+    public boolean isNamespace(Object obj)
+    {
+        return obj instanceof Namespace || obj instanceof XPathNamespace;
+    }
+
+    public String getElementName(Object obj)
+    {
+        Element elem = (Element) obj;
+
+        return elem.getName();
+    }
+
+    public String getElementNamespaceUri(Object obj)
+    {
+        Element elem = (Element) obj;
+        
+        String uri = elem.getNamespaceURI();
+        if ( uri != null && uri.length() == 0 ) 
+            return null;
+        else
+            return uri;
+    }
+
+    public String getAttributeName(Object obj)
+    {
+        Attribute attr = (Attribute) obj;
+
+        return attr.getName();
+    }
+
+    public String getAttributeNamespaceUri(Object obj)
+    {
+        Attribute attr = (Attribute) obj;
+
+        String uri = attr.getNamespaceURI();
+        if ( uri != null && uri.length() == 0 ) 
+            return null;
+        else
+            return uri;
+    }
+
+    public Iterator getChildAxisIterator(Object contextNode)
+    {
+        if ( contextNode instanceof Element )
+        {
+            return ((Element)contextNode).getContent().iterator();
+        }
+        else if ( contextNode instanceof Document )
+        {
+            return ((Document)contextNode).getContent().iterator();
+        }
+
+        return JaxenConstants.EMPTY_ITERATOR;
+    }
+
+    /**
+     * Retrieves an <code>Iterator</code> over the child elements that
+     * match the supplied local name and namespace URI.
+     *
+     * @param contextNode      the origin context node
+     * @param localName        the local name of the children to return, always present
+     * @param namespacePrefix  ignored; prefixes are not used when matching in XPath
+     * @param namespaceURI     the URI of the namespace of the children to return
+     * @return an Iterator     that traverses the named children, or null if none
+     */
+    public Iterator getChildAxisIterator(
+            Object contextNode, String localName, String namespacePrefix, String namespaceURI) {
+
+        if ( contextNode instanceof Element ) {
+            Element node = (Element) contextNode;
+            if (namespaceURI == null) {
+                return node.getChildren(localName).iterator();
+            }
+            return node.getChildren(localName, Namespace.getNamespace(namespacePrefix, namespaceURI)).iterator();
+        }
+        if ( contextNode instanceof Document ) {
+            Document node = (Document) contextNode;
+            
+            Element el = node.getRootElement();
+            if (el.getName().equals(localName) == false) {
+                return JaxenConstants.EMPTY_ITERATOR;
+            }
+            if (namespaceURI != null) {
+                // JDOM's equals method does not consider the prefix when comparing namespace objects
+                if (!Namespace.getNamespace(namespacePrefix, namespaceURI).equals(el.getNamespace())) {
+                    return JaxenConstants.EMPTY_ITERATOR;
+                }
+            }
+            else if(el.getNamespace() != Namespace.NO_NAMESPACE) { 
+                return JaxenConstants.EMPTY_ITERATOR; 
+            }
+            
+            return new SingleObjectIterator(el);
+        }
+
+        return JaxenConstants.EMPTY_ITERATOR;
+    }
+    
+    public Iterator getNamespaceAxisIterator(Object contextNode)
+    {
+        if ( ! ( contextNode instanceof Element ) )
+        {
+            return JaxenConstants.EMPTY_ITERATOR;
+        }
+
+        Element elem = (Element) contextNode;
+
+        Map nsMap = new HashMap();
+
+        Element current = elem;
+
+        while ( current != null ) {
+        
+            Namespace ns = current.getNamespace();
+            
+            if ( ns != Namespace.NO_NAMESPACE ) {
+                if ( !nsMap.containsKey(ns.getPrefix()) )
+                    nsMap.put( ns.getPrefix(), new XPathNamespace(elem, ns) );
+            }
+        
+            Iterator additional = current.getAdditionalNamespaces().iterator();
+
+            while ( additional.hasNext() ) {
+
+                ns = (Namespace)additional.next();
+                if ( !nsMap.containsKey(ns.getPrefix()) )
+                    nsMap.put( ns.getPrefix(), new XPathNamespace(elem, ns) );
+            }
+
+            Iterator attributes = current.getAttributes().iterator();
+
+            while ( attributes.hasNext() ) {
+
+                Attribute attribute = (Attribute)attributes.next();
+
+                Namespace attrNS = attribute.getNamespace();
+            
+                if ( attrNS != Namespace.NO_NAMESPACE ) {
+                    if ( !nsMap.containsKey(attrNS.getPrefix()) )
+                        nsMap.put( attrNS.getPrefix(), new XPathNamespace(elem, attrNS) );
+                }
+            }
+
+            if (current.getParent() instanceof Element) {
+                current = (Element)current.getParent();
+            } else {
+                current = null;
+            }
+        }
+
+        nsMap.put( "xml", new XPathNamespace(elem, Namespace.XML_NAMESPACE) );
+
+        return nsMap.values().iterator();
+    }
+
+    public Iterator getParentAxisIterator(Object contextNode)
+    {
+        Object parent = null;
+
+        if ( contextNode instanceof Document )
+        {
+            return JaxenConstants.EMPTY_ITERATOR;
+        }
+        else if ( contextNode instanceof Element )
+        {
+            parent = ((Element)contextNode).getParent();
+
+            if ( parent == null )
+            {
+                if ( ((Element)contextNode).isRootElement() )
+                {
+                    parent = ((Element)contextNode).getDocument();
+                }
+            }
+        }
+        else if ( contextNode instanceof Attribute )
+        {
+            parent = ((Attribute)contextNode).getParent();
+        }
+        else if ( contextNode instanceof XPathNamespace )
+        {
+            parent = ((XPathNamespace)contextNode).getJDOMElement();
+        }
+        else if ( contextNode instanceof ProcessingInstruction )
+        {
+            parent = ((ProcessingInstruction)contextNode).getParent();
+        }
+        else if ( contextNode instanceof Comment )
+        {
+            parent = ((Comment)contextNode).getParent();
+        }
+        else if ( contextNode instanceof Text )
+        {
+            parent = ((Text)contextNode).getParent();
+        }
+        
+        if ( parent != null )
+        {
+            return new SingleObjectIterator( parent );
+        }
+
+        return JaxenConstants.EMPTY_ITERATOR;
+    }
+
+    public Iterator getAttributeAxisIterator(Object contextNode)
+    {
+        if ( ! ( contextNode instanceof Element ) )
+        {
+            return JaxenConstants.EMPTY_ITERATOR;
+        }
+
+        Element elem = (Element) contextNode;
+
+        return elem.getAttributes().iterator();
+    }
+
+    /**
+     * Retrieves an <code>Iterator</code> over the attribute elements that
+     * match the supplied name.
+     *
+     * @param contextNode      the origin context node
+     * @param localName        the local name of the attributes to return, always present
+     * @param namespacePrefix  the prefix of the namespace of the attributes to return
+     * @param namespaceURI     the URI of the namespace of the attributes to return
+     * @return an Iterator     that traverses the named attributes, not null
+     */
+    public Iterator getAttributeAxisIterator(
+            Object contextNode, String localName, String namespacePrefix, String namespaceURI) {
+
+        if ( contextNode instanceof Element ) {
+            Element node = (Element) contextNode;
+            Namespace namespace = (namespaceURI == null ? Namespace.NO_NAMESPACE : 
+                                    Namespace.getNamespace(namespacePrefix, namespaceURI));
+            Attribute attr = node.getAttribute(localName, namespace);
+            if (attr != null) {
+                return new SingleObjectIterator(attr);
+            }
+        }
+        return JaxenConstants.EMPTY_ITERATOR;
+    }
+
+    /** Returns a parsed form of the given XPath string, which will be suitable
+     *  for queries on JDOM documents.
+     */
+    public XPath parseXPath (String xpath) throws SAXPathException
+    {
+        return new JDOMXPath(xpath);
+    }
+
+    public Object getDocumentNode(Object contextNode)
+    {
+        if ( contextNode instanceof Document )
+        {
+            return contextNode;
+        }
+
+        Element elem = (Element) contextNode;
+
+        return elem.getDocument();
+    }
+
+    public String getElementQName(Object obj)
+    {
+        Element elem = (Element) obj;
+
+        String prefix = elem.getNamespacePrefix();
+
+        if ( prefix == null || prefix.length() == 0 )
+        {
+            return elem.getName();
+        }
+
+        return prefix + ":" + elem.getName();
+    }
+
+    public String getAttributeQName(Object obj)
+    {
+        Attribute attr = (Attribute) obj;
+
+        String prefix = attr.getNamespacePrefix();
+
+        if ( prefix == null || "".equals( prefix ) )
+        {
+            return attr.getName();
+        }
+
+        return prefix + ":" + attr.getName();
+    }
+
+    public String getNamespaceStringValue(Object obj)
+    {
+        if (obj instanceof Namespace) {
+
+            Namespace ns = (Namespace) obj;
+            return ns.getURI();
+        } else {
+
+            XPathNamespace ns = (XPathNamespace) obj;
+            return ns.getJDOMNamespace().getURI();
+        }
+        
+    }
+
+    public String getNamespacePrefix(Object obj)
+    {
+        if (obj instanceof Namespace) {
+
+            Namespace ns = (Namespace) obj;
+            return ns.getPrefix();
+        } else {
+
+            XPathNamespace ns = (XPathNamespace) obj;
+            return ns.getJDOMNamespace().getPrefix();
+        }
+    }
+
+    public String getTextStringValue(Object obj)
+    {
+        if ( obj instanceof Text )
+        {
+            return ((Text)obj).getText();
+        }
+
+        if ( obj instanceof CDATA )
+        {
+            return ((CDATA)obj).getText();
+        }
+
+        return "";
+    }
+
+    public String getAttributeStringValue(Object obj)
+    {
+        Attribute attr = (Attribute) obj;
+
+        return attr.getValue();
+    }
+
+    public String getElementStringValue(Object obj)
+    {
+        Element elem = (Element) obj;
+
+        StringBuffer buf = new StringBuffer();
+
+        List     content     = elem.getContent();
+        Iterator contentIter = content.iterator();
+        Object   each        = null;
+
+        while ( contentIter.hasNext() )
+        {
+            each = contentIter.next();
+
+            if ( each instanceof Text )
+            {
+                buf.append( ((Text)each).getText() );
+            }
+            else if ( each instanceof CDATA )
+            {
+                buf.append( ((CDATA)each).getText() );
+            }
+            else if ( each instanceof Element )
+            {
+                buf.append( getElementStringValue( each ) );
+            }
+        }
+
+        return buf.toString();
+    }
+
+    public String getProcessingInstructionTarget(Object obj)
+    {
+        ProcessingInstruction pi = (ProcessingInstruction) obj;
+
+        return pi.getTarget();
+    }
+
+    public String getProcessingInstructionData(Object obj)
+    {
+        ProcessingInstruction pi = (ProcessingInstruction) obj;
+
+        return pi.getData();
+    }
+
+    public String getCommentStringValue(Object obj)
+    {
+        Comment cmt = (Comment) obj;
+
+        return cmt.getText();
+    }
+
+    public String translateNamespacePrefixToUri(String prefix, Object context)
+    {
+        Element element = null;
+        if ( context instanceof Element ) 
+        {
+            element = (Element) context;
+        }
+        else if ( context instanceof Text )
+        {
+            element = (Element)((Text)context).getParent();
+        }
+        else if ( context instanceof Attribute )
+        {
+            element = ((Attribute)context).getParent();
+        }
+        else if ( context instanceof XPathNamespace )
+        {
+            element = ((XPathNamespace)context).getJDOMElement();
+        }
+        else if ( context instanceof Comment )
+        {
+            element = (Element)((Comment)context).getParent();
+        }
+        else if ( context instanceof ProcessingInstruction )
+        {
+            element = (Element)((ProcessingInstruction)context).getParent();
+        }
+
+        if ( element != null )
+        {
+            Namespace namespace = element.getNamespace( prefix );
+
+            if ( namespace != null ) 
+            {
+                return namespace.getURI();
+            }
+        }
+        return null;
+    }
+
+    public Object getDocument(String url) throws FunctionCallException
+    {
+        try
+        {
+            SAXBuilder builder = new SAXBuilder();
+            
+            return builder.build( url );
+        }
+        catch (Exception e)
+        {
+            throw new FunctionCallException( e.getMessage() );
+        }
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/jdom/JDOMXPath.java b/libjaxen-java/src/java/main/org/jaxen/jdom/JDOMXPath.java
new file mode 100644
index 0000000..d6fd511
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/jdom/JDOMXPath.java
@@ -0,0 +1,93 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/jdom/JDOMXPath.java,v 1.8 2006/06/03 20:30:27 elharo Exp $
+ * $Revision: 1.8 $
+ * $Date: 2006/06/03 20:30:27 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: JDOMXPath.java,v 1.8 2006/06/03 20:30:27 elharo Exp $
+ */
+
+
+package org.jaxen.jdom;
+
+import org.jaxen.BaseXPath;
+import org.jaxen.JaxenException;
+
+/** An XPath implementation for the JDOM model
+ *
+ * <p>This is the main entry point for matching an XPath against a DOM
+ * tree.  You create a compiled XPath object, then match it against
+ * one or more context nodes using the {@link #selectNodes(Object)}
+ * method, as in the following example:</p>
+ *
+ * <pre>
+ * Object jdomNode = ...; // Document, Element etc.
+ * XPath path = new JDOMXPath("a/b/c");
+ * List results = path.selectNodes(jdomNode);
+ * </pre>
+ *
+ * @see BaseXPath
+ * @see <a href="http://jdom.org/">The JDOM website</a>
+ *
+ * @author <a href="mailto:bob at werken.com">bob mcwhirter</a>
+ * @author <a href="mailto:jstachan at apache.org">James Strachan</a>
+ *
+ * @version $Revision: 1.8 $
+ */
+public class JDOMXPath extends BaseXPath
+{
+    /**
+     * 
+     */
+    private static final long serialVersionUID = 6426091824802286928L;
+
+    /** Construct given an XPath expression string.
+     *
+     *  @param xpathExpr the XPath expression.
+     *
+     *  @throws JaxenException if there is a syntax error while
+     *          parsing the expression
+     */
+    public JDOMXPath(String xpathExpr) throws JaxenException
+    {
+        super( xpathExpr, DocumentNavigator.getInstance() );
+    }
+} 
diff --git a/libjaxen-java/src/java/main/org/jaxen/jdom/XPathNamespace.java b/libjaxen-java/src/java/main/org/jaxen/jdom/XPathNamespace.java
new file mode 100644
index 0000000..4601931
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/jdom/XPathNamespace.java
@@ -0,0 +1,112 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/jdom/XPathNamespace.java,v 1.7 2006/02/05 21:47:42 elharo Exp $
+ * $Revision: 1.7 $
+ * $Date: 2006/02/05 21:47:42 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: XPathNamespace.java,v 1.7 2006/02/05 21:47:42 elharo Exp $
+ */
+
+
+package org.jaxen.jdom;
+
+import org.jdom.Element;
+import org.jdom.Namespace;
+
+/** Wrapper for JDOM namespace nodes to give them a parent, as required
+ *  by the XPath data model.
+ *
+ *  @author Erwin Bolwidt
+ */
+public class XPathNamespace
+{
+    private Element jdomElement;
+
+    private Namespace jdomNamespace;
+
+    /** Creates a namespace-node wrapper for a namespace node that hasn't been
+     *  assigned to an element yet.
+     */
+    public XPathNamespace( Namespace jdomNamespace )
+    {
+        this.jdomNamespace = jdomNamespace;
+    }
+
+    /** Creates a namespace-node wrapper for a namespace node that is assigned
+     *  to the given JDOM element.
+     */
+    public XPathNamespace( Element jdomElement, Namespace jdomNamespace )
+    {
+        this.jdomElement = jdomElement;
+        this.jdomNamespace = jdomNamespace;
+    }
+
+    /** Returns the JDOM element from which this namespace node has been 
+     *  retrieved. The result may be null when the namespace node has not yet
+     *  been assigned to an element.
+     */
+    public Element getJDOMElement()
+    {
+        return jdomElement;
+    }
+
+    /** Sets or changes the element to which this namespace node is assigned.
+     */
+    public void setJDOMElement( Element jdomElement )
+    {
+        this.jdomElement = jdomElement;
+    }
+
+    /** Returns the JDOM namespace object of this namespace node; the JDOM
+     *  namespace object contains the prefix and URI of the namespace.
+     */
+    public Namespace getJDOMNamespace()
+    {
+        return jdomNamespace;
+    }
+
+    public String toString()
+    {
+        return ( "[xmlns:" + jdomNamespace.getPrefix() + "=\"" +
+                 jdomNamespace.getURI() + "\", element=" +
+                 jdomElement.getName() + "]" );
+    }
+} 
diff --git a/libjaxen-java/src/java/main/org/jaxen/jdom/package.html b/libjaxen-java/src/java/main/org/jaxen/jdom/package.html
new file mode 100644
index 0000000..bb8aed6
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/jdom/package.html
@@ -0,0 +1,13 @@
+<html>
+	<head>
+		<title>
+			org.jaxen.jdom.*
+		</title>
+	</head>
+
+	<body>
+		<p>
+			Navigation for <a href="http://jdom.org">JDOM</a> trees.
+		</p>
+	</body>
+</html>
diff --git a/libjaxen-java/src/java/main/org/jaxen/overview.html b/libjaxen-java/src/java/main/org/jaxen/overview.html
new file mode 100644
index 0000000..b18f3eb
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/overview.html
@@ -0,0 +1,74 @@
+
+<html>
+	<head>
+		<title>
+			Jaxen: Java XPath Engine
+		</title>
+	</head>
+
+	<body bgcolor="white">
+
+		<p>Jaxen is a fast Java engine for <a href="http://www.w3.org/TR/xpath">XPath 1.0</a>
+                  that works on all XML object models.
+                </p>
+
+		<p>
+		Jaxen currently works with the following XML models: 
+			<a href="http://dom4j.org/">dom4j</a>,
+			<a href="http://jdom.org/">JDOM</a>,
+			<a href="http://www.w3.org/">W3C DOM</a>
+				and
+			<a href="http://www.xom.nu/">XOM</a>.
+	
+		</p>
+	
+		<p>
+		An <code>XPath</code> implementation is typically all that's required
+		to get started with Jaxen.
+		</p>
+
+		<table>
+			<tr>
+				<td>
+					<b>Object Model</b>
+				</td>
+				<td>
+					<b>Class</b>
+				</td>
+			</tr>
+			<tr>
+				<td>
+					dom4j
+				</td>
+				<td>
+					{@link org.jaxen.dom4j.Dom4jXPath org.jaxen.dom4j.Dom4jXPath}
+				</td>
+			</tr>
+			<tr>
+				<td>
+					JDOM
+				</td>
+				<td>
+					{@link org.jaxen.jdom.JDOMXPath org.jaxen.jdom.JDOMXPath}
+				</td>
+			</tr>
+			<tr>
+				<td>
+					W3C DOM
+				</td>
+				<td>
+					{@link org.jaxen.dom.DOMXPath org.jaxen.dom.DOMXPath}
+				</td>
+			</tr>
+			<tr>
+				<td>
+					XOM
+				</td>
+				<td>
+					{@link org.jaxen.xom.XOMXPath org.jaxen.xom.XOMXPath}
+				</td>
+			</tr>
+		</table>
+	</body>
+</html>
+
diff --git a/libjaxen-java/src/java/main/org/jaxen/package.html b/libjaxen-java/src/java/main/org/jaxen/package.html
new file mode 100644
index 0000000..4c00b3b
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/package.html
@@ -0,0 +1,14 @@
+<html>
+	<head>
+		<title>
+			org.jaxen.*
+		</title>
+	</head>
+
+	<body>
+		<p>
+			This package defines the core Jaxen API to the XPath engine.
+                        Using this API you can work with XPath on any object model.
+		</p>
+	</body>
+</html>
diff --git a/libjaxen-java/src/java/main/org/jaxen/pantry/Test.java b/libjaxen-java/src/java/main/org/jaxen/pantry/Test.java
new file mode 100644
index 0000000..9bcd4c8
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/pantry/Test.java
@@ -0,0 +1,48 @@
+package org.jaxen.pantry;
+
+import java.io.StringReader;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.jaxen.Context;
+import org.jaxen.ContextSupport;
+import org.jaxen.dom.DocumentNavigator;
+import org.jaxen.pattern.Pattern;
+import org.jaxen.pattern.PatternParser;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.xml.sax.InputSource;
+
+public class Test {
+
+static Node elem;
+static Context context;
+static {
+try {
+InputSource is = new InputSource( new StringReader( "<root> <a/><!-- --><b/><?pi ip?><b foo='bar'/></root>" ) );
+Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse( is );
+elem = doc.getDocumentElement().getLastChild();
+System.out.println( "Current node is the last <"+ elem.getNodeName() +">" );
+context = new Context( new ContextSupport( null, null, null, new DocumentNavigator() ) );
+} catch (Exception e) { System.out.println("boo boo");}
+}
+
+    public static void main( String[] args ) throws Exception {
+    
+        // the troubles come here
+        test("/root/b[1]");
+        test("/root/b[2]");
+        test("/root/*[1]");
+        test("/root/*[2]");
+        test("/root/*[3]");
+        test("/root/node()[1]");
+        test("/root/node()[5]");
+        test("/root/node()[6]");
+    }
+    
+    private static void test( String pattern ) throws Exception {
+        Pattern p = PatternParser.parse( pattern );
+        boolean b = p.matches( elem, context );
+        System.out.println( b + " " + pattern );
+    }
+
+}
\ No newline at end of file
diff --git a/libjaxen-java/src/java/main/org/jaxen/pattern/AnyChildNodeTest.java b/libjaxen-java/src/java/main/org/jaxen/pattern/AnyChildNodeTest.java
new file mode 100644
index 0000000..a6e2121
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/pattern/AnyChildNodeTest.java
@@ -0,0 +1,94 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/pattern/AnyChildNodeTest.java,v 1.6 2006/02/05 21:47:42 elharo Exp $
+ * $Revision: 1.6 $
+ * $Date: 2006/02/05 21:47:42 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: AnyChildNodeTest.java,v 1.6 2006/02/05 21:47:42 elharo Exp $
+ */
+
+package org.jaxen.pattern;
+
+import org.jaxen.Context;
+
+/** <p><code>AnyChildNodeTest</code> matches any child node.</p>
+  *
+  * @author <a href="mailto:jstrachan at apache.org">James Strachan</a>
+  * @version $Revision: 1.6 $
+  */
+public class AnyChildNodeTest extends NodeTest {
+
+    private static AnyChildNodeTest instance = new AnyChildNodeTest();
+    
+    public static AnyChildNodeTest getInstance() 
+    {
+        return instance;
+    }
+    
+    public AnyChildNodeTest() 
+    {
+    }
+    
+    /** @return true if the pattern matches the given node
+      */
+    public boolean matches( Object node, Context context ) 
+    {
+        short type = context.getNavigator().getNodeType( node );
+        return type == ELEMENT_NODE || type == TEXT_NODE
+            || type == COMMENT_NODE || type == PROCESSING_INSTRUCTION_NODE;
+    }
+    
+    public double getPriority() 
+    {
+        return -0.5;
+    }
+
+    public short getMatchType() 
+    {
+        return ANY_NODE;
+    }
+    
+    public String getText() 
+    {
+        return "*";
+    }
+    
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/pattern/AnyNodeTest.java b/libjaxen-java/src/java/main/org/jaxen/pattern/AnyNodeTest.java
new file mode 100644
index 0000000..a8a35f0
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/pattern/AnyNodeTest.java
@@ -0,0 +1,89 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/pattern/AnyNodeTest.java,v 1.8 2006/02/05 21:47:42 elharo Exp $
+ * $Revision: 1.8 $
+ * $Date: 2006/02/05 21:47:42 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: AnyNodeTest.java,v 1.8 2006/02/05 21:47:42 elharo Exp $
+ */
+
+package org.jaxen.pattern;
+
+import org.jaxen.Context;
+
+/** <p><code>AnyNodeTest</code> matches any node.</p>
+  *
+  * @author <a href="mailto:jstrachan at apache.org">James Strachan</a>
+  * @version $Revision: 1.8 $
+  */
+public class AnyNodeTest extends NodeTest {
+
+    private static AnyNodeTest instance = new AnyNodeTest();
+    
+    public static AnyNodeTest getInstance() 
+    {
+        return instance;
+    }
+    
+    private AnyNodeTest() {}
+    
+    /** @return true if the pattern matches the given node
+      */
+    public boolean matches( Object node, Context context ) 
+    {
+        return true;
+    }
+    
+    public double getPriority() 
+    {
+        return -0.5;
+    }
+
+    public short getMatchType() 
+    {
+        return ANY_NODE;
+    }
+    
+    public String getText() 
+    {
+        return "*";
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/pattern/LocationPathPattern.java b/libjaxen-java/src/java/main/org/jaxen/pattern/LocationPathPattern.java
new file mode 100644
index 0000000..aa401e3
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/pattern/LocationPathPattern.java
@@ -0,0 +1,319 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/pattern/LocationPathPattern.java,v 1.15 2006/02/05 21:47:42 elharo Exp $
+ * $Revision: 1.15 $
+ * $Date: 2006/02/05 21:47:42 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: LocationPathPattern.java,v 1.15 2006/02/05 21:47:42 elharo Exp $
+ */
+
+package org.jaxen.pattern;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.jaxen.Context;
+import org.jaxen.JaxenException;
+import org.jaxen.Navigator;
+import org.jaxen.expr.FilterExpr;
+import org.jaxen.util.SingletonList;
+
+/** <p><code>LocationPathPattern</code> matches any node using a
+  * location path such as A/B/C.
+  * The parentPattern and ancestorPattern properties are used to
+  * chain location path patterns together</p>
+  *
+  * @author <a href="mailto:jstrachan at apache.org">James Strachan</a>
+  * @version $Revision: 1.15 $
+  */
+public class LocationPathPattern extends Pattern {
+
+    /** The node test to perform on this step of the path */
+    private NodeTest nodeTest = AnyNodeTest.getInstance();
+    
+    /** Patterns matching my parent node */
+    private Pattern parentPattern;
+    
+    /** Patterns matching one of my ancestors */
+    private Pattern ancestorPattern;
+        
+    /** The filters to match against */
+    private List filters;
+
+    /** Whether this lcoation path is absolute or not */
+    private boolean absolute;
+    
+    
+    public LocationPathPattern()   
+    {
+    }
+
+    public LocationPathPattern(NodeTest nodeTest)   
+    {
+        this.nodeTest = nodeTest;
+    }
+
+    public Pattern simplify()
+    {
+        if ( parentPattern != null )
+        {
+            parentPattern = parentPattern.simplify();
+        }
+        if ( ancestorPattern != null )
+        {
+            ancestorPattern = ancestorPattern.simplify();
+        }
+        if ( filters == null )
+        {
+            if ( parentPattern == null && ancestorPattern == null )
+            {
+                return nodeTest;
+            }
+            if ( parentPattern != null && ancestorPattern == null )
+            {
+                if ( nodeTest instanceof AnyNodeTest )
+                {
+                    return parentPattern;
+                }
+            }
+        }
+        return this;
+    }
+    
+    /** Adds a filter to this pattern
+     */
+    public void addFilter(FilterExpr filter) 
+    {
+        if ( filters == null )
+        {
+            filters = new ArrayList();
+        }
+        filters.add( filter );
+    }
+    
+    /** Adds a pattern for the parent of the current
+     * context node used in this pattern.
+     */
+    public void setParentPattern(Pattern parentPattern) 
+    {
+        this.parentPattern = parentPattern;
+    }
+    
+    /** Adds a pattern for an ancestor of the current
+     * context node used in this pattern.
+     */
+    public void setAncestorPattern(Pattern ancestorPattern) 
+    {
+        this.ancestorPattern = ancestorPattern;
+    }
+    
+    /** Allows the NodeTest to be set
+     */
+    public void setNodeTest(NodeTest nodeTest) throws JaxenException
+    {
+        if ( this.nodeTest instanceof AnyNodeTest )
+        {
+            this.nodeTest = nodeTest;
+        }   
+        else 
+        {
+            throw new JaxenException( "Attempt to overwrite nodeTest: " + this.nodeTest + " with: " + nodeTest );
+        }
+    }
+    
+    /** @return true if the pattern matches the given node
+      */
+    public boolean matches( Object node, Context context ) throws JaxenException
+    {
+        Navigator navigator = context.getNavigator();
+
+/*        
+        if ( isAbsolute() )
+        {
+            node = navigator.getDocumentNode( node );
+        }
+*/
+        if (! nodeTest.matches(node, context) )
+        {
+            return false;
+        }
+        
+        if (parentPattern != null) 
+        {
+            Object parent = navigator.getParentNode( node );
+            if ( parent == null ) 
+            {
+                return false;
+            }
+            if ( ! parentPattern.matches( parent, context ) ) 
+            {
+                return false;
+            }
+        }
+
+        if (ancestorPattern != null) {
+            Object ancestor = navigator.getParentNode( node );
+            while (true)
+            {
+                if ( ancestorPattern.matches( ancestor, context ) )
+                {
+                    break;
+                }
+                if ( ancestor == null )
+                {
+                    return false;
+                }
+                if ( navigator.isDocument( ancestor ) )
+                {
+                    return false;
+                }
+                ancestor = navigator.getParentNode( ancestor );
+            }
+        }
+        
+        if (filters != null) 
+        {
+            List list = new SingletonList(node);
+
+            context.setNodeSet( list );
+            
+            // XXXX: filters aren't positional, so should we clone context?
+
+            boolean answer = true;
+
+            for (Iterator iter = filters.iterator(); iter.hasNext(); ) 
+            {
+                FilterExpr filter = (FilterExpr) iter.next();
+
+                if ( ! filter.asBoolean( context ) )
+                {
+                    answer = false;
+                    break;
+                }
+            }
+            // restore context
+
+            context.setNodeSet( list );
+
+            return answer;
+        }
+        return true;
+    }
+    
+    public double getPriority() 
+    {
+        if ( filters != null ) 
+        {
+            return 0.5;
+        }
+        return nodeTest.getPriority();
+    }
+
+
+    public short getMatchType() 
+    {
+        return nodeTest.getMatchType();
+    }
+    
+    public String getText() 
+    {
+        StringBuffer buffer = new StringBuffer();
+        if ( absolute )
+        {
+            buffer.append( "/" );
+        }
+        if (ancestorPattern != null) 
+        {
+            String text = ancestorPattern.getText();
+            if ( text.length() > 0 )
+            {
+                buffer.append( text );
+                buffer.append( "//" );
+            }
+        }
+        if (parentPattern != null) 
+        {
+            String text = parentPattern.getText();
+            if ( text.length() > 0 )
+            {
+                buffer.append( text );
+                buffer.append( "/" );
+            }
+        }
+        buffer.append( nodeTest.getText() );
+        
+        if ( filters != null ) 
+        {
+            buffer.append( "[" );
+            for (Iterator iter = filters.iterator(); iter.hasNext(); ) 
+            {
+                FilterExpr filter = (FilterExpr) iter.next();
+                buffer.append( filter.getText() );
+            }
+            buffer.append( "]" );
+        }        
+        return buffer.toString();
+    }
+    
+    public String toString()
+    {
+        return super.toString() + "[ absolute: " + absolute + " parent: " + parentPattern + " ancestor: " 
+            + ancestorPattern + " filters: " + filters + " nodeTest: " 
+            + nodeTest + " ]";
+    }
+    
+    public boolean isAbsolute()
+    {
+        return absolute;
+    }
+    
+    public void setAbsolute(boolean absolute)
+    {
+        this.absolute = absolute;
+    }
+    
+    public boolean hasAnyNodeTest()
+    {
+        return nodeTest instanceof AnyNodeTest;
+    }
+        
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/pattern/NameTest.java b/libjaxen-java/src/java/main/org/jaxen/pattern/NameTest.java
new file mode 100644
index 0000000..b8a4ce3
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/pattern/NameTest.java
@@ -0,0 +1,129 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/pattern/NameTest.java,v 1.7 2006/02/05 21:47:42 elharo Exp $
+ * $Revision: 1.7 $
+ * $Date: 2006/02/05 21:47:42 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: NameTest.java,v 1.7 2006/02/05 21:47:42 elharo Exp $
+ */
+
+package org.jaxen.pattern;
+
+import org.jaxen.Context;
+import org.jaxen.Navigator;
+
+/** <p><code>NameTest</code> tests for a node name.</p>
+  *
+  * @author <a href="mailto:jstrachan at apache.org">James Strachan</a>
+  * @version $Revision: 1.7 $
+  */
+public class NameTest extends NodeTest {
+    
+    /** The name to match against */
+    private String name;
+    
+    /** The type of node to match - either attribute or element */
+    private short nodeType;
+    
+    public NameTest(String name, short nodeType)   
+    {
+        this.name = name;
+        this.nodeType = nodeType;
+    }
+        
+    /** @return true if the pattern matches the given node
+      */
+    public boolean matches( Object node, Context context ) 
+    {
+        Navigator navigator = context.getNavigator();
+        if ( nodeType == Pattern.ELEMENT_NODE ) 
+        {
+            return navigator.isElement( node ) 
+                && name.equals( navigator.getElementName( node ) );
+        }
+        else if ( nodeType == Pattern.ATTRIBUTE_NODE ) 
+        {
+            return navigator.isAttribute( node )
+                && name.equals( navigator.getAttributeName( node ) );
+        }
+        else
+        {
+            if ( navigator.isElement( node ) )
+            {
+                return name.equals( navigator.getElementName( node ) );
+            }
+            else
+            if ( navigator.isAttribute( node ) )
+            {
+                return name.equals( navigator.getAttributeName( node ) );
+            }
+        }
+        return false;
+    }
+    
+    public double getPriority() 
+    {
+        return 0.0;
+    }
+
+
+    public short getMatchType() 
+    {
+        return nodeType;
+    }
+    
+    public String getText() 
+    {
+        if ( nodeType == Pattern.ATTRIBUTE_NODE ) 
+        {
+            return "@" + name;
+        }
+        else 
+        {
+            return name;
+        }
+    }
+    
+    public String toString()
+    {
+        return super.toString() + "[ name: " + name + " type: " + nodeType + " ]";
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/pattern/NamespaceTest.java b/libjaxen-java/src/java/main/org/jaxen/pattern/NamespaceTest.java
new file mode 100644
index 0000000..9c84d1e
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/pattern/NamespaceTest.java
@@ -0,0 +1,132 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/pattern/NamespaceTest.java,v 1.6 2006/02/05 21:47:42 elharo Exp $
+ * $Revision: 1.6 $
+ * $Date: 2006/02/05 21:47:42 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: NamespaceTest.java,v 1.6 2006/02/05 21:47:42 elharo Exp $
+ */
+
+package org.jaxen.pattern;
+
+import org.jaxen.Context;
+import org.jaxen.Navigator;
+
+/** <p><code>NamespaceTest</code> tests for a given namespace URI.</p>
+  *
+  * @author <a href="mailto:jstrachan at apache.org">James Strachan</a>
+  * @version $Revision: 1.6 $
+  */
+public class NamespaceTest extends NodeTest {
+    
+    /** The prefix to match against */
+    private String prefix;
+    
+    /** The type of node to match - either attribute or element */
+    private short nodeType;
+    
+    public NamespaceTest(String prefix, short nodeType)   
+    {
+        if ( prefix == null ) 
+        {
+            prefix = "";
+        }
+        this.prefix = prefix;
+        this.nodeType = nodeType;
+    }
+        
+    /** @return true if the pattern matches the given node
+      */
+    public boolean matches( Object node, Context context ) 
+    {
+        Navigator navigator = context.getNavigator();
+        String uri = getURI( node, context );
+        
+        if ( nodeType == Pattern.ELEMENT_NODE ) 
+        {
+            return navigator.isElement( node ) 
+                && uri.equals( navigator.getElementNamespaceUri( node ) );
+        }
+        else if ( nodeType == Pattern.ATTRIBUTE_NODE ) 
+        {
+            return navigator.isAttribute( node )
+                && uri.equals( navigator.getAttributeNamespaceUri( node ) );
+        }
+        return false;
+    }
+    
+    public double getPriority() 
+    {
+        return -0.25;
+    }
+
+
+    public short getMatchType() 
+    {
+        return nodeType;
+    }
+    
+    public String getText() 
+    {
+        return prefix + ":";
+    }
+    
+    public String toString()
+    {
+        return super.toString() + "[ prefix: " + prefix + " type: " + nodeType + " ]";
+    }
+    
+    /** Returns the URI of the current prefix or "" if no URI can be found
+     */
+    protected String getURI(Object node, Context context)
+    {
+        String uri = context.getNavigator().translateNamespacePrefixToUri( prefix, node );
+        if ( uri == null )
+        {
+            uri = context.getContextSupport().translateNamespacePrefixToUri( prefix );
+        }
+        if ( uri == null ) 
+        {
+            uri = "";
+        }
+        return uri;
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/pattern/NoNodeTest.java b/libjaxen-java/src/java/main/org/jaxen/pattern/NoNodeTest.java
new file mode 100644
index 0000000..94dad69
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/pattern/NoNodeTest.java
@@ -0,0 +1,91 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/pattern/NoNodeTest.java,v 1.7 2006/02/05 21:47:42 elharo Exp $
+ * $Revision: 1.7 $
+ * $Date: 2006/02/05 21:47:42 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: NoNodeTest.java,v 1.7 2006/02/05 21:47:42 elharo Exp $
+ */
+
+package org.jaxen.pattern;
+
+import org.jaxen.Context;
+
+/** <p><code>NoNodeTest</code> matches no nodes.</p>
+  *
+  * @author <a href="mailto:jstrachan at apache.org">James Strachan</a>
+  * @version $Revision: 1.7 $
+  */
+public class NoNodeTest extends NodeTest {
+    
+    private static NoNodeTest instance = new NoNodeTest();
+    
+    public static NoNodeTest getInstance() 
+    {
+        return instance;
+    }
+    
+    public NoNodeTest() 
+    {
+    }
+        
+    /** @return true if the pattern matches the given node
+      */
+    public boolean matches( Object node, Context context ) 
+    {
+        return false;
+    }
+    
+    public double getPriority() 
+    {
+        return -0.5;
+    }
+
+    public short getMatchType() 
+    {
+        return NO_NODE;
+    }
+
+    public String getText() 
+    {
+        return "";
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/pattern/NodeTest.java b/libjaxen-java/src/java/main/org/jaxen/pattern/NodeTest.java
new file mode 100644
index 0000000..4210bad
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/pattern/NodeTest.java
@@ -0,0 +1,59 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/pattern/NodeTest.java,v 1.6 2006/02/05 21:47:42 elharo Exp $
+ * $Revision: 1.6 $
+ * $Date: 2006/02/05 21:47:42 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: NodeTest.java,v 1.6 2006/02/05 21:47:42 elharo Exp $
+ */
+
+package org.jaxen.pattern;
+
+
+
+/** <p><code>NodeTest</code> is a simple test on a node.</p>
+  *
+  * @author <a href="mailto:jstrachan at apache.org">James Strachan</a>
+  * @version $Revision: 1.6 $
+  */
+public abstract class NodeTest extends Pattern {
+
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/pattern/NodeTypeTest.java b/libjaxen-java/src/java/main/org/jaxen/pattern/NodeTypeTest.java
new file mode 100644
index 0000000..9d74b91
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/pattern/NodeTypeTest.java
@@ -0,0 +1,133 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/pattern/NodeTypeTest.java,v 1.8 2006/02/05 21:47:42 elharo Exp $
+ * $Revision: 1.8 $
+ * $Date: 2006/02/05 21:47:42 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: NodeTypeTest.java,v 1.8 2006/02/05 21:47:42 elharo Exp $
+ */
+
+package org.jaxen.pattern;
+
+import org.jaxen.Context;
+
+/** <p><code>NodeTypeTest</code> matches if the node is of a certain type 
+  * such as element, attribute, comment, text, processing instruction and so forth.</p>
+  *
+  * @author <a href="mailto:jstrachan at apache.org">James Strachan</a>
+  * @version $Revision: 1.8 $
+  */
+public class NodeTypeTest extends NodeTest {
+    
+    public static final NodeTypeTest DOCUMENT_TEST 
+        = new NodeTypeTest( DOCUMENT_NODE );
+    
+    public static final NodeTypeTest ELEMENT_TEST 
+        = new NodeTypeTest( ELEMENT_NODE );
+    
+    public static final NodeTypeTest ATTRIBUTE_TEST 
+        = new NodeTypeTest( ATTRIBUTE_NODE );
+    
+    public static final NodeTypeTest COMMENT_TEST 
+        = new NodeTypeTest( COMMENT_NODE );
+    
+    public static final NodeTypeTest TEXT_TEST 
+        = new NodeTypeTest( TEXT_NODE );
+    
+    public static final NodeTypeTest PROCESSING_INSTRUCTION_TEST 
+        = new NodeTypeTest( PROCESSING_INSTRUCTION_NODE );
+    
+    public static final NodeTypeTest NAMESPACE_TEST 
+        = new NodeTypeTest( NAMESPACE_NODE );
+    
+    
+    private short nodeType;
+    
+    public NodeTypeTest(short nodeType)   
+    {
+        this.nodeType = nodeType;
+    }
+        
+    /** @return true if the pattern matches the given node
+      */
+    public boolean matches( Object node, Context context ) 
+    {
+        return nodeType == context.getNavigator().getNodeType( node );
+    }
+    
+    public double getPriority() 
+    {
+        return -0.5;
+    }
+
+
+    public short getMatchType() 
+    {
+        return nodeType;
+    }
+    
+    public String getText() 
+    {
+        switch (nodeType) 
+        {
+            case ELEMENT_NODE:
+                return "child()";
+            case ATTRIBUTE_NODE:
+                return "@*";
+            case NAMESPACE_NODE:
+                return "namespace()";
+            case DOCUMENT_NODE:
+                return "/";
+            case COMMENT_NODE:
+                return "comment()";
+            case TEXT_NODE:
+                return "text()";
+            case PROCESSING_INSTRUCTION_NODE:
+                return "processing-instruction()";
+        }
+        return "";
+    }
+    
+    public String toString()
+    {
+        return super.toString() + "[ type: " + nodeType + " ]";
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/pattern/Pattern.java b/libjaxen-java/src/java/main/org/jaxen/pattern/Pattern.java
new file mode 100644
index 0000000..c315754
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/pattern/Pattern.java
@@ -0,0 +1,176 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/pattern/Pattern.java,v 1.13 2006/04/07 17:11:52 elharo Exp $
+ * $Revision: 1.13 $
+ * $Date: 2006/04/07 17:11:52 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: Pattern.java,v 1.13 2006/04/07 17:11:52 elharo Exp $
+ */
+
+package org.jaxen.pattern;
+
+import org.jaxen.Context;
+import org.jaxen.JaxenException;
+
+/** <p><code>Pattern</code> defines the behaviour for pattern in
+  * the XSLT processing model.</p>
+  *
+  * @author <a href="mailto:jstrachan at apache.org">James Strachan</a>
+  * @version $Revision: 1.13 $
+  */
+public abstract class Pattern {
+
+    // These node numbers are compatible with both DOM and dom4j's node types
+    /** Matches Element nodes */
+    public static final short ELEMENT_NODE = 1;
+    /** Matches attribute nodes */
+    public static final short ATTRIBUTE_NODE = 2;
+    /** Matches text nodes */
+    public static final short TEXT_NODE = 3;
+    /** Matches CDATA section nodes */
+    public static final short CDATA_SECTION_NODE = 4;
+    /** Matches entity reference nodes */
+    public static final short ENTITY_REFERENCE_NODE = 5;
+    /** Matches entity nodes */
+    //public static final short ENTITY_NODE = 6;
+    /** Matches ProcessingInstruction */
+    public static final short PROCESSING_INSTRUCTION_NODE = 7;
+    /** Matches comment nodes */
+    public static final short COMMENT_NODE = 8;
+    /** Matches document nodes */
+    public static final short DOCUMENT_NODE = 9;
+    /** Matches DocumentType nodes */
+    public static final short DOCUMENT_TYPE_NODE = 10;
+    //public static final short DOCUMENT_FRAGMENT_NODE = 11;
+    //public static final short NOTATION_NODE = 12;
+    
+    /** Matches a Namespace Node */
+    // This has the same value as the DOM Level 3 XPathNamespace type
+    public static final short NAMESPACE_NODE = 13;
+    
+    /** Does not match any valid node */
+    public static final short UNKNOWN_NODE = 14;
+    
+    /** The maximum number of node types for sizing purposes */
+    public static final short MAX_NODE_TYPE = 14;
+
+    /** Matches any node */
+    public static final short ANY_NODE = 0;
+    
+    /** Matches no nodes */
+    public static final short NO_NODE = 14;
+    
+    
+    /** 
+     * 
+     * @param node ????
+     * @param context ????
+     * @return true if the pattern matches the given node
+     * @throws JaxenException  if ????
+      */
+    public abstract boolean matches( Object node, Context context ) throws JaxenException;
+    
+    /** Returns the default resolution policy of the pattern according to the
+      * <a href="http://www.w3.org/TR/xslt#conflict">
+      * XSLT conflict resolution rules</a>.
+      *  
+     * @return 0.5; the default priority defined in XSLT
+     * 
+     * @see <a href="http://www.w3.org/TR/xslt#conflict" target="_top">Section 5.5 of the XSLT specification</a>
+      * 
+      */
+    public double getPriority() 
+    {
+        return 0.5;
+    }
+    
+    /** If this pattern is a union pattern then this
+      * method should return an array of patterns which
+      * describe the union pattern, which should contain more than one pattern.
+      * Otherwise this method should return null.
+      *
+      * @return an array of the patterns which make up this union pattern
+      * or null if this pattern is not a union pattern
+      */
+    public Pattern[] getUnionPatterns() 
+    {
+        return null;
+    }
+
+    
+    /** 
+     * Returns the type of node the pattern matches.
+     * 
+     * @return <code>ANY_NODE</code> unless overridden
+      */
+    public short getMatchType() 
+    {
+        return ANY_NODE;
+    }
+
+
+    /** For patterns which only match an ATTRIBUTE_NODE or an 
+      * ELEMENT_NODE then this pattern may return the name of the
+      * element or attribute it matches. This allows a more efficient
+      * rule matching algorithm to be performed, rather than a brute 
+      * force approach of evaluating every pattern for a given Node.
+      *
+      * @return the name of the element or attribute this pattern matches
+      * or null if this pattern matches any or more than one name
+      */
+    public String getMatchesNodeName() 
+    {
+        return null;
+    }
+    
+    
+    public Pattern simplify() 
+    {
+        return this;
+    }
+    
+    /** Returns a textual representation of this pattern
+     * 
+     * @return the usual string form of this XSLT pattern
+     */
+    public abstract String getText();
+
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/pattern/PatternHandler.java b/libjaxen-java/src/java/main/org/jaxen/pattern/PatternHandler.java
new file mode 100644
index 0000000..f2a3ab5
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/pattern/PatternHandler.java
@@ -0,0 +1,351 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/pattern/PatternHandler.java,v 1.8 2006/02/05 21:47:42 elharo Exp $
+ * $Revision: 1.8 $
+ * $Date: 2006/02/05 21:47:42 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: PatternHandler.java,v 1.8 2006/02/05 21:47:42 elharo Exp $
+ */
+
+
+package org.jaxen.pattern;
+
+import java.util.LinkedList;
+
+import org.jaxen.JaxenException;
+import org.jaxen.JaxenHandler;
+import org.jaxen.expr.Expr;
+import org.jaxen.expr.FilterExpr;
+import org.jaxen.saxpath.Axis;
+
+/** SAXPath <code>XPathHandler</code> implementation capable
+ *  of building Jaxen expression trees which can walk various
+ *  different object models.
+ *
+ *  @author bob mcwhirter (bob at werken.com)
+ */
+public class PatternHandler extends JaxenHandler
+{
+    private Pattern pattern;
+    
+    public PatternHandler()
+    {
+    }
+    
+    /** Retrieve the simplified Jaxen Pattern expression tree.
+     *
+     *  <p>
+     *  This method is only valid once <code>XPathReader.parse(...)</code>
+     *  successfully returned.
+     *  </p>
+     *
+     *  @return The Pattern expression tree.
+     */
+    public Pattern getPattern()
+    {
+        return getPattern( true );
+    }
+
+    /** Retrieve the Jaxen Pattern expression tree, optionally
+     *  simplified.
+     *
+     *  <p>
+     *  This method is only valid once <code>XPathReader.parse(...)</code>
+     *  successfully returned.
+     *  </p>
+     *  
+     *  @param shouldSimplify ????
+     *
+     *  @return The Pattern expression tree.
+     */
+    public Pattern getPattern(boolean shouldSimplify)
+    {
+        if ( shouldSimplify && ! this.simplified )
+        {
+            //System.err.println("simplifying....");
+            this.pattern.simplify();
+            this.simplified = true;
+        }
+
+        return this.pattern;
+    }
+
+    
+    
+    
+    public void endXPath()
+    {
+        this.pattern = (Pattern) pop();
+
+        System.out.println( "stack is: " + stack );
+        
+        popFrame();
+    }
+
+    public void endPathExpr()
+    {
+        //System.err.println("endPathExpr()");
+
+        // PathExpr ::=   LocationPath
+        //              | FilterExpr
+        //              | FilterExpr / RelativeLocationPath
+        //              | FilterExpr // RelativeLocationPath
+        //
+        // If the current stack-frame has two items, it's a
+        // FilterExpr and a LocationPath (of some flavor).
+        //
+        // If the current stack-frame has one item, it's simply
+        // a FilterExpr, and more than like boils down to a
+        // primary expr of some flavor.  But that's for another
+        // method...
+
+        LinkedList frame = popFrame();
+        
+        System.out.println( "endPathExpr(): " + frame );
+            
+        push( frame.removeFirst() );
+/*        
+        LocationPathPattern locationPath = new LocationPathPattern();
+        push( locationPath );
+        while (! frame.isEmpty() )
+        {
+            Object filter = frame.removeLast();
+            if ( filter instanceof NodeTest ) 
+            {
+                locationPath.setNodeTest( (NodeTest) filter );
+            }
+            else if ( filter instanceof FilterExpr )
+            {
+                locationPath.addFilter( (FilterExpr) filter );
+            }
+            else if ( filter instanceof LocationPathPattern ) 
+            {
+                LocationPathPattern parent = (LocationPathPattern) filter;
+                locationPath.setParentPattern( parent );
+                locationPath = parent;
+            }
+            else if ( filter != null ) 
+            {
+                throw new JaxenException( "Unknown filter: " + filter );
+            }
+        }
+*/
+    }
+
+    public void startAbsoluteLocationPath()
+    {
+        //System.err.println("startAbsoluteLocationPath()");
+        pushFrame();
+
+        push( createAbsoluteLocationPath() );
+    }
+    
+    public void endAbsoluteLocationPath() throws JaxenException
+    {
+        //System.err.println("endAbsoluteLocationPath()");
+        endLocationPath();
+    }
+
+    public void startRelativeLocationPath()
+    {
+        //System.err.println("startRelativeLocationPath()");
+        pushFrame();
+
+        push( createRelativeLocationPath() );
+    }
+
+    public void endRelativeLocationPath() throws JaxenException
+    {
+        //System.err.println("endRelativeLocationPath()");
+        endLocationPath();
+    }
+
+    protected void endLocationPath() throws JaxenException
+    {
+        // start at the back, its the main pattern then add everything else as 
+        LinkedList list = popFrame();
+        
+        System.out.println( "endLocationPath: " + list );
+
+        LocationPathPattern locationPath = (LocationPathPattern) list.removeFirst();
+        push( locationPath );
+        boolean doneNodeTest = false;
+        while ( ! list.isEmpty() )
+        {
+            Object filter = list.removeFirst();
+            if ( filter instanceof NodeTest ) 
+            {
+                if ( doneNodeTest ) 
+                {
+                    LocationPathPattern parent = new LocationPathPattern( (NodeTest) filter );
+                    locationPath.setParentPattern( parent );
+                    locationPath = parent;
+                    doneNodeTest = false;
+                }   
+                else
+                {
+                    locationPath.setNodeTest( (NodeTest) filter );
+                }
+            }
+            else if ( filter instanceof FilterExpr )
+            {
+                locationPath.addFilter( (FilterExpr) filter );
+            }
+            else if ( filter instanceof LocationPathPattern ) 
+            {
+                LocationPathPattern parent = (LocationPathPattern) filter;
+                locationPath.setParentPattern( parent );
+                locationPath = parent;
+                doneNodeTest = false;
+            }
+        }
+    }
+
+    
+    public void startNameStep(int axis,
+                              String prefix,
+                              String localName)
+    {
+        //System.err.println("startNameStep(" + axis + ", " + prefix + ", " + localName + ")");
+        pushFrame();
+
+        short nodeType = Pattern.ELEMENT_NODE;            
+        switch ( axis ) 
+        {
+            case Axis.ATTRIBUTE:
+                nodeType = Pattern.ATTRIBUTE_NODE;
+                break;
+            case Axis.NAMESPACE:
+                nodeType = Pattern.NAMESPACE_NODE;
+                break;
+        }
+        
+        if ( prefix != null && prefix.length() > 0 && ! prefix.equals( "*" ) ) 
+        {                    
+            push( new NamespaceTest( prefix, nodeType ) );
+        }
+        if ( localName != null && localName.length() > 0 && ! localName.equals( "*" ) ) 
+        {
+            push( new NameTest( localName, nodeType ) );
+        }
+    }
+
+    public void startTextNodeStep(int axis)
+    {
+        //System.err.println("startTextNodeStep()");
+        pushFrame();
+        
+        push( new NodeTypeTest( Pattern.TEXT_NODE ) );
+    }
+    
+    public void startCommentNodeStep(int axis)
+    {
+        //System.err.println("startCommentNodeStep()");
+        pushFrame();
+
+        push( new NodeTypeTest( Pattern.COMMENT_NODE ) );
+    }
+
+    public void startAllNodeStep(int axis)
+    {
+        //System.err.println("startAllNodeStep()");
+        pushFrame();
+
+        push( AnyNodeTest.getInstance() );
+    }
+
+    public void startProcessingInstructionNodeStep(int axis,
+                                                   String name)
+    {
+        //System.err.println("startProcessingInstructionStep()");
+        pushFrame();
+
+        // XXXX: should we throw an exception if name is present?            
+        push( new NodeTypeTest( Pattern.PROCESSING_INSTRUCTION_NODE ) );
+    }
+    
+    protected void endStep()
+    {
+        LinkedList list = popFrame();
+        if ( ! list.isEmpty() ) 
+        {
+            push( list.removeFirst() );
+            
+            if ( ! list.isEmpty() )
+            {
+                System.out.println( "List should now be empty!" + list );
+            }
+        }
+    }
+    
+
+    public void startUnionExpr()
+    {
+        //System.err.println("startUnionExpr()");
+    }
+
+    public void endUnionExpr(boolean create) throws JaxenException
+    {
+        //System.err.println("endUnionExpr()");
+
+        if ( create )
+        {
+            //System.err.println("makeUnionExpr");
+
+            Expr rhs = (Expr) pop();
+            Expr lhs = (Expr) pop();
+
+            push( getXPathFactory().createUnionExpr( lhs,
+                                                    rhs ) );
+        }
+    }
+
+    protected Pattern createAbsoluteLocationPath() 
+    {
+        return new LocationPathPattern( NodeTypeTest.DOCUMENT_TEST );
+    }
+
+    protected Pattern createRelativeLocationPath() 
+    {
+        return new LocationPathPattern();
+    }
+
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/pattern/PatternParser.java b/libjaxen-java/src/java/main/org/jaxen/pattern/PatternParser.java
new file mode 100644
index 0000000..14d5493
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/pattern/PatternParser.java
@@ -0,0 +1,300 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/pattern/PatternParser.java,v 1.18 2006/02/05 21:47:42 elharo Exp $
+ * $Revision: 1.18 $
+ * $Date: 2006/02/05 21:47:42 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: PatternParser.java,v 1.18 2006/02/05 21:47:42 elharo Exp $
+ */
+
+
+package org.jaxen.pattern;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+
+import org.jaxen.JaxenException;
+import org.jaxen.JaxenHandler;
+import org.jaxen.expr.DefaultAllNodeStep;
+import org.jaxen.expr.DefaultCommentNodeStep;
+import org.jaxen.expr.DefaultFilterExpr;
+import org.jaxen.expr.DefaultNameStep;
+import org.jaxen.expr.DefaultProcessingInstructionNodeStep;
+import org.jaxen.expr.DefaultStep;
+import org.jaxen.expr.DefaultTextNodeStep;
+import org.jaxen.expr.DefaultXPathFactory;
+import org.jaxen.expr.Expr;
+import org.jaxen.expr.FilterExpr;
+import org.jaxen.expr.LocationPath;
+import org.jaxen.expr.Predicate;
+import org.jaxen.expr.PredicateSet;
+import org.jaxen.expr.Step;
+import org.jaxen.expr.UnionExpr;
+import org.jaxen.saxpath.Axis;
+import org.jaxen.saxpath.XPathReader;
+import org.jaxen.saxpath.helpers.XPathReaderFactory;
+
+
+/** <code>PatternParser</code> is a helper class for parsing
+  * XSLT patterns
+  *
+  * @author <a href="mailto:jstrachan at apache.org">James Strachan</a>
+  */
+public class PatternParser 
+{
+    private static final boolean TRACE = false;
+    private static final boolean USE_HANDLER = false;
+    public static Pattern parse(String text) throws JaxenException, org.jaxen.saxpath.SAXPathException
+    {
+        if ( USE_HANDLER )
+        {
+            XPathReader reader = XPathReaderFactory.createReader();
+            PatternHandler handler = new PatternHandler();       
+            
+            handler.setXPathFactory( new DefaultXPathFactory() );            
+            reader.setXPathHandler( handler );
+            reader.parse( text );
+            
+            return handler.getPattern();
+        }
+        else
+        {
+            XPathReader reader = XPathReaderFactory.createReader();
+            JaxenHandler handler = new JaxenHandler();
+            
+            handler.setXPathFactory( new DefaultXPathFactory() );            
+            reader.setXPathHandler( handler );
+            reader.parse( text );
+
+            Pattern pattern = convertExpr( handler.getXPathExpr().getRootExpr() );
+            return pattern.simplify();
+        }
+    }
+    
+    protected static Pattern convertExpr(Expr expr) throws JaxenException 
+    {
+        if ( TRACE )
+        {
+            System.out.println( "Converting: " + expr + " into a pattern." );
+        }
+        
+        if ( expr instanceof LocationPath )
+        {
+            return convertExpr( (LocationPath) expr );
+        }
+        else if ( expr instanceof FilterExpr )
+        {
+            LocationPathPattern answer = new LocationPathPattern();
+            answer.addFilter( (FilterExpr) expr );
+            return answer;
+        }
+        else if ( expr instanceof UnionExpr )
+        {
+            UnionExpr unionExpr = (UnionExpr) expr;
+            Pattern lhs = convertExpr( unionExpr.getLHS() );
+            Pattern rhs = convertExpr( unionExpr.getRHS() );
+            return new UnionPattern( lhs, rhs );
+        }
+        else 
+        {
+            LocationPathPattern answer = new LocationPathPattern();
+            answer.addFilter( new DefaultFilterExpr( expr,
+                                new PredicateSet()) );
+            return answer;
+        }
+    }
+    
+    protected static LocationPathPattern convertExpr(LocationPath locationPath) throws JaxenException
+    {
+        LocationPathPattern answer = new LocationPathPattern();        
+        //answer.setAbsolute( locationPath.isAbsolute() );
+        List steps = locationPath.getSteps();
+        
+        // go through steps backwards
+        LocationPathPattern path = answer;
+        boolean first = true;
+        for ( ListIterator iter = steps.listIterator( steps.size() ); iter.hasPrevious(); ) 
+        {
+            Step step = (Step) iter.previous();
+            if ( first )
+            {
+                first = false;
+                path = convertStep( path, step );
+            }
+            else
+            {
+                if ( navigationStep( step ) ) 
+                {
+                    LocationPathPattern parent = new LocationPathPattern();
+                    int axis = step.getAxis();
+                    if ( axis == Axis.DESCENDANT || axis == Axis.DESCENDANT_OR_SELF )
+                    {
+                        path.setAncestorPattern( parent );
+                    }
+                    else
+                    {
+                        path.setParentPattern( parent );
+                    }
+                    path = parent;
+                }
+                path = convertStep( path, step );
+            }
+        }
+        if ( locationPath.isAbsolute() )
+        {
+            LocationPathPattern parent = new LocationPathPattern( NodeTypeTest.DOCUMENT_TEST );
+            path.setParentPattern( parent );
+        }
+        return answer;
+    }   
+    
+    protected static LocationPathPattern convertStep(LocationPathPattern path, Step step) throws JaxenException
+    {
+        if ( step instanceof DefaultAllNodeStep )
+        {
+            int axis = step.getAxis();
+            if ( axis == Axis.ATTRIBUTE )
+            {
+                path.setNodeTest( NodeTypeTest.ATTRIBUTE_TEST );
+            }
+            else 
+            {
+                path.setNodeTest( NodeTypeTest.ELEMENT_TEST );
+            }
+        }
+        else if ( step instanceof DefaultCommentNodeStep )
+        {
+            path.setNodeTest( NodeTypeTest.COMMENT_TEST );
+        }
+        else if ( step instanceof DefaultProcessingInstructionNodeStep )
+        {
+            path.setNodeTest( NodeTypeTest.PROCESSING_INSTRUCTION_TEST );
+        }
+        else if ( step instanceof DefaultTextNodeStep )
+        {
+            path.setNodeTest( TextNodeTest.SINGLETON );
+        }
+        else if ( step instanceof DefaultCommentNodeStep )
+        {
+            path.setNodeTest( NodeTypeTest.COMMENT_TEST );
+        }
+        else if ( step instanceof DefaultNameStep )
+        {
+            DefaultNameStep nameStep = (DefaultNameStep) step;
+            String localName = nameStep.getLocalName();
+            String prefix = nameStep.getPrefix();
+            int axis = nameStep.getAxis();
+            short nodeType = Pattern.ELEMENT_NODE;
+            if ( axis == Axis.ATTRIBUTE )
+            {
+                nodeType = Pattern.ATTRIBUTE_NODE;
+            }
+            if ( nameStep.isMatchesAnyName() )
+            {
+                if ( prefix.length() == 0 || prefix.equals( "*" ) ) 
+                {
+                    if ( axis == Axis.ATTRIBUTE )
+                    {
+                        path.setNodeTest( NodeTypeTest.ATTRIBUTE_TEST );
+                    }
+                    else 
+                    {
+                        path.setNodeTest( NodeTypeTest.ELEMENT_TEST );
+                    }
+                }
+                else 
+                {
+                    path.setNodeTest( new NamespaceTest( prefix, nodeType ) );
+                }
+            }
+            else 
+            {
+                path.setNodeTest( new NameTest( localName, nodeType ) );
+                // XXXX: should support namespace in the test too
+            }
+            return convertDefaultStep(path, nameStep);
+        }
+        else if ( step instanceof DefaultStep )
+        {
+            return convertDefaultStep(path, (DefaultStep) step);
+        }
+        else 
+        {
+            throw new JaxenException( "Cannot convert: " + step + " to a Pattern" );            
+        }
+        return path;
+    }
+    
+    protected static LocationPathPattern convertDefaultStep(LocationPathPattern path, DefaultStep step) throws JaxenException
+    {
+        List predicates = step.getPredicates();
+        if ( ! predicates.isEmpty() ) 
+        {
+            FilterExpr filter = new DefaultFilterExpr(new PredicateSet());
+            for ( Iterator iter = predicates.iterator(); iter.hasNext(); )
+            {
+                filter.addPredicate( (Predicate) iter.next() );
+            }
+            path.addFilter( filter );
+        }         
+        return path;
+    }
+    
+    protected static boolean navigationStep( Step step )
+    {
+        if ( step instanceof DefaultNameStep )
+        {
+            return true;
+        }
+        else
+        if ( step.getClass().equals( DefaultStep.class ) )
+        {
+            return ! step.getPredicates().isEmpty();
+        }
+        else 
+        {
+            return true;
+        }
+    }
+
+}
+
diff --git a/libjaxen-java/src/java/main/org/jaxen/pattern/TextNodeTest.java b/libjaxen-java/src/java/main/org/jaxen/pattern/TextNodeTest.java
new file mode 100644
index 0000000..047623d
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/pattern/TextNodeTest.java
@@ -0,0 +1,86 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/pattern/TextNodeTest.java,v 1.6 2006/02/05 21:47:42 elharo Exp $
+ * $Revision: 1.6 $
+ * $Date: 2006/02/05 21:47:42 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: TextNodeTest.java,v 1.6 2006/02/05 21:47:42 elharo Exp $
+ */
+
+package org.jaxen.pattern;
+
+import org.jaxen.Context;
+
+/** <p><code>TextNodeTest</code> matches any text node.</p>
+  *
+  * @author <a href="mailto:jstrachan at apache.org">James Strachan</a>
+  * @version $Revision: 1.6 $
+  */
+public class TextNodeTest extends NodeTest {
+    
+    public static final TextNodeTest SINGLETON = new TextNodeTest();
+    
+    public TextNodeTest()   
+    {
+    }
+        
+    /** @return true if the pattern matches the given node
+      */
+    public boolean matches( Object node, Context context ) 
+    {
+        return context.getNavigator().isText( node );
+    }
+    
+    public double getPriority() 
+    {
+        return -0.5;
+    }
+
+    public short getMatchType()
+    {
+        return Pattern.TEXT_NODE;
+    }
+
+    public String getText() 
+    {
+        return "text()";
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/pattern/UnionPattern.java b/libjaxen-java/src/java/main/org/jaxen/pattern/UnionPattern.java
new file mode 100644
index 0000000..be06365
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/pattern/UnionPattern.java
@@ -0,0 +1,164 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/pattern/UnionPattern.java,v 1.8 2006/02/05 21:47:42 elharo Exp $
+ * $Revision: 1.8 $
+ * $Date: 2006/02/05 21:47:42 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: UnionPattern.java,v 1.8 2006/02/05 21:47:42 elharo Exp $
+ */
+
+package org.jaxen.pattern;
+
+import org.jaxen.Context;
+import org.jaxen.JaxenException;
+
+/** <p><code>UnionPattern</code> represents a union pattern.</p>
+  *
+  * @author <a href="mailto:jstrachan at apache.org">James Strachan</a>
+  * @version $Revision: 1.8 $
+  */
+public class UnionPattern extends Pattern {
+
+    private Pattern lhs;
+    private Pattern rhs;
+    private short nodeType = ANY_NODE;
+    private String matchesNodeName = null;
+    
+    
+    public UnionPattern() 
+    {
+    }
+    
+    public UnionPattern(Pattern lhs, Pattern rhs) 
+    {
+        this.lhs = lhs;
+        this.rhs = rhs;
+        init();
+    }
+    
+    
+    public Pattern getLHS() 
+    {
+        return lhs;
+    }
+    
+    public void setLHS(Pattern lhs) 
+    {
+        this.lhs = lhs;
+        init();
+    }
+    
+    public Pattern getRHS() 
+    {
+        return rhs;
+    }
+    
+    public void setRHS(Pattern rhs) 
+    {
+        this.rhs = rhs;
+        init();
+    }
+    
+    
+    // Pattern interface
+    //-------------------------------------------------------------------------    
+    
+    /** @return true if the pattern matches the given node
+      */
+    public boolean matches( Object node, Context context ) throws JaxenException
+    {
+        return lhs.matches( node, context ) || rhs.matches( node, context );
+    }
+    
+    public Pattern[] getUnionPatterns() 
+    {
+        return new Pattern[] { lhs, rhs };
+    }
+
+    
+    public short getMatchType() 
+    {
+        return nodeType;
+    }
+
+
+    public String getMatchesNodeName() 
+    {
+        return matchesNodeName;
+    }
+    
+    
+    public Pattern simplify() 
+    {
+        this.lhs = lhs.simplify();
+        this.rhs = rhs.simplify();
+        init();
+        return this;
+    }
+    
+    public String getText() 
+    {
+        return lhs.getText() + " | " + rhs.getText();
+    }
+        
+    public String toString()
+    {
+        return super.toString() + "[ lhs: " + lhs + " rhs: " + rhs + " ]";
+    }
+    
+    // Implementation methods
+    //-------------------------------------------------------------------------    
+    private void init() 
+    {
+        short type1 = lhs.getMatchType();
+        short type2 = rhs.getMatchType();
+        this.nodeType = ( type1 == type2 ) ? type1 : ANY_NODE;
+        
+        String name1 = lhs.getMatchesNodeName();
+        String name2 = rhs.getMatchesNodeName();
+        
+        this.matchesNodeName = null;
+        if ( name1 != null && name2 != null && name1.equals( name2 ) ) 
+        {
+            this.matchesNodeName = name1;
+        }
+    }    
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/pattern/package.html b/libjaxen-java/src/java/main/org/jaxen/pattern/package.html
new file mode 100644
index 0000000..c47b9d9
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/pattern/package.html
@@ -0,0 +1,9 @@
+<html>
+<head>
+</head>
+<body>
+
+  <p>Defines XSLT Pattern objects. The design of this library is greatly influenced by Michael Kay's SAXON implementation.</p>
+  
+</body>
+</html>
diff --git a/libjaxen-java/src/java/main/org/jaxen/saxpath/Axis.java b/libjaxen-java/src/java/main/org/jaxen/saxpath/Axis.java
new file mode 100644
index 0000000..90b9a83
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/saxpath/Axis.java
@@ -0,0 +1,247 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/saxpath/Axis.java,v 1.8 2006/03/30 13:56:36 elharo Exp $
+ * $Revision: 1.8 $
+ * $Date: 2006/03/30 13:56:36 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Jaxen Project and was originally
+ * created by bob mcwhirter <bob at werken.com> and
+ * James Strachan <jstrachan at apache.org>.  For more information on the
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ *
+ * $Id: Axis.java,v 1.8 2006/03/30 13:56:36 elharo Exp $
+ */
+
+
+
+package org.jaxen.saxpath;
+
+import org.jaxen.JaxenRuntimeException;
+
+
+
+/**
+ * 
+ * Internal SAXPath class that contains constants representing 
+ * XPath operators to avoid a lot of string comparisons. 
+ */
+public class Axis
+{
+    
+    private Axis() {}
+    
+    // XXX Ultimately these should use the type-safe enum pattern instead
+    /** Marker for an invalid axis */
+    public final static int INVALID_AXIS       =  0;
+
+    /** The <code>child</code> axis */
+    public final static int CHILD              =  1;
+
+    /** The <code>descendant</code> axis */
+    public final static int DESCENDANT         =  2;
+
+    /** The <code>parent</code> axis */
+    public final static int PARENT             =  3;
+
+    /** The <code>ancestor</code> axis */
+    public final static int ANCESTOR           =  4;
+
+    /** The <code>following-sibling</code> axis */
+    public final static int FOLLOWING_SIBLING  =  5;
+
+    /** The <code>preceding-sibling</code> axis */
+    public final static int PRECEDING_SIBLING  =  6;
+
+    /** The <code>following</code> axis */
+    public final static int FOLLOWING          =  7;
+
+    /** The <code>preceding</code> axis */
+    public final static int PRECEDING          =  8;
+
+    /** The <code>attribute</code> axis */
+    public final static int ATTRIBUTE          =  9;
+
+    /** The <code>namespace</code> axis */
+    public final static int NAMESPACE          = 10;
+
+    /** The <code>self</code> axis */
+    public final static int SELF               = 11;
+
+    /** The <code>descendant-or-self</code> axis */
+    public final static int DESCENDANT_OR_SELF = 12;
+
+    /** The <code>ancestor-or-self</code> axis */
+    public final static int ANCESTOR_OR_SELF   = 13;
+
+    /**
+     * <p>
+     * Returns the name of the axis.
+     * </p>
+     * 
+     * @param axisNum the axis code
+     * @return the name of the axis such as might be used in an XPath expression
+     * @throws JaxenRuntimeException if the number does not represent one of the 13
+     *     XPath axes
+     */
+    public static String lookup(int axisNum)
+    {
+        switch ( axisNum )
+        {
+            case CHILD:
+                return "child";
+
+            case DESCENDANT:
+                return "descendant";
+
+            case PARENT:
+                return "parent";
+
+            case ANCESTOR:
+                return "ancestor";
+
+            case FOLLOWING_SIBLING:
+                return "following-sibling";
+
+            case PRECEDING_SIBLING:
+                return "preceding-sibling";
+
+            case FOLLOWING:
+                return "following";
+
+            case PRECEDING:
+                return "preceding";
+
+            case ATTRIBUTE:
+                return "attribute";
+
+            case NAMESPACE:
+                return "namespace";
+
+            case SELF:
+                return "self";
+
+            case DESCENDANT_OR_SELF:
+                return "descendant-or-self";
+
+            case ANCESTOR_OR_SELF:
+                return "ancestor-or-self";
+        }
+
+        throw new JaxenRuntimeException("Illegal Axis Number");
+    }
+
+    /**
+     * <p>
+     * Returns the code for an axis given its name.
+     * </p>
+     * 
+     * @param axisName the name of the axis: child, parent, descendant, descendant-or-self, etc.
+     * @return the axis code
+     */
+    public static int lookup(String axisName)
+    {
+        
+        // XXX All these equals calls are a small HotSpot;
+        // Need to replace this with a static HashMap
+        if ( "child".equals( axisName ) )
+        {
+            return CHILD;
+        }
+
+        if ( "descendant".equals( axisName ) )
+        {
+            return DESCENDANT;
+        }
+
+        if ( "parent".equals( axisName ) )
+        {
+            return PARENT;
+        }
+
+        if ( "ancestor".equals( axisName ) )
+        {
+            return ANCESTOR;
+        }
+
+        if ( "following-sibling".equals( axisName ) )
+        {
+            return FOLLOWING_SIBLING;
+        }
+
+        if ( "preceding-sibling".equals( axisName ) )
+        {
+            return PRECEDING_SIBLING;
+        }
+
+        if ( "following".equals( axisName ) )
+        {
+            return FOLLOWING;
+        }
+
+        if ( "preceding".equals( axisName ) )
+        {
+            return PRECEDING;
+        }
+
+        if ( "attribute".equals( axisName ) )
+        {
+            return ATTRIBUTE;
+        }
+
+        if ( "namespace".equals( axisName ) )
+        {
+            return NAMESPACE;
+        }
+
+        if ( "self".equals( axisName ) )
+        {
+            return SELF;
+        }
+
+        if ( "descendant-or-self".equals( axisName ) )
+        {
+            return DESCENDANT_OR_SELF;
+        }
+
+        if ( "ancestor-or-self".equals( axisName ) )
+        {
+            return ANCESTOR_OR_SELF;
+        }
+
+        return INVALID_AXIS;
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/saxpath/Operator.java b/libjaxen-java/src/java/main/org/jaxen/saxpath/Operator.java
new file mode 100644
index 0000000..c7bf3a1
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/saxpath/Operator.java
@@ -0,0 +1,135 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/saxpath/Operator.java,v 1.5 2006/02/05 21:47:42 elharo Exp $
+ * $Revision: 1.5 $
+ * $Date: 2006/02/05 21:47:42 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Jaxen Project and was originally
+ * created by bob mcwhirter <bob at werken.com> and
+ * James Strachan <jstrachan at apache.org>.  For more information on the
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ *
+ * $Id: Operator.java,v 1.5 2006/02/05 21:47:42 elharo Exp $
+ */
+
+package org.jaxen.saxpath;
+
+/**
+ * Constants used to represent XPath operators.
+ */
+public interface Operator
+{
+    /**
+     * Indicates that we're passing through a grammar production without
+     * actually activating it. For example in the expression
+     * <code>1</code> is matches AdditiveExpr and MultiplicativeExpr in 
+     * the XPath grammar, even though it has neither a plus, 
+     * minus, multiplication, or other sign.
+     */
+    final static int NO_OP               =  0;
+    
+    // Equality
+    /**
+     * The equal to operator <code>=</code>. This is equivalent to <code>==</code>
+     * in Java. This is a comparison operator, not an assignment operator.
+     */
+    final static int EQUALS              =  1;
+    
+    /**
+     * The not equal to operator <code>!=</code>
+     */
+    final static int NOT_EQUALS          =  2;
+    
+    // Relational
+    /**
+     * The less-than operator <code><</code>
+     */
+    final static int LESS_THAN           =  3;
+    
+    /**
+     * The less-than-or-equal-to operator <code><=</code>
+     */
+    final static int LESS_THAN_EQUALS    =  4;
+
+    /**
+     * The greater-than operator <code>></code>
+     */
+    final static int GREATER_THAN        =  5;
+
+    /**
+     * The greater-than or equals operator <code>>=</code>
+     */
+    final static int GREATER_THAN_EQUALS =  6;
+    
+    // Additive
+
+    /**
+     * The addition operator <code>+</code>
+     */
+    final static int ADD                 =  7;
+
+    /**
+     * The subtraction operator <code>-</code>
+     */
+    final static int SUBTRACT            =  8;
+
+    // Multiplicative
+
+    /**
+     * The multiplication operator <code>*</code>
+     */
+    final static int MULTIPLY            =  9;
+
+    /**
+     * The remainder operator <code>mod</code>. This is equivalent to
+     * <code>%</code> in Java. 
+     */
+    final static int MOD                 = 10;
+
+    /**
+     * The floating point division operator <code>div</code>.  This is equivalent to
+     * <code>/</code> in Java. 
+     */
+    final static int DIV                 = 11;
+
+    // Unary
+
+    /**
+     * Unary <code>-</code>
+     */
+    final static int NEGATIVE            = 12;
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/saxpath/SAXPathEventSource.java b/libjaxen-java/src/java/main/org/jaxen/saxpath/SAXPathEventSource.java
new file mode 100644
index 0000000..7f6538a
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/saxpath/SAXPathEventSource.java
@@ -0,0 +1,76 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/saxpath/SAXPathEventSource.java,v 1.5 2006/02/05 21:47:42 elharo Exp $
+ * $Revision: 1.5 $
+ * $Date: 2006/02/05 21:47:42 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Jaxen Project and was originally
+ * created by bob mcwhirter <bob at werken.com> and
+ * James Strachan <jstrachan at apache.org>.  For more information on the
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ *
+ * $Id: SAXPathEventSource.java,v 1.5 2006/02/05 21:47:42 elharo Exp $
+ */
+
+
+
+package org.jaxen.saxpath;
+
+
+
+/** Interface for any object capable of generating
+ *  SAXPath events to an {@link org.jaxen.saxpath.XPathHandler}.
+ *
+ *  @author bob mcwhirter (bob at werken.com)
+ */
+public interface SAXPathEventSource
+{
+    /** Set the {@link org.jaxen.saxpath.XPathHandler} to receive
+     *  event callbacks during the parse.
+     *
+     *  @param handler the handler to receive callbacks
+     */
+    void setXPathHandler(XPathHandler handler);
+    
+    /** Retrieve the current {@link org.jaxen.saxpath.XPathHandler}
+     *  which receives the event callbacks.
+     *
+     *  @return the currently installed  <code>XPathHandler</code>
+     */
+    XPathHandler getXPathHandler();
+    
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/saxpath/SAXPathException.java b/libjaxen-java/src/java/main/org/jaxen/saxpath/SAXPathException.java
new file mode 100644
index 0000000..25b71da
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/saxpath/SAXPathException.java
@@ -0,0 +1,172 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/saxpath/SAXPathException.java,v 1.14 2006/06/03 20:28:45 elharo Exp $
+ * $Revision: 1.14 $
+ * $Date: 2006/06/03 20:28:45 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Jaxen Project and was originally
+ * created by bob mcwhirter <bob at werken.com> and
+ * James Strachan <jstrachan at apache.org>.  For more information on the
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ *
+ * $Id: SAXPathException.java,v 1.14 2006/06/03 20:28:45 elharo Exp $
+ */
+
+package org.jaxen.saxpath;
+
+import java.io.PrintStream;
+import java.io.PrintWriter;
+
+/** Base of all SAXPath exceptions.
+ *
+ *  @author bob mcwhirter (bob at werken.com)
+ */
+public class SAXPathException extends Exception
+{
+    
+    /**
+     * 
+     */
+    private static final long serialVersionUID = 4826444568928720706L;
+    
+    private static double javaVersion = 1.4;
+    
+    static {
+        try {
+            String versionString = System.getProperty("java.version");
+            versionString = versionString.substring(0, 3);
+            javaVersion = Double.valueOf(versionString).doubleValue();
+        }
+        catch (Exception ex) {
+            // The version string format changed so presumably it's
+            // 1.4 or later.
+        }
+    }
+    
+    /** Create a new SAXPathException with a given message.
+     *
+     *  @param message the error message
+     */
+    public SAXPathException(String message)
+    {
+        super( message );
+    }
+
+    /** Create a new SAXPathException based on another exception
+     *
+     *  @param cause the error source
+     */
+    public SAXPathException(Throwable cause)
+    {
+        super ( cause.getMessage() );
+        initCause(cause);
+    }
+
+    /**
+     * Create a new SAXPathException with the specified detail message
+     * and root cause.
+     * 
+     * @param message the detail message
+     * @param cause the cause of this exception
+     */
+    public SAXPathException(String message, Throwable cause) {
+        super( message );
+        initCause(cause);
+    }
+    
+    
+    private Throwable cause;
+    private boolean causeSet = false;
+
+    /**
+     * Returns the exception that caused this exception.
+     * This is necessary to implement Java 1.4 chained exception 
+     * functionality in a Java 1.3-compatible way.
+     * 
+     * @return the exception that caused this exception
+     */
+    public Throwable getCause() {
+        return cause;
+    }
+    
+
+    /**
+     * Sets the exception that caused this exception.
+     * This is necessary to implement Java 1.4 chained exception 
+     * functionality in a Java 1.3-compatible way.
+     * 
+     * @param cause the exception wrapped in this runtime exception
+     * 
+     * @return this exception
+     */
+    public Throwable initCause(Throwable cause) {
+        if (causeSet) throw new IllegalStateException("Cause cannot be reset");
+        if (cause == this) throw new IllegalArgumentException("Exception cannot be its own cause");
+        causeSet = true;
+        this.cause = cause;
+        return this;
+    }
+
+    /** Print this exception's stack trace, followed by the
+     *  source exception's trace, if any.
+     *
+     * @param s the stream on which to print the stack trace
+     */
+    public void printStackTrace ( PrintStream s )
+    {
+        super.printStackTrace ( s );
+        if (javaVersion < 1.4 && getCause() != null) {
+            s.print( "Caused by: " );
+            getCause().printStackTrace( s );
+        }
+    }
+
+    /** Print this exception's stack trace, followed by the
+     *  source exception's stack trace, if any.
+     *
+     * @param s the writer on which to print the stack trace
+     */
+    public void printStackTrace ( PrintWriter s )
+    {
+        super.printStackTrace( s );
+        if (javaVersion < 1.4 && getCause() != null) {
+            s.print( "Caused by: " );
+            getCause().printStackTrace( s );
+        }
+    }
+
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/saxpath/XPathHandler.java b/libjaxen-java/src/java/main/org/jaxen/saxpath/XPathHandler.java
new file mode 100644
index 0000000..35288a0
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/saxpath/XPathHandler.java
@@ -0,0 +1,319 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/saxpath/XPathHandler.java,v 1.9 2006/02/05 21:47:42 elharo Exp $
+ * $Revision: 1.9 $
+ * $Date: 2006/02/05 21:47:42 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Jaxen Project and was originally
+ * created by bob mcwhirter <bob at werken.com> and
+ * James Strachan <jstrachan at apache.org>.  For more information on the
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ *
+ * $Id: XPathHandler.java,v 1.9 2006/02/05 21:47:42 elharo Exp $
+ */
+
+
+
+
+package org.jaxen.saxpath;
+
+
+/** Interface for event-based XPath parsing.
+ *
+ *  <p>
+ *  A {@link org.jaxen.saxpath.XPathReader} generates callbacks into
+ *  an <code>XPathHandler</code> to allow for custom
+ *  handling of the parse.
+ *  </p>
+ *
+ *  <p>
+ *  The callbacks very closely match the productions
+ *  listed in the W3C XPath specification.  Gratuitous
+ *  productions (e.g. Expr/startExpr()/endExpr()) are not
+ *  included in this API.
+ *  </p>
+ *
+ *  @author bob mcwhirter (bob at werken.com)
+ */
+public interface XPathHandler
+{
+    /** Receive notification of the start of an XPath expression parse.
+     */
+    void startXPath() throws org.jaxen.saxpath.SAXPathException;
+
+    /** Receive notification of the end of an XPath expression parse.
+     */
+    void endXPath() throws org.jaxen.saxpath.SAXPathException;
+
+    /** Receive notification of the start of a path expression.
+     */
+    void startPathExpr() throws org.jaxen.saxpath.SAXPathException;
+
+    /** Receive notification of the end of a path expression.
+     */
+    void endPathExpr() throws org.jaxen.saxpath.SAXPathException;
+
+    /** Receive notification of the start of an absolute location path expression.
+     */
+    void startAbsoluteLocationPath() throws org.jaxen.saxpath.SAXPathException;
+
+    /** Receive notification of the end of an absolute location path expression.
+     */
+    void endAbsoluteLocationPath() throws org.jaxen.saxpath.SAXPathException;
+
+    /** Receive notification of the start of a relative location path expression.
+     */
+    void startRelativeLocationPath() throws org.jaxen.saxpath.SAXPathException;
+
+    /** Receive notification of the end of a relative location path expression.
+     */
+    void endRelativeLocationPath() throws org.jaxen.saxpath.SAXPathException;
+
+    /** Receive notification of the start of a name step.
+     *
+     *  @param axis the axis of this step
+     *  @param prefix the namespace prefix for the name to test,
+     *         or the empty string if no prefix is specified
+     *  @param localName the local part of the name to test
+     */
+    void startNameStep(int axis,
+                       String prefix,
+                       String localName) throws org.jaxen.saxpath.SAXPathException;
+
+    /** Receive notification of the end of a NameStep
+     */
+    void endNameStep() throws org.jaxen.saxpath.SAXPathException;
+
+    /** Receive notification of the start of a text() step.
+     *
+     *  @param axis the axis of this step
+     */
+    void startTextNodeStep(int axis) throws org.jaxen.saxpath.SAXPathException;
+
+    /** Receive notification of the end of a text() step.
+     */
+    void endTextNodeStep() throws org.jaxen.saxpath.SAXPathException;
+
+    /** Receive notification of the start of a comment() step.
+     *
+     *  @param axis the axis of this step
+     */
+    void startCommentNodeStep(int axis) throws org.jaxen.saxpath.SAXPathException;
+
+    /** Receive notification of the end of a comment() step.
+     */
+    void endCommentNodeStep() throws org.jaxen.saxpath.SAXPathException;
+
+    /** Receive notification of the start of a node() step.
+     *
+     *  @param axis the axis of this step
+     */
+    void startAllNodeStep(int axis) throws org.jaxen.saxpath.SAXPathException;
+
+    /** Receive notification of the end of a node() step.
+     */
+    void endAllNodeStep() throws org.jaxen.saxpath.SAXPathException;
+
+    /** Receive notification of the start of a processing-instruction(...) step.
+     *
+     *  @param axis the axis of this step
+     *  @param name the name of the processing-instruction, or
+     *         the empty string if none is specified
+     */
+    void startProcessingInstructionNodeStep(int axis,
+                                            String name) throws org.jaxen.saxpath.SAXPathException;
+
+    /** Receive notification of the end of a processing-instruction(...) step.
+     */
+    void endProcessingInstructionNodeStep() throws org.jaxen.saxpath.SAXPathException;
+
+    /** Receive notification of the start of a predicate.
+     */
+    void startPredicate() throws org.jaxen.saxpath.SAXPathException;
+
+    /** Receive notification of the end of a predicate.
+     */
+    void endPredicate() throws org.jaxen.saxpath.SAXPathException;
+
+    /** Receive notification of the start of a filter expression.
+     */
+    void startFilterExpr() throws org.jaxen.saxpath.SAXPathException;
+
+    /** Receive notification of the end of a filter expression.
+     */
+    void endFilterExpr() throws org.jaxen.saxpath.SAXPathException;
+
+    /** Receive notification of the start of an 'or' expression.
+     */
+    void startOrExpr() throws org.jaxen.saxpath.SAXPathException;
+
+    /** Receive notification of the end of an 'or' expression.
+     *
+     *  @param create flag that indicates if this expression
+     *         should truly be instantiated, or if it was just
+     *         a pass-through, based upon the grammar productions
+     */
+    void endOrExpr(boolean create) throws org.jaxen.saxpath.SAXPathException;
+
+    /** Receive notification of the start of an 'and' expression.
+     */
+    void startAndExpr() throws org.jaxen.saxpath.SAXPathException;
+
+    /** Receive notification of the end of an 'and' expression.
+     *
+     *  @param create flag that indicates if this expression
+     *         should truly be instantiated, or if it was just
+     *         a pass-through, based upon the grammar productions
+     */
+    void endAndExpr(boolean create) throws org.jaxen.saxpath.SAXPathException;
+
+    /** Receive notification of the start of an equality ('=' or '!=') expression.
+     */
+    void startEqualityExpr() throws org.jaxen.saxpath.SAXPathException;
+
+    /** Receive notification of the end of an equality ('=' or '!=') expression.
+     *
+     *  @param equalityOperator the operator specific to this particular
+     *         equality expression.  If null, this expression
+     *         is only a pass-through, and should not actually
+     *         be instantiated.
+     */
+    void endEqualityExpr(int equalityOperator) throws org.jaxen.saxpath.SAXPathException;
+
+    /** Receive notification of the start of a relational ('<', '>', '<=', or '>=') expression.
+     */
+    void startRelationalExpr() throws org.jaxen.saxpath.SAXPathException;
+
+    /** Receive notification of the start of a relational ('<', '>', '<=', or '>=') expression.
+     *
+     *  @param relationalOperator the operator specific to this particular
+     *         relational expression.  If NO_OP, this expression
+     *         is only a pass-through, and should not actually
+     *         be instantiated.
+     */
+    void endRelationalExpr(int relationalOperator) throws org.jaxen.saxpath.SAXPathException;
+
+    /** Receive notification of the start of an additive ('+' or '-') expression.
+     */
+    void startAdditiveExpr() throws org.jaxen.saxpath.SAXPathException;
+
+    /** Receive notification of the end of an additive ('+' or '-') expression.
+     *
+     *  @param additiveOperator the operator specific to this particular
+     *         additive expression.   If NO_OP, this expression
+     *         is only a pass-through, and should not actually
+     *         be instantiated.
+     */
+    void endAdditiveExpr(int additiveOperator) throws org.jaxen.saxpath.SAXPathException;
+
+    /** Receive notification of the start of a multiplicative ('*', 'div' or 'mod') expression.
+     */
+    void startMultiplicativeExpr() throws org.jaxen.saxpath.SAXPathException;
+
+    /** Receive notification of the start of a multiplicative ('*', 'div' or 'mod') expression.
+     *
+     *  @param multiplicativeOperator the operator specific to this particular
+     *         multiplicative expression.  If null, this expression
+     *         is only a pass-through, and should not actually
+     *         be instantiated.
+     */
+    void endMultiplicativeExpr(int multiplicativeOperator) throws org.jaxen.saxpath.SAXPathException;
+
+    /** Receive notification of the start of a unary ('+' or '-') expression.
+     */
+    void startUnaryExpr() throws org.jaxen.saxpath.SAXPathException;
+
+    /** Receive notification of the end of a unary ('+' or '-') expression.
+     *
+     *  @param unaryOperator the operator specific to this particular
+     *         unary expression. If NO_OP, this expression is only
+     *         a pass-through, and should not actually be instantiated.
+     *         If not {@link org.jaxen.saxpath.Operator#NO_OP}, it will 
+     *         always be {@link org.jaxen.saxpath.Operator#NEGATIVE}.
+     */
+    void endUnaryExpr(int unaryOperator) throws org.jaxen.saxpath.SAXPathException;
+
+    /** Receive notification of the start of a union ('|') expression.
+     */
+    void startUnionExpr() throws org.jaxen.saxpath.SAXPathException;
+
+    /** Receive notification of the end of a union ('|') expression.
+     *
+     *  @param create flag that indicates if this expression
+     *         should truly be instantiated, or if it was just
+     *         a pass-through, based upon the grammar productions
+     */
+    void endUnionExpr(boolean create) throws org.jaxen.saxpath.SAXPathException;
+
+    /** Receive notification of a number expression.
+     *
+     *  @param number the number value
+     */
+    void number(int number) throws org.jaxen.saxpath.SAXPathException;
+
+    /** Receive notification of a number expression.
+     *
+     *  @param number the number value
+     */
+    void number(double number) throws org.jaxen.saxpath.SAXPathException;
+
+    /** Receive notification of a literal expression.
+     *
+     *  @param literal the string literal value
+     */
+    void literal(String literal) throws org.jaxen.saxpath.SAXPathException;
+
+    /** Receive notification of a variable-reference expression.
+     *
+     *  @param prefix the namespace prefix of the variable
+     *  @param variableName the local name of the variable
+     */
+    void variableReference(String prefix,
+                           String variableName) throws org.jaxen.saxpath.SAXPathException;
+
+    /** Receive notification of a function call.
+     *
+     *  @param prefix the namespace prefix of the function
+     *  @param functionName the local name of the function
+     */
+    void startFunction(String prefix,
+                       String functionName) throws org.jaxen.saxpath.SAXPathException;
+
+    /** Receive notification of the end of a function call
+     */
+    void endFunction() throws org.jaxen.saxpath.SAXPathException;
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/saxpath/XPathReader.java b/libjaxen-java/src/java/main/org/jaxen/saxpath/XPathReader.java
new file mode 100644
index 0000000..9af58b9
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/saxpath/XPathReader.java
@@ -0,0 +1,69 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/saxpath/XPathReader.java,v 1.6 2006/02/05 21:47:42 elharo Exp $
+ * $Revision: 1.6 $
+ * $Date: 2006/02/05 21:47:42 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Jaxen Project and was originally
+ * created by bob mcwhirter <bob at werken.com> and
+ * James Strachan <jstrachan at apache.org>.  For more information on the
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ *
+ * $Id: XPathReader.java,v 1.6 2006/02/05 21:47:42 elharo Exp $
+ */
+
+
+package org.jaxen.saxpath;
+
+
+/** Interface for readers which can parse textual
+ *  XPath expressions, and produce callbacks to
+ *  {@link org.jaxen.saxpath.XPathHandler} objects.
+ *
+ *  @author bob mcwhirter (bob at werken.com)
+ */
+public interface XPathReader extends SAXPathEventSource
+{
+    /** Parse an XPath expression,
+     *  and send event callbacks to an {@link org.jaxen.saxpath.XPathHandler}.
+     *
+     *  @param xpath the textual XPath expression to parse
+     *
+     *  @throws SAXPathException if the expression is syntactically incorrect
+     */
+    void parse(String xpath) throws SAXPathException;
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/saxpath/XPathSyntaxException.java b/libjaxen-java/src/java/main/org/jaxen/saxpath/XPathSyntaxException.java
new file mode 100644
index 0000000..a920fba
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/saxpath/XPathSyntaxException.java
@@ -0,0 +1,160 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/saxpath/XPathSyntaxException.java,v 1.10 2006/06/03 20:29:30 elharo Exp $
+ * $Revision: 1.10 $
+ * $Date: 2006/06/03 20:29:30 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Jaxen Project and was originally
+ * created by bob mcwhirter <bob at werken.com> and
+ * James Strachan <jstrachan at apache.org>.  For more information on the
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ *
+ * $Id: XPathSyntaxException.java,v 1.10 2006/06/03 20:29:30 elharo Exp $
+ */
+
+package org.jaxen.saxpath;
+
+
+/**
+ * Represents a syntax error in an XPath expression.
+ * This is a compile-time error that is detectable irrespective of 
+ * the context in which the XPath expression is evaluated.
+ */
+public class XPathSyntaxException extends SAXPathException
+{
+    /**
+     * 
+     */
+    private static final long serialVersionUID = 3567675610742422397L;
+    private String xpath;
+    private int    position;
+    private final static String lineSeparator = System.getProperty("line.separator");
+
+    /**
+     * Creates a new XPathSyntaxException.
+     * 
+     * @param xpath the incorrect XPath expression 
+     * @param position the index of the character at which the syntax error was detected
+     * @param message the detail message
+     */
+    public XPathSyntaxException(String xpath,
+                                int position,
+                                String message)
+    {
+        super( message );
+        this.position = position;
+        this.xpath    = xpath;
+    }
+
+    /**
+     * <p>
+     * Returns the index of the character at which the syntax error was detected
+     * in the XPath expression.
+     * </p>
+     * 
+     * @return the character index in the XPath expression  
+     *     at which the syntax error was detected
+     */
+    public int getPosition()
+    {
+        return this.position;
+    }
+
+    /**
+     * <p>
+     * Returns the syntactically incorrect XPath expression.
+     * </p>
+     * 
+     * @return the syntactically incorrect XPath expression
+     */
+    public String getXPath()
+    {
+        return this.xpath;
+    }
+
+    public String toString()
+    {
+        return getClass() + ": " + getXPath() + ": " + getPosition() + ": " + getMessage();
+    }
+
+    /**
+     * <p>
+     * Returns a string in the form <code>"   ^"</code> which, when placed on the line
+     * below the XPath expression in a monospaced font, should point to the
+     * location of the error.
+     * </p>
+     * 
+     * @return the position marker 
+     */
+    private String getPositionMarker()
+    {
+        int pos = getPosition();
+        StringBuffer buf = new StringBuffer(pos+1);
+        for ( int i = 0 ; i < pos ; ++i )
+        {
+            buf.append(" ");
+        }
+
+        buf.append("^");
+
+        return buf.toString();
+        
+    }
+
+    /**
+     * <p>
+     * Returns a long formatted description of the error,
+     * including line breaks.
+     * </p>
+     * 
+     * @return a longer description of the error on multiple lines
+     */
+    public String getMultilineMessage()
+    {
+        StringBuffer buf = new StringBuffer();
+
+        buf.append( getMessage() );
+        buf.append( lineSeparator );
+        buf.append( getXPath() );
+        buf.append( lineSeparator );
+
+        buf.append( getPositionMarker() );
+
+        return buf.toString();
+    }
+
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/saxpath/base/Token.java b/libjaxen-java/src/java/main/org/jaxen/saxpath/base/Token.java
new file mode 100644
index 0000000..9f09514
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/saxpath/base/Token.java
@@ -0,0 +1,117 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/saxpath/base/Token.java,v 1.5 2006/02/05 21:47:42 elharo Exp $
+ * $Revision: 1.5 $
+ * $Date: 2006/02/05 21:47:42 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Jaxen Project and was originally
+ * created by bob mcwhirter <bob at werken.com> and
+ * James Strachan <jstrachan at apache.org>.  For more information on the
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ *
+ * $Id: Token.java,v 1.5 2006/02/05 21:47:42 elharo Exp $
+ */
+
+
+
+
+package org.jaxen.saxpath.base;
+
+class Token
+{
+    private int    tokenType;
+    private String parseText;
+    private int    tokenBegin;
+    private int    tokenEnd;
+
+    Token(int tokenType,
+          String parseText,
+          int tokenBegin,
+          int tokenEnd)
+    {
+        setTokenType( tokenType );
+        setParseText( parseText );
+        setTokenBegin( tokenBegin );
+        setTokenEnd( tokenEnd );
+    }
+
+    private void setTokenType(int tokenType)
+    {
+        this.tokenType = tokenType;
+    }
+
+    int getTokenType()
+    {
+        return this.tokenType;
+    }
+
+    private void setParseText(String parseText)
+    {
+        this.parseText = parseText;
+    }
+
+    String getTokenText()
+    {
+        return this.parseText.substring( getTokenBegin(),
+                                         getTokenEnd() );
+    }
+
+    private void setTokenBegin(int tokenBegin)
+    {
+        this.tokenBegin = tokenBegin;
+    }
+
+    int getTokenBegin()
+    {
+        return this.tokenBegin;
+    }
+
+    private void setTokenEnd(int tokenEnd)
+    {
+        this.tokenEnd = tokenEnd;
+    }
+
+    int getTokenEnd()
+    {
+        return this.tokenEnd;
+    }
+
+    public String toString()
+    {
+        return ("[ (" + tokenType + ") (" + getTokenText() + ")");
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/saxpath/base/TokenTypes.java b/libjaxen-java/src/java/main/org/jaxen/saxpath/base/TokenTypes.java
new file mode 100644
index 0000000..2972b4b
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/saxpath/base/TokenTypes.java
@@ -0,0 +1,183 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/saxpath/base/TokenTypes.java,v 1.12 2006/02/05 21:47:42 elharo Exp $
+ * $Revision: 1.12 $
+ * $Date: 2006/02/05 21:47:42 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2004 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Jaxen Project and was originally
+ * created by bob mcwhirter <bob at werken.com> and
+ * James Strachan <jstrachan at apache.org>.  For more information on the
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ *
+ * $Id: TokenTypes.java,v 1.12 2006/02/05 21:47:42 elharo Exp $
+ */
+
+package org.jaxen.saxpath.base;
+
+
+class TokenTypes
+{
+    static final int EOF   = -1;
+    static final int SKIP  = -2;
+    static final int ERROR = -3;
+
+    static final int EQUALS = 1;
+    static final int NOT_EQUALS = 2;
+    
+    static final int LESS_THAN_SIGN = 3;
+    static final int LESS_THAN_OR_EQUALS_SIGN = 4;
+    static final int GREATER_THAN_SIGN = 5;
+    static final int GREATER_THAN_OR_EQUALS_SIGN = 6;  
+    
+    static final int PLUS  = 7;
+    static final int MINUS = 8;
+    static final int STAR  = 9;
+    static final int MOD   = 10;
+    static final int DIV   = 11;
+    
+    static final int SLASH = 12;
+    static final int DOUBLE_SLASH = 13;
+    static final int DOT = 14;
+    static final int DOT_DOT = 15;
+
+    static final int IDENTIFIER = 16;
+
+    static final int AT = 17;
+    static final int PIPE = 18;
+    static final int COLON = 19;
+    static final int DOUBLE_COLON = 20;
+    
+    static final int LEFT_BRACKET = 21;
+    static final int RIGHT_BRACKET = 22;    
+    static final int LEFT_PAREN = 23;
+    static final int RIGHT_PAREN = 24;
+
+    // 25 was NOT but there is no such token in XPath
+    static final int DOLLAR = 25;
+    static final int LITERAL = 26;
+    static final int AND = 27;
+    static final int OR = 28;
+
+    // No need for an integer token type. All numbers
+    // in XPath are doubles.
+    static final int DOUBLE = 29;
+    static final int COMMA = 30;
+
+    static String getTokenText( int tokenType )
+    {
+        switch( tokenType )
+        {
+            case ERROR:
+                return "(error)";
+            case SKIP:
+                return "(skip)";
+            case EOF:
+                return "(eof)";
+            case 0:
+                return "Unrecognized token type: 0";
+            case EQUALS:
+                return "=";
+            case NOT_EQUALS:
+                return "!=";
+            case LESS_THAN_SIGN:
+                return "<";
+            case LESS_THAN_OR_EQUALS_SIGN:
+                return "<=";
+            case GREATER_THAN_SIGN:
+                return ">";
+            case GREATER_THAN_OR_EQUALS_SIGN:
+                return ">=";
+            case PLUS:
+                return "+";
+            case MINUS:
+                return "-";
+            case STAR:
+                return "*";
+            case DIV:
+                return "div";
+            case MOD:
+                return "mod";
+            case SLASH:
+                return "/";
+            case DOUBLE_SLASH:
+                return "//";
+            case DOT:
+                return ".";
+            case DOT_DOT:
+                return "..";
+            case IDENTIFIER:
+                return "(identifier)";
+            case AT:
+                return "@";
+            case PIPE:
+                return "|";
+            case COLON:
+                return ":";
+            case DOUBLE_COLON:
+                return "::";
+            case LEFT_BRACKET:
+                return "[";
+            case RIGHT_BRACKET:
+                return "]";
+            case LEFT_PAREN:
+                return "(";
+            case RIGHT_PAREN:
+                return ")";
+            case DOLLAR:
+                return "$";
+            case LITERAL:
+                return "(literal)";
+            case AND:
+                return "and";
+            case OR:
+                return "or";
+            case DOUBLE:
+                return "(double)";
+            case COMMA:
+                return ",";
+            default:
+                // This method is only called from an error handler, and only
+                // to provide an exception message. In other words, the string
+                // returned by this method is only used in an exception message.
+                // Something has already gone wrong, and is being reported.
+                // Thus there's no real reason to throw another exception here.
+                // Just return a string and this message will be reported in an
+                // exception anyway.
+                return("Unrecognized token type: " + tokenType);
+        }
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/saxpath/base/Verifier.java b/libjaxen-java/src/java/main/org/jaxen/saxpath/base/Verifier.java
new file mode 100644
index 0000000..af6cba9
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/saxpath/base/Verifier.java
@@ -0,0 +1,508 @@
+/*-- 
+ *
+ * $Id$
+ *
+ * Copyright 2000-2004 Jason Hunter & Brett McLaughlin.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ *  
+ */
+
+package org.jaxen.saxpath.base;
+
+/**
+ * A utility class to handle well-formedness checks on names. 
+ *
+ * @author  Brett McLaughlin
+ * @author  Elliotte Rusty Harold
+ * @author  Jason Hunter
+ * @author  Bradley S. Huffman
+ */
+final class Verifier {
+
+    /**
+     * This is a utility function for determining whether a specified 
+     * character is a name character according to production 4 of the 
+     * XML 1.0 specification.
+     *
+     * @param c <code>char</code> to check for XML name compliance.
+     * @return <code>boolean</code> true if it's a name character, 
+     *                                false otherwise
+     */
+     static boolean isXMLNCNameCharacter(char c) {
+    
+      return (isXMLLetter(c) || isXMLDigit(c) || c == '.' || c == '-' 
+                             || c == '_' || isXMLCombiningChar(c) 
+                             || isXMLExtender(c));
+    }
+
+    /**
+     * This is a utility function for determining whether a specified 
+     * character is a legal name start character according to production 5
+     * of the XML 1.0 specification. This production does allow names
+     * to begin with colons which the Namespaces in XML Recommendation
+     * disallows. 
+     *
+     * @param c <code>char</code> to check for XML name start compliance
+     * @return true if it's a name start character, false otherwise
+     */
+    static boolean isXMLNCNameStartCharacter(char c) {
+    
+      return (isXMLLetter(c) || c == '_');
+    
+    }
+
+    /**
+     * Determine whether a specified character
+     * is a letter according to production 84 of the XML 1.0 specification.
+     *
+     * @param c <code>char</code> to check for XML name compliance
+     * @return <code>String</code> true if it's a letter, false otherwise
+     */
+    static boolean isXMLLetter(char c) {
+        // Note that order is very important here.  The search proceeds 
+        // from lowest to highest values, so that no searching occurs 
+        // above the character's value.  BTW, the first line is equivalent to:
+        // if (c >= 0x0041 && c <= 0x005A) return true;
+
+        if (c < 0x0041) return false;  if (c <= 0x005a) return true;
+        if (c < 0x0061) return false;  if (c <= 0x007A) return true;
+        if (c < 0x00C0) return false;  if (c <= 0x00D6) return true;
+        if (c < 0x00D8) return false;  if (c <= 0x00F6) return true;
+        if (c < 0x00F8) return false;  if (c <= 0x00FF) return true;
+        if (c < 0x0100) return false;  if (c <= 0x0131) return true;
+        if (c < 0x0134) return false;  if (c <= 0x013E) return true;
+        if (c < 0x0141) return false;  if (c <= 0x0148) return true;
+        if (c < 0x014A) return false;  if (c <= 0x017E) return true;
+        if (c < 0x0180) return false;  if (c <= 0x01C3) return true;
+        if (c < 0x01CD) return false;  if (c <= 0x01F0) return true;
+        if (c < 0x01F4) return false;  if (c <= 0x01F5) return true;
+        if (c < 0x01FA) return false;  if (c <= 0x0217) return true;
+        if (c < 0x0250) return false;  if (c <= 0x02A8) return true;
+        if (c < 0x02BB) return false;  if (c <= 0x02C1) return true;
+        if (c == 0x0386) return true;
+        if (c < 0x0388) return false;  if (c <= 0x038A) return true;
+        if (c == 0x038C) return true;
+        if (c < 0x038E) return false;  if (c <= 0x03A1) return true;
+        if (c < 0x03A3) return false;  if (c <= 0x03CE) return true;
+        if (c < 0x03D0) return false;  if (c <= 0x03D6) return true;
+        if (c == 0x03DA) return true;
+        if (c == 0x03DC) return true;
+        if (c == 0x03DE) return true;
+        if (c == 0x03E0) return true;
+        if (c < 0x03E2) return false;  if (c <= 0x03F3) return true;
+        if (c < 0x0401) return false;  if (c <= 0x040C) return true;
+        if (c < 0x040E) return false;  if (c <= 0x044F) return true;
+        if (c < 0x0451) return false;  if (c <= 0x045C) return true;
+        if (c < 0x045E) return false;  if (c <= 0x0481) return true;
+        if (c < 0x0490) return false;  if (c <= 0x04C4) return true;
+        if (c < 0x04C7) return false;  if (c <= 0x04C8) return true;
+        if (c < 0x04CB) return false;  if (c <= 0x04CC) return true;
+        if (c < 0x04D0) return false;  if (c <= 0x04EB) return true;
+        if (c < 0x04EE) return false;  if (c <= 0x04F5) return true;
+        if (c < 0x04F8) return false;  if (c <= 0x04F9) return true;
+        if (c < 0x0531) return false;  if (c <= 0x0556) return true;
+        if (c == 0x0559) return true;
+        if (c < 0x0561) return false;  if (c <= 0x0586) return true;
+        if (c < 0x05D0) return false;  if (c <= 0x05EA) return true;
+        if (c < 0x05F0) return false;  if (c <= 0x05F2) return true;
+        if (c < 0x0621) return false;  if (c <= 0x063A) return true;
+        if (c < 0x0641) return false;  if (c <= 0x064A) return true;
+        if (c < 0x0671) return false;  if (c <= 0x06B7) return true;
+        if (c < 0x06BA) return false;  if (c <= 0x06BE) return true;
+        if (c < 0x06C0) return false;  if (c <= 0x06CE) return true;
+        if (c < 0x06D0) return false;  if (c <= 0x06D3) return true;
+        if (c == 0x06D5) return true;
+        if (c < 0x06E5) return false;  if (c <= 0x06E6) return true;
+        if (c < 0x0905) return false;  if (c <= 0x0939) return true;
+        if (c == 0x093D) return true;
+        if (c < 0x0958) return false;  if (c <= 0x0961) return true;
+        if (c < 0x0985) return false;  if (c <= 0x098C) return true;
+        if (c < 0x098F) return false;  if (c <= 0x0990) return true;
+        if (c < 0x0993) return false;  if (c <= 0x09A8) return true;
+        if (c < 0x09AA) return false;  if (c <= 0x09B0) return true;
+        if (c == 0x09B2) return true;
+        if (c < 0x09B6) return false;  if (c <= 0x09B9) return true;
+        if (c < 0x09DC) return false;  if (c <= 0x09DD) return true;
+        if (c < 0x09DF) return false;  if (c <= 0x09E1) return true;
+        if (c < 0x09F0) return false;  if (c <= 0x09F1) return true;
+        if (c < 0x0A05) return false;  if (c <= 0x0A0A) return true;
+        if (c < 0x0A0F) return false;  if (c <= 0x0A10) return true;
+        if (c < 0x0A13) return false;  if (c <= 0x0A28) return true;
+        if (c < 0x0A2A) return false;  if (c <= 0x0A30) return true;
+        if (c < 0x0A32) return false;  if (c <= 0x0A33) return true;
+        if (c < 0x0A35) return false;  if (c <= 0x0A36) return true;
+        if (c < 0x0A38) return false;  if (c <= 0x0A39) return true;
+        if (c < 0x0A59) return false;  if (c <= 0x0A5C) return true;
+        if (c == 0x0A5E) return true;
+        if (c < 0x0A72) return false;  if (c <= 0x0A74) return true;
+        if (c < 0x0A85) return false;  if (c <= 0x0A8B) return true;
+        if (c == 0x0A8D) return true;
+        if (c < 0x0A8F) return false;  if (c <= 0x0A91) return true;
+        if (c < 0x0A93) return false;  if (c <= 0x0AA8) return true;
+        if (c < 0x0AAA) return false;  if (c <= 0x0AB0) return true;
+        if (c < 0x0AB2) return false;  if (c <= 0x0AB3) return true;
+        if (c < 0x0AB5) return false;  if (c <= 0x0AB9) return true;
+        if (c == 0x0ABD) return true;
+        if (c == 0x0AE0) return true;
+        if (c < 0x0B05) return false;  if (c <= 0x0B0C) return true;
+        if (c < 0x0B0F) return false;  if (c <= 0x0B10) return true;
+        if (c < 0x0B13) return false;  if (c <= 0x0B28) return true;
+        if (c < 0x0B2A) return false;  if (c <= 0x0B30) return true;
+        if (c < 0x0B32) return false;  if (c <= 0x0B33) return true;
+        if (c < 0x0B36) return false;  if (c <= 0x0B39) return true;
+        if (c == 0x0B3D) return true;
+        if (c < 0x0B5C) return false;  if (c <= 0x0B5D) return true;
+        if (c < 0x0B5F) return false;  if (c <= 0x0B61) return true;
+        if (c < 0x0B85) return false;  if (c <= 0x0B8A) return true;
+        if (c < 0x0B8E) return false;  if (c <= 0x0B90) return true;
+        if (c < 0x0B92) return false;  if (c <= 0x0B95) return true;
+        if (c < 0x0B99) return false;  if (c <= 0x0B9A) return true;
+        if (c == 0x0B9C) return true;
+        if (c < 0x0B9E) return false;  if (c <= 0x0B9F) return true;
+        if (c < 0x0BA3) return false;  if (c <= 0x0BA4) return true;
+        if (c < 0x0BA8) return false;  if (c <= 0x0BAA) return true;
+        if (c < 0x0BAE) return false;  if (c <= 0x0BB5) return true;
+        if (c < 0x0BB7) return false;  if (c <= 0x0BB9) return true;
+        if (c < 0x0C05) return false;  if (c <= 0x0C0C) return true;
+        if (c < 0x0C0E) return false;  if (c <= 0x0C10) return true;
+        if (c < 0x0C12) return false;  if (c <= 0x0C28) return true;
+        if (c < 0x0C2A) return false;  if (c <= 0x0C33) return true;
+        if (c < 0x0C35) return false;  if (c <= 0x0C39) return true;
+        if (c < 0x0C60) return false;  if (c <= 0x0C61) return true;
+        if (c < 0x0C85) return false;  if (c <= 0x0C8C) return true;
+        if (c < 0x0C8E) return false;  if (c <= 0x0C90) return true;
+        if (c < 0x0C92) return false;  if (c <= 0x0CA8) return true;
+        if (c < 0x0CAA) return false;  if (c <= 0x0CB3) return true;
+        if (c < 0x0CB5) return false;  if (c <= 0x0CB9) return true;
+        if (c == 0x0CDE) return true;
+        if (c < 0x0CE0) return false;  if (c <= 0x0CE1) return true;
+        if (c < 0x0D05) return false;  if (c <= 0x0D0C) return true;
+        if (c < 0x0D0E) return false;  if (c <= 0x0D10) return true;
+        if (c < 0x0D12) return false;  if (c <= 0x0D28) return true;
+        if (c < 0x0D2A) return false;  if (c <= 0x0D39) return true;
+        if (c < 0x0D60) return false;  if (c <= 0x0D61) return true;
+        if (c < 0x0E01) return false;  if (c <= 0x0E2E) return true;
+        if (c == 0x0E30) return true;
+        if (c < 0x0E32) return false;  if (c <= 0x0E33) return true;
+        if (c < 0x0E40) return false;  if (c <= 0x0E45) return true;
+        if (c < 0x0E81) return false;  if (c <= 0x0E82) return true;
+        if (c == 0x0E84) return true;
+        if (c < 0x0E87) return false;  if (c <= 0x0E88) return true;
+        if (c == 0x0E8A) return true;
+        if (c == 0x0E8D) return true;
+        if (c < 0x0E94) return false;  if (c <= 0x0E97) return true;
+        if (c < 0x0E99) return false;  if (c <= 0x0E9F) return true;
+        if (c < 0x0EA1) return false;  if (c <= 0x0EA3) return true;
+        if (c == 0x0EA5) return true;
+        if (c == 0x0EA7) return true;
+        if (c < 0x0EAA) return false;  if (c <= 0x0EAB) return true;
+        if (c < 0x0EAD) return false;  if (c <= 0x0EAE) return true;
+        if (c == 0x0EB0) return true;
+        if (c < 0x0EB2) return false;  if (c <= 0x0EB3) return true;
+        if (c == 0x0EBD) return true;
+        if (c < 0x0EC0) return false;  if (c <= 0x0EC4) return true;
+        if (c < 0x0F40) return false;  if (c <= 0x0F47) return true;
+        if (c < 0x0F49) return false;  if (c <= 0x0F69) return true;
+        if (c < 0x10A0) return false;  if (c <= 0x10C5) return true;
+        if (c < 0x10D0) return false;  if (c <= 0x10F6) return true;
+        if (c == 0x1100) return true;
+        if (c < 0x1102) return false;  if (c <= 0x1103) return true;
+        if (c < 0x1105) return false;  if (c <= 0x1107) return true;
+        if (c == 0x1109) return true;
+        if (c < 0x110B) return false;  if (c <= 0x110C) return true;
+        if (c < 0x110E) return false;  if (c <= 0x1112) return true;
+        if (c == 0x113C) return true;
+        if (c == 0x113E) return true;
+        if (c == 0x1140) return true;
+        if (c == 0x114C) return true;
+        if (c == 0x114E) return true;
+        if (c == 0x1150) return true;
+        if (c < 0x1154) return false;  if (c <= 0x1155) return true;
+        if (c == 0x1159) return true;
+        if (c < 0x115F) return false;  if (c <= 0x1161) return true;
+        if (c == 0x1163) return true;
+        if (c == 0x1165) return true;
+        if (c == 0x1167) return true;
+        if (c == 0x1169) return true;
+        if (c < 0x116D) return false;  if (c <= 0x116E) return true;
+        if (c < 0x1172) return false;  if (c <= 0x1173) return true;
+        if (c == 0x1175) return true;
+        if (c == 0x119E) return true;
+        if (c == 0x11A8) return true;
+        if (c == 0x11AB) return true;
+        if (c < 0x11AE) return false;  if (c <= 0x11AF) return true;
+        if (c < 0x11B7) return false;  if (c <= 0x11B8) return true;
+        if (c == 0x11BA) return true;
+        if (c < 0x11BC) return false;  if (c <= 0x11C2) return true;
+        if (c == 0x11EB) return true;
+        if (c == 0x11F0) return true;
+        if (c == 0x11F9) return true;
+        if (c < 0x1E00) return false;  if (c <= 0x1E9B) return true;
+        if (c < 0x1EA0) return false;  if (c <= 0x1EF9) return true;
+        if (c < 0x1F00) return false;  if (c <= 0x1F15) return true;
+        if (c < 0x1F18) return false;  if (c <= 0x1F1D) return true;
+        if (c < 0x1F20) return false;  if (c <= 0x1F45) return true;
+        if (c < 0x1F48) return false;  if (c <= 0x1F4D) return true;
+        if (c < 0x1F50) return false;  if (c <= 0x1F57) return true;
+        if (c == 0x1F59) return true;
+        if (c == 0x1F5B) return true;
+        if (c == 0x1F5D) return true;
+        if (c < 0x1F5F) return false;  if (c <= 0x1F7D) return true;
+        if (c < 0x1F80) return false;  if (c <= 0x1FB4) return true;
+        if (c < 0x1FB6) return false;  if (c <= 0x1FBC) return true;
+        if (c == 0x1FBE) return true;
+        if (c < 0x1FC2) return false;  if (c <= 0x1FC4) return true;
+        if (c < 0x1FC6) return false;  if (c <= 0x1FCC) return true;
+        if (c < 0x1FD0) return false;  if (c <= 0x1FD3) return true;
+        if (c < 0x1FD6) return false;  if (c <= 0x1FDB) return true;
+        if (c < 0x1FE0) return false;  if (c <= 0x1FEC) return true;
+        if (c < 0x1FF2) return false;  if (c <= 0x1FF4) return true;
+        if (c < 0x1FF6) return false;  if (c <= 0x1FFC) return true;
+        if (c == 0x2126) return true;
+        if (c < 0x212A) return false;  if (c <= 0x212B) return true;
+        if (c == 0x212E) return true;
+        if (c < 0x2180) return false;  if (c <= 0x2182) return true;
+        if (c == 0x3007) return true;                          
+        if (c < 0x3021) return false;  if (c <= 0x3029) return true;
+        if (c < 0x3041) return false;  if (c <= 0x3094) return true;
+        if (c < 0x30A1) return false;  if (c <= 0x30FA) return true;
+        if (c < 0x3105) return false;  if (c <= 0x312C) return true;
+        if (c < 0x4E00) return false;  if (c <= 0x9FA5) return true;
+        if (c < 0xAC00) return false;  if (c <= 0xD7A3) return true;
+      
+        return false;
+        
+    }
+
+    /**
+     * Determine whether a specified character
+     * is a combining character according to production 87
+     * of the XML 1.0 specification.
+     *
+     * @param c <code>char</code> to check
+     * @return <code>boolean</code> true if it's a combining character,
+     *         false otherwise
+     */
+    static boolean isXMLCombiningChar(char c) {
+        // CombiningChar
+        if (c < 0x0300) return false;  if (c <= 0x0345) return true;
+        if (c < 0x0360) return false;  if (c <= 0x0361) return true;
+        if (c < 0x0483) return false;  if (c <= 0x0486) return true;
+        if (c < 0x0591) return false;  if (c <= 0x05A1) return true;
+                                       
+        if (c < 0x05A3) return false;  if (c <= 0x05B9) return true;
+        if (c < 0x05BB) return false;  if (c <= 0x05BD) return true;
+        if (c == 0x05BF) return true;
+        if (c < 0x05C1) return false;  if (c <= 0x05C2) return true;
+                                       
+        if (c == 0x05C4) return true;
+        if (c < 0x064B) return false;  if (c <= 0x0652) return true;
+        if (c == 0x0670) return true;
+        if (c < 0x06D6) return false;  if (c <= 0x06DC) return true;
+                                       
+        if (c < 0x06DD) return false;  if (c <= 0x06DF) return true;
+        if (c < 0x06E0) return false;  if (c <= 0x06E4) return true;
+        if (c < 0x06E7) return false;  if (c <= 0x06E8) return true;
+                                       
+        if (c < 0x06EA) return false;  if (c <= 0x06ED) return true;
+        if (c < 0x0901) return false;  if (c <= 0x0903) return true;
+        if (c == 0x093C) return true;
+        if (c < 0x093E) return false;  if (c <= 0x094C) return true;
+                                       
+        if (c == 0x094D) return true;
+        if (c < 0x0951) return false;  if (c <= 0x0954) return true;
+        if (c < 0x0962) return false;  if (c <= 0x0963) return true;
+        if (c < 0x0981) return false;  if (c <= 0x0983) return true;
+                                       
+        if (c == 0x09BC) return true;
+        if (c == 0x09BE) return true;
+        if (c == 0x09BF) return true;
+        if (c < 0x09C0) return false;  if (c <= 0x09C4) return true;
+        if (c < 0x09C7) return false;  if (c <= 0x09C8) return true;
+                                       
+        if (c < 0x09CB) return false;  if (c <= 0x09CD) return true;
+        if (c == 0x09D7) return true;
+        if (c < 0x09E2) return false;  if (c <= 0x09E3) return true;
+        if (c == 0x0A02) return true;
+        if (c == 0x0A3C) return true;
+                                       
+        if (c == 0x0A3E) return true;
+        if (c == 0x0A3F) return true;
+        if (c < 0x0A40) return false;  if (c <= 0x0A42) return true;
+        if (c < 0x0A47) return false;  if (c <= 0x0A48) return true;
+                                       
+        if (c < 0x0A4B) return false;  if (c <= 0x0A4D) return true;
+        if (c < 0x0A70) return false;  if (c <= 0x0A71) return true;
+        if (c < 0x0A81) return false;  if (c <= 0x0A83) return true;
+        if (c == 0x0ABC) return true;
+                                       
+        if (c < 0x0ABE) return false;  if (c <= 0x0AC5) return true;
+        if (c < 0x0AC7) return false;  if (c <= 0x0AC9) return true;
+        if (c < 0x0ACB) return false;  if (c <= 0x0ACD) return true;
+                                       
+        if (c < 0x0B01) return false;  if (c <= 0x0B03) return true;
+        if (c == 0x0B3C) return true;
+        if (c < 0x0B3E) return false;  if (c <= 0x0B43) return true;
+        if (c < 0x0B47) return false;  if (c <= 0x0B48) return true;
+                                       
+        if (c < 0x0B4B) return false;  if (c <= 0x0B4D) return true;
+        if (c < 0x0B56) return false;  if (c <= 0x0B57) return true;
+        if (c < 0x0B82) return false;  if (c <= 0x0B83) return true;
+                                       
+        if (c < 0x0BBE) return false;  if (c <= 0x0BC2) return true;
+        if (c < 0x0BC6) return false;  if (c <= 0x0BC8) return true;
+        if (c < 0x0BCA) return false;  if (c <= 0x0BCD) return true;
+        if (c == 0x0BD7) return true;
+                                       
+        if (c < 0x0C01) return false;  if (c <= 0x0C03) return true;
+        if (c < 0x0C3E) return false;  if (c <= 0x0C44) return true;
+        if (c < 0x0C46) return false;  if (c <= 0x0C48) return true;
+                                       
+        if (c < 0x0C4A) return false;  if (c <= 0x0C4D) return true;
+        if (c < 0x0C55) return false;  if (c <= 0x0C56) return true;
+        if (c < 0x0C82) return false;  if (c <= 0x0C83) return true;
+                                       
+        if (c < 0x0CBE) return false;  if (c <= 0x0CC4) return true;
+        if (c < 0x0CC6) return false;  if (c <= 0x0CC8) return true;
+        if (c < 0x0CCA) return false;  if (c <= 0x0CCD) return true;
+                                       
+        if (c < 0x0CD5) return false;  if (c <= 0x0CD6) return true;
+        if (c < 0x0D02) return false;  if (c <= 0x0D03) return true;
+        if (c < 0x0D3E) return false;  if (c <= 0x0D43) return true;
+                                       
+        if (c < 0x0D46) return false;  if (c <= 0x0D48) return true;
+        if (c < 0x0D4A) return false;  if (c <= 0x0D4D) return true;
+        if (c == 0x0D57) return true;
+        if (c == 0x0E31) return true;
+                                       
+        if (c < 0x0E34) return false;  if (c <= 0x0E3A) return true;
+        if (c < 0x0E47) return false;  if (c <= 0x0E4E) return true;
+        if (c == 0x0EB1) return true;
+        if (c < 0x0EB4) return false;  if (c <= 0x0EB9) return true;
+                                       
+        if (c < 0x0EBB) return false;  if (c <= 0x0EBC) return true;
+        if (c < 0x0EC8) return false;  if (c <= 0x0ECD) return true;
+        if (c < 0x0F18) return false;  if (c <= 0x0F19) return true;
+        if (c == 0x0F35) return true;
+                                       
+        if (c == 0x0F37) return true;
+        if (c == 0x0F39) return true;
+        if (c == 0x0F3E) return true;
+        if (c == 0x0F3F) return true;
+        if (c < 0x0F71) return false;  if (c <= 0x0F84) return true;
+                                       
+        if (c < 0x0F86) return false;  if (c <= 0x0F8B) return true;
+        if (c < 0x0F90) return false;  if (c <= 0x0F95) return true;
+        if (c == 0x0F97) return true;
+        if (c < 0x0F99) return false;  if (c <= 0x0FAD) return true;
+                                       
+        if (c < 0x0FB1) return false;  if (c <= 0x0FB7) return true;
+        if (c == 0x0FB9) return true;
+        if (c < 0x20D0) return false;  if (c <= 0x20DC) return true;
+        if (c == 0x20E1) return true;
+                                       
+        if (c < 0x302A) return false;  if (c <= 0x302F) return true;
+        if (c == 0x3099) return true;
+        if (c == 0x309A) return true; 
+        
+        return false;
+        
+    }
+    
+    /**
+     * Determine whether a specified 
+     * character is an extender according to production 88 of the XML 1.0
+     * specification.
+     *
+     * @param c <code>char</code> to check
+     * @return true if it's an extender, false otherwise
+     */
+    static boolean isXMLExtender(char c) {
+
+        if (c < 0x00B6) return false;  // quick short circuit
+
+        // Extenders                               
+        if (c == 0x00B7) return true;
+        if (c == 0x02D0) return true;
+        if (c == 0x02D1) return true;
+        if (c == 0x0387) return true;
+        if (c == 0x0640) return true;
+        if (c == 0x0E46) return true;
+        if (c == 0x0EC6) return true;
+        if (c == 0x3005) return true;
+                                       
+        if (c < 0x3031) return false;  if (c <= 0x3035) return true;
+        if (c < 0x309D) return false;  if (c <= 0x309E) return true;
+        if (c < 0x30FC) return false;  if (c <= 0x30FE) return true;
+        
+        return false;
+        
+    }
+      
+    /**
+     * Determine whether a specified Unicode character
+     * is a digit according to production 88 of the XML 1.0 specification.
+     *
+     * @param c <code>char</code> to check for XML digit compliance
+     * @return <code>boolean</code> true if it's a digit, false otherwise
+     */
+    static boolean isXMLDigit(char c) {
+      
+        if (c < 0x0030) return false;  if (c <= 0x0039) return true;
+        if (c < 0x0660) return false;  if (c <= 0x0669) return true;
+        if (c < 0x06F0) return false;  if (c <= 0x06F9) return true;
+        if (c < 0x0966) return false;  if (c <= 0x096F) return true;
+                                       
+        if (c < 0x09E6) return false;  if (c <= 0x09EF) return true;
+        if (c < 0x0A66) return false;  if (c <= 0x0A6F) return true;
+        if (c < 0x0AE6) return false;  if (c <= 0x0AEF) return true;
+                                       
+        if (c < 0x0B66) return false;  if (c <= 0x0B6F) return true;
+        if (c < 0x0BE7) return false;  if (c <= 0x0BEF) return true;
+        if (c < 0x0C66) return false;  if (c <= 0x0C6F) return true;
+                                       
+        if (c < 0x0CE6) return false;  if (c <= 0x0CEF) return true;
+        if (c < 0x0D66) return false;  if (c <= 0x0D6F) return true;
+        if (c < 0x0E50) return false;  if (c <= 0x0E59) return true;
+                                       
+        if (c < 0x0ED0) return false;  if (c <= 0x0ED9) return true;
+        if (c < 0x0F20) return false;  if (c <= 0x0F29) return true; 
+      
+        return false;
+    }  
+    
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/saxpath/base/XPathLexer.java b/libjaxen-java/src/java/main/org/jaxen/saxpath/base/XPathLexer.java
new file mode 100644
index 0000000..c410741
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/saxpath/base/XPathLexer.java
@@ -0,0 +1,941 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/saxpath/base/XPathLexer.java,v 1.17 2006/02/05 21:47:42 elharo Exp $
+ * $Revision: 1.17 $
+ * $Date: 2006/02/05 21:47:42 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Jaxen Project and was originally
+ * created by bob mcwhirter <bob at werken.com> and
+ * James Strachan <jstrachan at apache.org>.  For more information on the
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ *
+ * $Id: XPathLexer.java,v 1.17 2006/02/05 21:47:42 elharo Exp $
+ */
+
+
+
+
+package org.jaxen.saxpath.base;
+
+class XPathLexer
+{
+    private String xpath;
+    private int    currentPosition;
+    private int    endPosition;
+
+    private Token  previousToken;
+
+    XPathLexer(String xpath)
+    {
+        setXPath( xpath );
+    }
+
+    private void setXPath(String xpath)
+    {
+        this.xpath           = xpath;
+        this.currentPosition = 0;
+        this.endPosition     = xpath.length();
+    }
+
+    String getXPath()
+    {
+        return this.xpath;
+    }
+
+    Token nextToken()
+    {
+        Token token = null;
+
+        do
+        {
+            token = null;
+
+            switch ( LA(1) )
+            {
+                case '$':
+                {
+                    token = dollar();
+                    break;
+                }
+                    
+                case '"':
+                case '\'':
+                {
+                    token = literal();
+                    break;
+                }
+                    
+                case '/':
+                {
+                    token = slashes();
+                    break;
+                }
+
+                case ',':
+                {
+                    token = comma();
+                    break;
+                }
+                    
+                case '(':
+                {
+                    token = leftParen();
+                    break;
+                }
+                    
+                case ')':
+                {
+                    token = rightParen();
+                    break;
+                }
+                    
+                case '[':
+                {
+                    token = leftBracket();
+                    break;
+                }
+                    
+                case ']':
+                {
+                    token = rightBracket();
+                    break;
+                }
+                    
+                case '+':
+                {
+                    token = plus();
+                    break;
+                }
+                    
+                case '-':
+                {
+                    token = minus();
+                    break;
+                }
+                    
+                case '<':
+                case '>':
+                {
+                    token = relationalOperator();
+                    break;
+                }        
+
+                case '=':
+                {
+                    token = equals();
+                    break;
+                }
+                    
+                case '!':
+                {
+                    if ( LA(2) == '=' )
+                    {
+                        token = notEquals();
+                    }
+                    break;
+                }
+                    
+                case '|':
+                {
+                    token = pipe();
+                    break;
+                }
+                    
+                case '@':
+                {
+                    token = at();
+                    break;
+                }
+                    
+                case ':':
+                {
+                    if ( LA(2) == ':' )
+                    {
+                        token = doubleColon();
+                    }
+                    else
+                    {
+                        token = colon();
+                    }
+                    break;
+                }
+                    
+                case '*':
+                {
+                    token = star();
+                    break;
+                }
+                    
+                case '.':
+                {
+                    switch ( LA(2) )
+                    {
+                        case '0':
+                        case '1':
+                        case '2':
+                        case '3':
+                        case '4':
+                        case '5':
+                        case '6':
+                        case '7':
+                        case '8':
+                        case '9':
+                        {
+                            token = number();
+                            break;
+                        }
+                        default:
+                        {
+                            token = dots();
+                            break;
+                        }
+                    }
+                    break;
+                }
+
+                case '0':
+                case '1':
+                case '2':
+                case '3':
+                case '4':
+                case '5':
+                case '6':
+                case '7':
+                case '8':
+                case '9':
+                {
+                    token = number();
+                    break;
+                }
+
+                case ' ':
+                case '\t':
+                case '\n':
+                case '\r':
+                {
+                    token = whitespace();
+                    break;
+                }
+                    
+                default:
+                {
+                    if ( isIdentifierStartChar( LA(1) ) )
+                    {
+                        token = identifierOrOperatorName();
+                    }
+                }
+            }
+
+            if ( token == null )
+            {
+                if (!hasMoreChars())
+                {
+                    token = new Token( TokenTypes.EOF,
+                                   getXPath(),
+                                   currentPosition(),
+                                   endPosition() );
+            }
+                else
+                {
+                    token = new Token( TokenTypes.ERROR,
+                                   getXPath(),
+                                   currentPosition(),
+                                   endPosition() );
+                }
+            }
+
+        }
+        while ( token.getTokenType() == TokenTypes.SKIP );
+
+        setPreviousToken( token );
+        
+        return token;
+    }
+
+    private Token identifierOrOperatorName()
+    {
+        Token token = null;
+    
+        if ( previousToken != null )
+        {
+            // For some reason, section 3.7, Lexical structure,
+            // doesn't seem to feel like it needs to mention the
+            // SLASH, DOUBLE_SLASH, and COLON tokens for the test
+            // if an NCName is an operator or not.
+            //
+            // According to section 3.7, "/foo" should be considered
+            // as a SLASH following by an OperatorName being 'foo'.
+            // Which is just simply, clearly, wrong, in my mind.
+            //
+            //     -bob
+            
+            switch ( previousToken.getTokenType() )
+            {
+                case TokenTypes.AT:
+                case TokenTypes.DOUBLE_COLON:
+                case TokenTypes.LEFT_PAREN:
+                case TokenTypes.LEFT_BRACKET:
+                case TokenTypes.AND:
+                case TokenTypes.OR:
+                case TokenTypes.MOD:
+                case TokenTypes.DIV:
+                case TokenTypes.COLON:
+                case TokenTypes.SLASH:
+                case TokenTypes.DOUBLE_SLASH:
+                case TokenTypes.PIPE:
+                case TokenTypes.DOLLAR:
+                case TokenTypes.PLUS:
+                case TokenTypes.MINUS:
+                case TokenTypes.STAR:
+                case TokenTypes.COMMA:
+                case TokenTypes.LESS_THAN_SIGN:
+                case TokenTypes.GREATER_THAN_SIGN:
+                case TokenTypes.LESS_THAN_OR_EQUALS_SIGN:
+                case TokenTypes.GREATER_THAN_OR_EQUALS_SIGN:
+                case TokenTypes.EQUALS:
+                case TokenTypes.NOT_EQUALS:
+                {
+                    token = identifier();
+                    break;
+                }
+                default:
+                {
+                    token = operatorName();
+                    break;
+                }
+            }
+        }
+        else
+        {
+            token = identifier();
+        }
+    
+        return token;
+    }
+    
+    private Token identifier()
+    {
+        Token token = null;
+    
+        int start = currentPosition();
+    
+        while ( hasMoreChars() )
+        {
+            if ( isIdentifierChar( LA(1) ) )
+            {
+                consume();
+            }
+            else
+            {
+                break;
+            }
+        }
+    
+        token = new Token( TokenTypes.IDENTIFIER,
+                           getXPath(),
+                           start,
+                           currentPosition() );
+    
+        return token;
+    }
+    
+    private Token operatorName()
+    {
+        Token token = null;
+    
+        switch ( LA(1) )
+        {
+            case 'a':
+            {
+                token = and();
+                break;
+            }
+    
+            case 'o':
+            {
+                token = or();
+                break;
+            }
+    
+            case 'm':
+            {
+                token = mod();
+                break;
+            }
+    
+            case 'd':
+            {
+                token = div();
+                break;
+            }
+        }
+    
+        return token;
+    }
+    
+    private Token mod()
+    {
+        Token token = null;
+    
+        if ( ( LA(1) == 'm' )
+             &&
+             ( LA(2) == 'o' )
+             &&
+             ( LA(3) == 'd' )
+           )
+        {
+            token = new Token( TokenTypes.MOD,
+                               getXPath(),
+                               currentPosition(),
+                               currentPosition()+3 );
+    
+            consume();
+            consume();
+            consume();
+        }
+    
+        return token;
+    }
+    
+    private Token div()
+    {
+        Token token = null;
+    
+        if ( ( LA(1) == 'd' )
+             &&
+             ( LA(2) == 'i' )
+             &&
+             ( LA(3) == 'v' )
+            )
+        {
+            token = new Token( TokenTypes.DIV,
+                               getXPath(),
+                               currentPosition(),
+                               currentPosition()+3 );
+    
+            consume();
+            consume();
+            consume();
+        }
+    
+        return token;
+    }
+    
+    private Token and()
+    {
+        Token token = null;
+    
+        if ( ( LA(1) == 'a' )
+             &&
+             ( LA(2) == 'n' )
+             &&
+             ( LA(3) == 'd' )
+           )
+        {
+            token = new Token( TokenTypes.AND,
+                               getXPath(),
+                               currentPosition(),
+                               currentPosition()+3 );
+    
+            consume();
+            consume();
+            consume();
+        }
+    
+        return token;
+    }
+    
+    private Token or()
+    {
+        Token token = null;
+    
+        if ( ( LA(1) == 'o' )
+             &&
+             ( LA(2) == 'r' )
+           )
+        {
+            token = new Token( TokenTypes.OR,
+                               getXPath(),
+                               currentPosition(),
+                               currentPosition()+2 );
+    
+            consume();
+            consume();
+        }
+    
+        return token;
+    }
+    
+    private Token number()
+    {
+        int     start         = currentPosition();
+        boolean periodAllowed = true;
+    
+      loop:
+        while( true )
+        {
+            switch ( LA(1) )
+            {
+                case '.':
+                    if ( periodAllowed )
+                    {
+                        periodAllowed = false;
+                        consume();
+                    }
+                    else
+                    {
+                        break loop;
+                    }
+                    break;
+                case '0':
+                case '1':
+                case '2':
+                case '3':
+                case '4':
+                case '5':
+                case '6':
+                case '7':
+                case '8':
+                case '9':
+                    consume();
+                    break;
+                default:
+                    break loop;
+            }
+        }
+    
+        return new Token( TokenTypes.DOUBLE,
+                               getXPath(),
+                               start,
+                               currentPosition() );
+    }
+    
+    private Token whitespace()
+    {
+        consume();
+            
+      loop:
+        while( hasMoreChars() )
+        {
+            switch ( LA(1) )
+            {
+                case ' ':
+                case '\t':
+                case '\n':
+                case '\r':
+                {
+                    consume();
+                    break;
+                }
+                    
+                default:
+                {
+                    break loop;
+                }
+            }
+        }
+    
+        return new Token( TokenTypes.SKIP,
+                          getXPath(),
+                          0,
+                          0 );
+    }
+    
+    private Token comma()
+    {
+        Token token = new Token( TokenTypes.COMMA,
+                                 getXPath(),
+                                 currentPosition(),
+                                 currentPosition()+1 );
+    
+        consume();
+    
+        return token;
+    }
+    
+    private Token equals()
+    {
+        Token token = new Token( TokenTypes.EQUALS,
+                                 getXPath(),
+                                 currentPosition(),
+                                 currentPosition()+1 );
+    
+        consume();
+    
+        return token;
+    }
+    
+    private Token minus()
+    {
+        Token token = new Token( TokenTypes.MINUS,
+                                 getXPath(),
+                                 currentPosition(),
+                                 currentPosition()+1 );
+        consume();
+            
+        return token;
+    }
+    
+    private Token plus()
+    {
+        Token token = new Token( TokenTypes.PLUS,
+                                 getXPath(),
+                                 currentPosition(),
+                                 currentPosition()+1 );
+        consume();
+    
+        return token;
+    }
+    
+    private Token dollar()
+    {
+        Token token = new Token( TokenTypes.DOLLAR,
+                                 getXPath(),
+                                 currentPosition(),
+                                 currentPosition()+1 );
+        consume();
+    
+        return token;
+    }
+    
+    private Token pipe()
+    {
+        Token token = new Token( TokenTypes.PIPE,
+                                 getXPath(),
+                                 currentPosition(),
+                                 currentPosition()+1 );
+    
+        consume();
+    
+        return token;
+    }
+    
+    private Token at()
+    {
+        Token token = new Token( TokenTypes.AT,
+                                 getXPath(),
+                                 currentPosition(),
+                                 currentPosition()+1 );
+    
+        consume();
+    
+        return token;
+    }
+    
+    private Token colon()
+    {
+        Token token = new Token( TokenTypes.COLON,
+                                 getXPath(),
+                                 currentPosition(),
+                                 currentPosition()+1 );
+        consume();
+    
+        return token;
+    }
+    
+    private Token doubleColon()
+    {
+        Token token = new Token( TokenTypes.DOUBLE_COLON,
+                                 getXPath(),
+                                 currentPosition(),
+                                 currentPosition()+2 );
+    
+        consume();
+        consume();
+    
+        return token;
+    }
+    
+    private Token notEquals()
+    {
+        Token token = new Token( TokenTypes.NOT_EQUALS,
+                                 getXPath(),
+                                 currentPosition(),
+                                 currentPosition() + 2 );
+    
+        consume();
+        consume();
+    
+        return token;
+    }
+    
+    private Token relationalOperator()
+    {
+        Token token = null;
+    
+        switch ( LA(1) )
+        {
+            case '<':
+            {
+                if ( LA(2) == '=' )
+                {
+                    token = new Token( TokenTypes.LESS_THAN_OR_EQUALS_SIGN,
+                                       getXPath(),
+                                       currentPosition(),
+                                       currentPosition() + 2 );
+                    consume();
+                }
+                else
+                {
+                    token = new Token( TokenTypes.LESS_THAN_SIGN,
+                                       getXPath(),
+                                       currentPosition(),
+                                       currentPosition() + 1);
+                }
+    
+                consume();
+                break;
+            }
+            case '>':
+            {
+                if ( LA(2) == '=' )
+                {
+                    token = new Token( TokenTypes.GREATER_THAN_OR_EQUALS_SIGN,
+                                       getXPath(),
+                                       currentPosition(),
+                                       currentPosition() + 2 );
+                    consume();
+                }
+                else
+                {
+                    token = new Token( TokenTypes.GREATER_THAN_SIGN,
+                                       getXPath(),
+                                       currentPosition(),
+                                       currentPosition() + 1 );
+                }
+    
+                consume();
+                break;
+            }
+        }
+    
+        return token;
+                
+    }
+    
+    private Token star()
+    {
+        Token token = new Token( TokenTypes.STAR,
+                                 getXPath(),
+                                 currentPosition(),
+                                 currentPosition()+1 );
+    
+        consume();
+            
+        return token;
+    }
+    
+    private Token literal()
+    {
+        Token token = null;
+    
+        char match  = LA(1);
+    
+        consume();
+    
+        int start = currentPosition();
+            
+        while ( ( token == null )
+                &&
+                hasMoreChars() )
+        {
+            if ( LA(1) == match )
+            {
+                token = new Token( TokenTypes.LITERAL,
+                                   getXPath(),
+                                   start,
+                                   currentPosition() );
+            }
+            consume();
+        }
+    
+        return token;
+    }
+    
+    private Token dots()
+    {
+        Token token = null;
+    
+        switch ( LA(2) )
+        {
+            case '.':
+            {
+                token = new Token( TokenTypes.DOT_DOT,
+                                   getXPath(),
+                                   currentPosition(),
+                                   currentPosition()+2 ) ;
+                consume();
+                consume();
+                break;
+            }
+            default:
+            {
+                token = new Token( TokenTypes.DOT,
+                                   getXPath(),
+                                   currentPosition(),
+                                   currentPosition()+1 );
+                consume();
+                break;
+            }
+        }
+    
+        return token;
+    }
+    
+    private Token leftBracket()
+    {
+        Token token = new Token( TokenTypes.LEFT_BRACKET,
+                                 getXPath(),
+                                 currentPosition(),
+                                 currentPosition()+1 );
+    
+        consume();
+    
+        return token;
+    }
+    
+    private Token rightBracket()
+    {
+        Token token = new Token( TokenTypes.RIGHT_BRACKET,
+                                 getXPath(),
+                                 currentPosition(),
+                                 currentPosition()+1 );
+    
+        consume();
+    
+        return token;
+    }
+    
+    private Token leftParen()
+    {
+        Token token = new Token( TokenTypes.LEFT_PAREN,
+                                 getXPath(),
+                                 currentPosition(),
+                                 currentPosition()+1 );
+    
+        consume();
+    
+        return token;
+    }
+    
+    private Token rightParen()
+    {
+        Token token = new Token( TokenTypes.RIGHT_PAREN,
+                                 getXPath(),
+                                 currentPosition(),
+                                 currentPosition()+1 );
+    
+        consume();
+    
+        return token;
+    }
+    
+    private Token slashes()
+    {
+        Token token = null;
+    
+        switch ( LA(2) )
+        {
+            case '/':
+            {
+                token = new Token( TokenTypes.DOUBLE_SLASH,
+                                   getXPath(),
+                                   currentPosition(),
+                                   currentPosition()+2 );
+                consume();
+                consume();
+                break;
+            }
+            default:
+            {
+                token = new Token( TokenTypes.SLASH,
+                                   getXPath(),
+                                   currentPosition(),
+                                   currentPosition()+1 );
+                consume();
+            }
+        }
+    
+        return token;
+    }
+    
+    private char LA(int i) 
+    {
+        if ( currentPosition + ( i - 1 ) >= endPosition() )
+        {
+            return (char) -1;
+        }
+    
+        return getXPath().charAt( currentPosition() + (i - 1) );
+    }
+    
+    private void consume()
+    {
+        ++this.currentPosition;
+    }
+    
+    private int currentPosition()
+    {
+        return this.currentPosition;
+    }
+    
+    private int endPosition()
+    {
+        return this.endPosition;
+    }
+    
+    private void setPreviousToken(Token previousToken)
+    {
+        this.previousToken = previousToken;
+    }
+    
+    private boolean hasMoreChars()
+    {
+        return currentPosition() < endPosition();
+    }
+    
+    private boolean isIdentifierChar(char c)
+    {
+        return Verifier.isXMLNCNameCharacter( c );
+    }
+    
+    private boolean isIdentifierStartChar(char c)
+    {
+        return Verifier.isXMLNCNameStartCharacter( c );
+    }
+
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/saxpath/base/XPathReader.java b/libjaxen-java/src/java/main/org/jaxen/saxpath/base/XPathReader.java
new file mode 100644
index 0000000..7d44331
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/saxpath/base/XPathReader.java
@@ -0,0 +1,1100 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/saxpath/base/XPathReader.java,v 1.32 2006/04/07 23:47:37 elharo Exp $
+ * $Revision: 1.32 $
+ * $Date: 2006/04/07 23:47:37 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Jaxen Project and was originally
+ * created by bob mcwhirter <bob at werken.com> and
+ * James Strachan <jstrachan at apache.org>.  For more information on the
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ *
+ * $Id: XPathReader.java,v 1.32 2006/04/07 23:47:37 elharo Exp $
+ */
+
+
+package org.jaxen.saxpath.base;
+
+import java.util.ArrayList;
+
+import org.jaxen.saxpath.Axis;
+import org.jaxen.saxpath.Operator;
+import org.jaxen.saxpath.SAXPathException;
+import org.jaxen.saxpath.XPathHandler;
+import org.jaxen.saxpath.XPathSyntaxException;
+import org.jaxen.saxpath.helpers.DefaultXPathHandler;
+
+/** Implementation of SAXPath's <code>XPathReader</code> which
+ *  generates callbacks to an <code>XPathHandler</code>.
+ *
+ *  @author bob mcwhirter (bob at werken.com)
+ */
+public class XPathReader implements org.jaxen.saxpath.XPathReader
+{
+    private ArrayList  tokens;
+    private XPathLexer lexer;
+
+    private XPathHandler handler;
+    
+    private static XPathHandler defaultHandler = new DefaultXPathHandler();
+
+    /**
+     * Create a new <code>XPathReader</code> with a do-nothing
+     * <code>XPathHandler</code>.
+     */
+    public XPathReader()
+    {
+        setXPathHandler( defaultHandler );
+    }
+
+    public void setXPathHandler(XPathHandler handler)
+    {
+        this.handler = handler;
+    }
+
+    public XPathHandler getXPathHandler()
+    {
+        return this.handler;
+    }
+
+    public void parse(String xpath) throws SAXPathException
+    {
+        setUpParse( xpath );
+
+        getXPathHandler().startXPath();
+
+        expr();
+
+        getXPathHandler().endXPath();
+
+        if ( LA(1) != TokenTypes.EOF )
+        {
+            XPathSyntaxException ex = createSyntaxException( "Unexpected '" + LT(1).getTokenText() + "'" );
+            throw ex;
+        }
+
+        lexer  = null;
+        tokens = null;
+    }
+
+    void setUpParse(String xpath)
+    {
+        this.tokens = new ArrayList();
+        this.lexer = new XPathLexer( xpath );
+    }
+
+    private void pathExpr() throws SAXPathException
+    {
+        getXPathHandler().startPathExpr();
+
+        switch ( LA(1) )
+        {
+            case TokenTypes.DOUBLE:
+            case TokenTypes.LITERAL:
+            {
+                filterExpr();
+
+                if ( LA(1) == TokenTypes.SLASH || LA(1) == TokenTypes.DOUBLE_SLASH )
+                {
+                    XPathSyntaxException ex = createSyntaxException("Node-set expected");
+                    throw ex;
+                }
+
+                break;
+            }                
+            case TokenTypes.LEFT_PAREN:
+            case TokenTypes.DOLLAR:
+            {
+                filterExpr();
+                    
+                if ( LA(1) == TokenTypes.SLASH || LA(1) == TokenTypes.DOUBLE_SLASH)
+                {
+                    locationPath( false );
+                }
+                break;
+            }
+            case TokenTypes.IDENTIFIER:
+            {
+
+                if ( ( LA(2) == TokenTypes.LEFT_PAREN
+                     &&
+                       ! isNodeTypeName( LT(1) ) )
+                     ||
+                    ( LA(2) == TokenTypes.COLON
+                      &&
+                      LA(4) == TokenTypes.LEFT_PAREN) ) 
+                {
+                    filterExpr();
+                    
+                    if ( LA(1) == TokenTypes.SLASH || LA(1) == TokenTypes.DOUBLE_SLASH)
+                    {
+                        locationPath( false );
+                    }
+                }
+                else
+                {
+                    locationPath( false );
+                }
+                break;
+            }
+            case TokenTypes.DOT:
+            case TokenTypes.DOT_DOT:
+            case TokenTypes.STAR:
+            case TokenTypes.AT:
+            {
+                locationPath( false );
+                break;
+            }
+            case TokenTypes.SLASH:
+            case TokenTypes.DOUBLE_SLASH:
+            {
+                locationPath( true );
+                break;
+            }
+            default:
+            {
+                XPathSyntaxException ex = createSyntaxException( "Unexpected '" + LT(1).getTokenText() + "'" );
+                throw ex;
+            }
+        }
+
+        getXPathHandler().endPathExpr();
+    }
+
+    private void literal() throws SAXPathException
+    {
+        Token token = match( TokenTypes.LITERAL );
+
+        getXPathHandler().literal( token.getTokenText() );
+    }
+
+    private void functionCall() throws SAXPathException
+    {
+        String prefix       = null;
+        String functionName = null;
+
+        if ( LA(2) == TokenTypes.COLON )
+        {
+            prefix = match( TokenTypes.IDENTIFIER ).getTokenText();
+            match( TokenTypes.COLON );
+        }
+        else
+        {
+            prefix = "";
+        }
+
+        functionName = match( TokenTypes.IDENTIFIER ).getTokenText();
+
+        getXPathHandler().startFunction( prefix,
+                                         functionName );
+
+        match ( TokenTypes.LEFT_PAREN );
+
+        arguments();
+
+        match ( TokenTypes.RIGHT_PAREN );
+
+        getXPathHandler().endFunction();
+    }
+
+    private void arguments() throws SAXPathException
+    {
+        while ( LA(1) != TokenTypes.RIGHT_PAREN )
+        {
+            expr();
+
+            if ( LA(1) == TokenTypes.COMMA )
+            {
+                match( TokenTypes.COMMA );
+            }
+            else
+            {
+                break;
+            }
+        }
+    }
+
+    private void filterExpr() throws SAXPathException
+    {
+
+        getXPathHandler().startFilterExpr();
+
+        switch ( LA(1) )
+        {
+            case TokenTypes.DOUBLE:
+            {
+                Token token = match( TokenTypes.DOUBLE );
+                
+                getXPathHandler().number( Double.parseDouble( token.getTokenText() ) );
+                break;
+            }
+            case TokenTypes.LITERAL:
+            {
+                literal();
+                break;
+            }
+            case TokenTypes.LEFT_PAREN:
+            {
+                match( TokenTypes.LEFT_PAREN );
+                expr();
+                match( TokenTypes.RIGHT_PAREN );
+                break;
+            }
+            case TokenTypes.IDENTIFIER:
+            {
+                functionCall();
+                break;
+            }
+            case TokenTypes.DOLLAR:
+            {
+                variableReference();
+                break;
+            }
+        }
+
+        predicates();
+
+        getXPathHandler().endFilterExpr();
+    }
+
+    private void variableReference() throws SAXPathException
+    {
+        match( TokenTypes.DOLLAR );
+
+        String prefix       = null;
+        String variableName = null;
+
+        if ( LA(2) == TokenTypes.COLON )
+        {
+            prefix = match( TokenTypes.IDENTIFIER ).getTokenText();
+            match( TokenTypes.COLON );
+        }
+        else
+        {
+            prefix = "";
+        }
+
+        variableName = match( TokenTypes.IDENTIFIER ).getTokenText();
+
+        getXPathHandler().variableReference( prefix,
+                                             variableName );
+    }
+
+    void locationPath(boolean isAbsolute) throws SAXPathException
+    {
+        switch ( LA(1) )
+        {
+            case TokenTypes.SLASH:
+            case TokenTypes.DOUBLE_SLASH:
+            {
+                if ( isAbsolute )
+                {
+                    absoluteLocationPath();
+                }
+                else
+                {
+                    relativeLocationPath();
+                }
+                break;
+            }
+            case TokenTypes.AT:
+            case TokenTypes.IDENTIFIER:
+            case TokenTypes.DOT:
+            case TokenTypes.DOT_DOT:
+            case TokenTypes.STAR:
+            {
+                relativeLocationPath();
+                break;
+            }
+            default:
+            {
+                XPathSyntaxException ex = createSyntaxException( "Unexpected '" + LT(1).getTokenText() + "'" );
+                throw ex;
+            }
+        }
+    }
+
+    private void absoluteLocationPath() throws SAXPathException
+    {
+        getXPathHandler().startAbsoluteLocationPath();
+
+        switch ( LA(1) )
+        {
+            case TokenTypes.SLASH:
+            {
+                match( TokenTypes.SLASH );
+
+                switch ( LA(1) )
+                {
+
+                    case TokenTypes.DOT:
+                    case TokenTypes.DOT_DOT:
+                    case TokenTypes.AT:
+                    case TokenTypes.IDENTIFIER:
+                    case TokenTypes.STAR:
+                    {
+                        steps();
+                        break;
+                    }
+                }
+                break;
+            }
+            case TokenTypes.DOUBLE_SLASH:
+            {
+                getXPathHandler().startAllNodeStep( Axis.DESCENDANT_OR_SELF );
+                getXPathHandler().endAllNodeStep();
+
+                match( TokenTypes.DOUBLE_SLASH );
+                switch ( LA(1) )
+                {
+                    case TokenTypes.DOT:
+                    case TokenTypes.DOT_DOT:
+                    case TokenTypes.AT:
+                    case TokenTypes.IDENTIFIER:
+                    case TokenTypes.STAR:
+                    {
+                        steps();
+                        break;
+                    }
+                    default:
+                        XPathSyntaxException ex = this.createSyntaxException("Location path cannot end with //");
+                        throw ex;
+                }
+                break;
+            }
+        }
+        
+        getXPathHandler().endAbsoluteLocationPath();
+    }
+
+    private void relativeLocationPath() throws SAXPathException
+    {
+        getXPathHandler().startRelativeLocationPath();
+
+        switch ( LA(1) )
+        {
+            case TokenTypes.SLASH:
+            {
+                match( TokenTypes.SLASH );
+                break;
+            }
+            case TokenTypes.DOUBLE_SLASH:
+            {
+                getXPathHandler().startAllNodeStep( Axis.DESCENDANT_OR_SELF );
+                getXPathHandler().endAllNodeStep();
+
+                match( TokenTypes.DOUBLE_SLASH );
+
+                break;
+            }
+        }
+
+        steps();
+
+        getXPathHandler().endRelativeLocationPath();
+    }
+
+    private void steps() throws SAXPathException
+    {
+        switch ( LA(1) )
+        {
+
+            case TokenTypes.DOT:
+            case TokenTypes.DOT_DOT:
+            case TokenTypes.AT:
+            case TokenTypes.IDENTIFIER:
+            case TokenTypes.STAR:
+            {
+                step();
+                break;
+            }
+            case TokenTypes.EOF:
+            {
+                return;
+            }
+            default:
+            {
+                XPathSyntaxException ex = createSyntaxException( "Expected one of '.', '..', '@', '*', <QName>" );
+                throw ex;
+            }
+        }
+
+        do
+        {
+            if ( ( LA(1) == TokenTypes.SLASH)
+                 ||
+                 ( LA(1) == TokenTypes.DOUBLE_SLASH ) )
+            {
+                switch ( LA(1) )
+                {
+                    case TokenTypes.SLASH:
+                    {
+                        match( TokenTypes.SLASH );
+                        break;
+                    }
+                    case TokenTypes.DOUBLE_SLASH:
+                    {
+                        getXPathHandler().startAllNodeStep( Axis.DESCENDANT_OR_SELF );
+                        getXPathHandler().endAllNodeStep();
+
+                        match( TokenTypes.DOUBLE_SLASH );
+                        break;
+                    }
+                }
+            }
+            else
+            {
+                return;
+            }
+            
+            switch ( LA(1) )
+            {
+                case TokenTypes.DOT:
+                case TokenTypes.DOT_DOT:
+                case TokenTypes.AT:
+                case TokenTypes.IDENTIFIER:
+                case TokenTypes.STAR:
+                {
+                    step();
+                    break;
+                }
+                default:
+                {
+                    XPathSyntaxException ex = createSyntaxException( "Expected one of '.', '..', '@', '*', <QName>" );
+                    throw ex;
+                }
+            }
+
+        } while ( true );
+    }
+
+    void step() throws SAXPathException
+    {
+        int axis = 0;
+
+        switch ( LA(1) )
+        {
+            case TokenTypes.DOT:
+            case TokenTypes.DOT_DOT:
+            {
+                abbrStep();
+                return;
+            }
+            case TokenTypes.AT:
+            {
+                axis = axisSpecifier();
+                break;
+            }
+            case TokenTypes.IDENTIFIER:
+            {
+                if ( LA(2) == TokenTypes.DOUBLE_COLON )
+                {
+                    axis = axisSpecifier();
+                }
+                else
+                {
+                    axis = Axis.CHILD;
+                }
+                break;
+            }
+            case TokenTypes.STAR:
+            {
+                axis = Axis.CHILD;
+                break;
+            }
+        }
+
+        nodeTest( axis );
+    }
+
+    private int axisSpecifier() throws SAXPathException
+    {
+        int axis = 0;
+
+        switch ( LA(1) )
+        {
+            case TokenTypes.AT:
+            {
+                match( TokenTypes.AT );
+                axis = Axis.ATTRIBUTE;
+                break;
+            }
+            case TokenTypes.IDENTIFIER:
+            {
+                Token token = LT( 1 );
+
+                axis = Axis.lookup( token.getTokenText() );
+
+                if ( axis == Axis.INVALID_AXIS )
+                {
+                    throwInvalidAxis( token.getTokenText() );
+                }
+
+                match( TokenTypes.IDENTIFIER );
+                match( TokenTypes.DOUBLE_COLON );
+
+                break;
+            }
+        }
+
+        return axis;
+    }
+
+    private void nodeTest(int axis) throws SAXPathException
+    {
+        switch ( LA(1) )
+        {
+            case TokenTypes.IDENTIFIER:
+            {
+                switch ( LA(2) )
+                {
+                    case TokenTypes.LEFT_PAREN:
+                    {
+                        nodeTypeTest( axis );
+                        break;
+                    }
+                    default:
+                    {
+                        nameTest( axis );
+                        break;
+                    }
+                }
+                break;
+            }
+            case TokenTypes.STAR:
+            {
+                nameTest( axis );
+                break;
+            }
+            default:
+                XPathSyntaxException ex = createSyntaxException("Expected <QName> or *");
+                throw ex;
+        }
+    }
+
+    private void nodeTypeTest(int axis) throws SAXPathException
+    {
+        Token  nodeTypeToken = match( TokenTypes.IDENTIFIER );
+        String nodeType      = nodeTypeToken.getTokenText();
+
+        match( TokenTypes.LEFT_PAREN );
+
+        if ( "processing-instruction".equals( nodeType ) )
+        {
+            String piName = "";
+
+            if ( LA(1) == TokenTypes.LITERAL )
+            {
+                piName = match( TokenTypes.LITERAL ).getTokenText();
+            }
+
+            match( TokenTypes.RIGHT_PAREN );
+
+            getXPathHandler().startProcessingInstructionNodeStep( axis,
+                                                                  piName );
+
+            predicates();
+
+            getXPathHandler().endProcessingInstructionNodeStep();
+        }
+        else if ( "node".equals( nodeType ) )
+        {
+            match( TokenTypes.RIGHT_PAREN );
+
+            getXPathHandler().startAllNodeStep( axis );
+
+            predicates();
+
+            getXPathHandler().endAllNodeStep();
+        }
+        else if ( "text".equals( nodeType ) )
+        {
+            match( TokenTypes.RIGHT_PAREN );
+
+            getXPathHandler().startTextNodeStep( axis );
+
+            predicates();
+
+            getXPathHandler().endTextNodeStep();
+        }
+        else if ( "comment".equals( nodeType ) )
+        {
+            match( TokenTypes.RIGHT_PAREN );
+
+            getXPathHandler().startCommentNodeStep( axis );
+
+            predicates();
+
+            getXPathHandler().endCommentNodeStep();
+        }
+        else
+        {
+            XPathSyntaxException ex = createSyntaxException( "Expected node-type" );
+            throw ex;
+        }
+    }
+
+    private void nameTest(int axis) throws SAXPathException
+    {
+        String prefix    = null;
+        String localName = null;
+
+        switch ( LA(2) )
+        {
+            case TokenTypes.COLON:
+            {
+                switch ( LA(1) )
+                {
+                    case TokenTypes.IDENTIFIER:
+                    {
+                        prefix = match( TokenTypes.IDENTIFIER ).getTokenText();
+                        match( TokenTypes.COLON );
+                        break;
+                    }
+                }
+                break;
+            }
+        }
+        
+        switch ( LA(1) )
+        {
+            case TokenTypes.IDENTIFIER:
+            {
+                localName = match( TokenTypes.IDENTIFIER ).getTokenText();
+                break;
+            }
+            case TokenTypes.STAR:
+            {
+                match( TokenTypes.STAR );
+                localName = "*";
+                break;
+            }
+        }
+
+        if ( prefix == null )
+        {
+            prefix = "";
+        }
+        
+        getXPathHandler().startNameStep( axis,
+                                         prefix,
+                                         localName );
+
+        predicates();
+
+        getXPathHandler().endNameStep();
+    }
+
+    private void abbrStep() throws SAXPathException
+    {
+        switch ( LA(1) )
+        {
+            case TokenTypes.DOT:
+            {
+                match( TokenTypes.DOT );
+                getXPathHandler().startAllNodeStep( Axis.SELF );
+                predicates();
+                getXPathHandler().endAllNodeStep();
+                break;
+            }
+            case TokenTypes.DOT_DOT:
+            {
+                match( TokenTypes.DOT_DOT );
+                getXPathHandler().startAllNodeStep( Axis.PARENT );
+                predicates();
+                getXPathHandler().endAllNodeStep();
+                break;
+            }
+        }
+    }
+
+    private void predicates() throws SAXPathException
+    {
+        while (true )
+        {
+            if ( LA(1) == TokenTypes.LEFT_BRACKET )
+            {
+                predicate();
+            }
+            else
+            {
+                break;
+            }
+        }
+    }
+    
+    void predicate() throws SAXPathException
+    {
+        getXPathHandler().startPredicate();
+        
+        match( TokenTypes.LEFT_BRACKET );
+        
+        predicateExpr();
+
+        match( TokenTypes.RIGHT_BRACKET );
+
+        getXPathHandler().endPredicate();
+    }
+
+    private void predicateExpr() throws SAXPathException
+    {
+        expr();
+    }
+
+    private void expr() throws SAXPathException
+    {
+        orExpr();
+    }
+
+    private void orExpr() throws SAXPathException
+    {
+        getXPathHandler().startOrExpr();
+        
+        andExpr();
+
+        boolean create = false;
+
+        switch ( LA(1) )
+        {
+            case TokenTypes.OR:
+            {
+                create = true;
+                match( TokenTypes.OR );
+                orExpr();
+                break;
+            }
+        }
+
+        getXPathHandler().endOrExpr( create );
+    }
+
+    private void andExpr() throws SAXPathException
+    {
+        getXPathHandler().startAndExpr();
+
+        equalityExpr();
+
+        boolean create = false;
+
+        switch ( LA(1) )
+        {
+            case TokenTypes.AND:
+            {
+                create = true;
+                match( TokenTypes.AND );
+                andExpr();
+                break;
+            }
+        }
+
+        getXPathHandler().endAndExpr( create );
+    }
+
+    private void equalityExpr() throws SAXPathException
+    {
+        relationalExpr();
+
+        int la = LA(1);
+        while (la == TokenTypes.EQUALS || la == TokenTypes.NOT_EQUALS)
+        {
+            switch ( la )
+            {
+                case TokenTypes.EQUALS:
+                {
+                    match( TokenTypes.EQUALS );
+                    getXPathHandler().startEqualityExpr();
+                    relationalExpr();
+                    getXPathHandler().endEqualityExpr( Operator.EQUALS );
+                    break;
+                }
+                case TokenTypes.NOT_EQUALS:
+                {
+                    match( TokenTypes.NOT_EQUALS );
+                    getXPathHandler().startEqualityExpr();
+                    relationalExpr();
+                    getXPathHandler().endEqualityExpr( Operator.NOT_EQUALS );
+                    break;
+                }
+            }
+            la = LA(1);
+        }
+    }
+    
+    private void relationalExpr() throws SAXPathException
+    {
+
+        additiveExpr();
+
+        int la = LA(1);
+        // Very important: TokenTypes.LESS_THAN != Operator.LESS_THAN
+        //                 TokenTypes.GREATER_THAN != Operator.GREATER_THAN
+        //                 TokenTypes.GREATER_THAN_EQUALS != Operator.GREATER_THAN_EQUALS
+        //                 TokenTypes.LESS_THAN_EQUALS != Operator.LESS_THAN_EQUALS
+        while (la == TokenTypes.LESS_THAN_SIGN 
+            || la == TokenTypes.GREATER_THAN_SIGN 
+            || la == TokenTypes.LESS_THAN_OR_EQUALS_SIGN 
+            || la == TokenTypes.GREATER_THAN_OR_EQUALS_SIGN ) {
+            switch ( la )
+            {
+                case TokenTypes.LESS_THAN_SIGN:
+                {
+                    match( TokenTypes.LESS_THAN_SIGN );
+                    getXPathHandler().startRelationalExpr();
+                    additiveExpr();
+                    getXPathHandler().endRelationalExpr( Operator.LESS_THAN );
+                    break;
+                }
+                case TokenTypes.GREATER_THAN_SIGN:
+                {
+                    match( TokenTypes.GREATER_THAN_SIGN );
+                    getXPathHandler().startRelationalExpr();
+                    additiveExpr();
+                    getXPathHandler().endRelationalExpr( Operator.GREATER_THAN );
+                    break;
+                }
+                case TokenTypes.GREATER_THAN_OR_EQUALS_SIGN:
+                {
+                    match( TokenTypes.GREATER_THAN_OR_EQUALS_SIGN );
+                    getXPathHandler().startRelationalExpr();
+                    additiveExpr();
+                    getXPathHandler().endRelationalExpr( Operator.GREATER_THAN_EQUALS );
+                    break;
+                }
+                case TokenTypes.LESS_THAN_OR_EQUALS_SIGN:
+                {
+                    match( TokenTypes.LESS_THAN_OR_EQUALS_SIGN );
+                    getXPathHandler().startRelationalExpr();
+                    additiveExpr();
+                    getXPathHandler().endRelationalExpr( Operator.LESS_THAN_EQUALS );
+                    break;
+                }
+            }
+            la = LA(1);
+        }
+    } 
+
+    
+    private void additiveExpr() throws SAXPathException
+    {
+        multiplicativeExpr();
+
+        int la = LA(1);
+        while (la == TokenTypes.PLUS || la == TokenTypes.MINUS)
+        {
+            switch ( la )
+            {
+                case TokenTypes.PLUS:
+                {
+                    match( TokenTypes.PLUS );
+                    getXPathHandler().startAdditiveExpr();
+                    multiplicativeExpr();
+                    getXPathHandler().endAdditiveExpr( Operator.ADD );
+                    break;
+                }
+                case TokenTypes.MINUS:
+                {
+                    match( TokenTypes.MINUS );
+                    getXPathHandler().startAdditiveExpr();
+                    multiplicativeExpr();
+                    getXPathHandler().endAdditiveExpr( Operator.SUBTRACT );
+                    break;
+                }
+            }
+            la = LA(1);
+        }
+    }
+
+    private void multiplicativeExpr() throws SAXPathException
+    {
+        unaryExpr();
+
+        int la = LA(1);
+        while (la == TokenTypes.STAR || la == TokenTypes.DIV || la == TokenTypes.MOD)
+        {
+            switch ( la )
+            {
+                case TokenTypes.STAR:
+                {
+                    match( TokenTypes.STAR );
+                    getXPathHandler().startMultiplicativeExpr();
+                    unaryExpr();
+                    getXPathHandler().endMultiplicativeExpr( Operator.MULTIPLY );
+                    break;
+                }
+                case TokenTypes.DIV:
+                {
+                    match( TokenTypes.DIV );
+                    getXPathHandler().startMultiplicativeExpr();
+                    unaryExpr();
+                    getXPathHandler().endMultiplicativeExpr( Operator.DIV );
+                    break;
+                }
+                case TokenTypes.MOD:
+                {
+                    match( TokenTypes.MOD );
+                    getXPathHandler().startMultiplicativeExpr();
+                    unaryExpr();
+                    getXPathHandler().endMultiplicativeExpr( Operator.MOD );
+                    break;
+                }
+            }
+            la = LA(1);
+        }
+
+    }
+
+    private void unaryExpr() throws SAXPathException
+    {
+        switch ( LA(1) )
+        {
+            case TokenTypes.MINUS:
+            {
+                getXPathHandler().startUnaryExpr();
+                match( TokenTypes.MINUS );
+                unaryExpr();
+                getXPathHandler().endUnaryExpr( Operator.NEGATIVE );
+                break;
+            }
+            default:
+            {
+                unionExpr();
+                break;
+            }
+        }
+
+        
+    }
+
+    private void unionExpr() throws SAXPathException
+    {
+        getXPathHandler().startUnionExpr();
+
+        pathExpr();
+
+        boolean create = false;
+
+        switch ( LA(1) )
+        {
+            case TokenTypes.PIPE:
+            {
+                match( TokenTypes.PIPE );
+                create = true;
+                expr();
+                break;
+            }
+        }
+
+        getXPathHandler().endUnionExpr( create );
+    }
+
+    private Token match(int tokenType) throws XPathSyntaxException
+    {
+        LT(1);
+
+        Token token = (Token) tokens.get( 0 );
+
+        if ( token.getTokenType() == tokenType )
+        {
+            tokens.remove(0);
+            return token;
+        }
+
+        
+        XPathSyntaxException ex = createSyntaxException( "Expected: " + TokenTypes.getTokenText( tokenType ) );
+        throw ex;
+    }
+
+    private int LA(int position)
+    {
+        return LT(position).getTokenType();
+    }
+
+    
+    // XXX This method's a HotSpot; could we improve it?
+    private Token LT(int position)
+    {
+        if ( tokens.size() <= ( position - 1 ) )
+        {
+            for ( int i = 0 ; i < position ; ++i )
+            {
+                tokens.add( lexer.nextToken() );
+            }
+        }
+
+        return (Token) tokens.get( position - 1 );
+    }
+
+    private boolean isNodeTypeName(Token name)
+    {
+        String text = name.getTokenText();
+
+        if ( "node".equals( text )
+             ||
+             "comment".equals( text )
+             ||
+             "text".equals( text )
+             ||
+             "processing-instruction".equals( text ) )
+        {
+            return true;
+        }
+
+        return false;
+    }
+
+    private XPathSyntaxException createSyntaxException(String message)
+    {
+        String xpath    = this.lexer.getXPath();
+        int    position = LT(1).getTokenBegin();
+
+        return new XPathSyntaxException( xpath,
+                                         position,
+                                         message );
+    }
+
+    private void throwInvalidAxis(String invalidAxis) throws SAXPathException
+    {
+        String xpath    = this.lexer.getXPath();
+        int    position = LT(1).getTokenBegin();
+
+        String message  = "Expected valid axis name instead of [" + invalidAxis + "]";
+
+        throw new XPathSyntaxException( xpath,
+                                        position,
+                                        message );
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/saxpath/base/package.html b/libjaxen-java/src/java/main/org/jaxen/saxpath/base/package.html
new file mode 100644
index 0000000..abf547b
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/saxpath/base/package.html
@@ -0,0 +1,14 @@
+<html>
+	<head>
+		<title>
+			com.jaxen.saxpath.*
+		</title>
+	</head>
+
+	<body>
+		<p>
+			<a href="http://jaxen.org">jaxen</a>
+			implementation of the SAXPath functionality.
+		</p>
+	</body>
+</html>
diff --git a/libjaxen-java/src/java/main/org/jaxen/saxpath/helpers/DefaultXPathHandler.java b/libjaxen-java/src/java/main/org/jaxen/saxpath/helpers/DefaultXPathHandler.java
new file mode 100644
index 0000000..6431da0
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/saxpath/helpers/DefaultXPathHandler.java
@@ -0,0 +1,254 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/saxpath/helpers/DefaultXPathHandler.java,v 1.7 2006/02/05 21:47:42 elharo Exp $
+ * $Revision: 1.7 $
+ * $Date: 2006/02/05 21:47:42 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Jaxen Project and was originally
+ * created by bob mcwhirter <bob at werken.com> and
+ * James Strachan <jstrachan at apache.org>.  For more information on the
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ *
+ * $Id: DefaultXPathHandler.java,v 1.7 2006/02/05 21:47:42 elharo Exp $
+ */
+
+
+
+
+package org.jaxen.saxpath.helpers;
+
+import org.jaxen.saxpath.SAXPathException;
+import org.jaxen.saxpath.XPathHandler;
+
+/**
+
+   Default base class for SAXPath event handlers. 
+
+   This class is available as a convenience base class for SAXPath
+   applications: it provides a default do-nothing implementation 
+   for all of the callbacks in the core SAXPath handler class, {@link
+   org.jaxen.saxpath.XPathHandler}.
+
+   Application writers can extend this class when they need to
+   implement only part of the <code>XPathHandler</code>
+   interface. Parser writers can instantiate
+   this class to provide default handlers when the application has not
+   supplied its own. */
+
+public class DefaultXPathHandler implements XPathHandler
+{
+
+    public void startXPath() throws SAXPathException
+    {
+    }
+
+    public void endXPath() throws SAXPathException
+    {
+    }
+
+    public void startPathExpr() throws SAXPathException
+    {
+    }
+
+    public void endPathExpr() throws SAXPathException
+    {
+    }
+
+    public void startAbsoluteLocationPath() throws SAXPathException
+    {
+    }
+
+    public void endAbsoluteLocationPath() throws SAXPathException
+    {
+    }
+
+    public void startRelativeLocationPath() throws SAXPathException
+    {
+    }
+
+    public void endRelativeLocationPath() throws SAXPathException
+    {
+    }
+
+    public void startNameStep(int axis,
+                              String prefix,
+                              String localName) throws SAXPathException
+    {
+    }
+
+    public void endNameStep() throws SAXPathException
+    {
+    }
+
+    public void startTextNodeStep(int axis) throws SAXPathException
+    {
+    }
+    public void endTextNodeStep() throws SAXPathException
+    {
+    }
+
+    public void startCommentNodeStep(int axis) throws SAXPathException
+    {
+    }
+
+    public void endCommentNodeStep() throws SAXPathException
+    {
+    }
+
+    public void startAllNodeStep(int axis) throws SAXPathException
+    {
+    }
+
+    public void endAllNodeStep() throws SAXPathException
+    {
+    }
+
+    public void startProcessingInstructionNodeStep(int axis,
+                                                   String name) throws SAXPathException
+    {
+    }
+    public void endProcessingInstructionNodeStep() throws SAXPathException
+    {
+    }
+
+    public void startPredicate() throws SAXPathException
+    {
+    }
+
+    public void endPredicate() throws SAXPathException
+    {
+    }
+
+    public void startFilterExpr() throws SAXPathException
+    {
+    }
+
+    public void endFilterExpr() throws SAXPathException
+    {
+    }
+
+    public void startOrExpr() throws SAXPathException
+    {
+    }
+
+    public void endOrExpr(boolean create) throws SAXPathException
+    {
+    }
+
+    public void startAndExpr() throws SAXPathException
+    {
+    }
+
+    public void endAndExpr(boolean create) throws SAXPathException
+    {
+    }
+
+    public void startEqualityExpr() throws SAXPathException
+    {
+    }
+
+    public void endEqualityExpr(int operator) throws SAXPathException
+    {
+    }
+
+    public void startRelationalExpr() throws SAXPathException
+    {
+    }
+
+    public void endRelationalExpr(int operator) throws SAXPathException
+    {
+    }
+
+    public void startAdditiveExpr() throws SAXPathException
+    {
+    }
+
+    public void endAdditiveExpr(int operator) throws SAXPathException
+    {
+    }
+
+    public void startMultiplicativeExpr() throws SAXPathException
+    {
+    }
+
+    public void endMultiplicativeExpr(int operator) throws SAXPathException
+    {
+    }
+
+    public void startUnaryExpr() throws SAXPathException
+    {
+    }
+
+    public void endUnaryExpr(int operator) throws SAXPathException
+    {
+    }
+
+    public void startUnionExpr() throws SAXPathException
+    {
+    }
+
+    public void endUnionExpr(boolean create) throws SAXPathException
+    {
+    }
+
+    public void number(int number) throws SAXPathException
+    {
+    }
+
+    public void number(double number) throws SAXPathException
+    {
+    }
+
+    public void literal(String literal) throws SAXPathException
+    {
+    }
+
+    public void variableReference(String prefix,
+                                  String variableName) throws SAXPathException
+    {
+    }
+
+    public void startFunction(String prefix,
+                              String functionName) throws SAXPathException
+    {
+    }
+
+    public void endFunction() throws SAXPathException
+    {
+    }
+
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/saxpath/helpers/XPathReaderFactory.java b/libjaxen-java/src/java/main/org/jaxen/saxpath/helpers/XPathReaderFactory.java
new file mode 100644
index 0000000..216ba47
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/saxpath/helpers/XPathReaderFactory.java
@@ -0,0 +1,170 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/saxpath/helpers/XPathReaderFactory.java,v 1.9 2006/09/15 20:41:38 elharo Exp $
+ * $Revision: 1.9 $
+ * $Date: 2006/09/15 20:41:38 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Jaxen Project and was originally
+ * created by bob mcwhirter <bob at werken.com> and
+ * James Strachan <jstrachan at apache.org>.  For more information on the
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ *
+ * $Id: XPathReaderFactory.java,v 1.9 2006/09/15 20:41:38 elharo Exp $
+ */
+
+
+
+
+package org.jaxen.saxpath.helpers;
+
+import org.jaxen.saxpath.SAXPathException;
+import org.jaxen.saxpath.XPathReader;
+
+/** Create an {@link org.jaxen.saxpath.XPathReader} from
+ *  either a system property, or a named class.
+ *
+ *  <p>
+ *  Similar to the SAX API, the <code>XPathReaderFactory</code>
+ *  can create an <code>XPathReader</code> from a name of a
+ *  class passed in directly, or by inspecting the system
+ *  property <code>org.saxpath.driver</code>.
+ *
+ *  @author bob mcwhirter (bob at werken.com)
+ */
+public class XPathReaderFactory
+{
+    /** The <code>org.saxpath.driver</code> property name. */
+    public static final String DRIVER_PROPERTY = "org.saxpath.driver";
+
+    /** The default driver to use if none is configured. */
+    protected static final String DEFAULT_DRIVER = "org.jaxen.saxpath.base.XPathReader";
+    
+    private XPathReaderFactory() {}
+    
+    
+    /** Create an <code>XPathReader</code> using the value of
+     *  the <code>org.saxpath.driver</code> system property.
+     *
+     *  @return an instance of the <code>XPathReader</code> specified
+     *          by the <code>org.saxpath.driver</code> property
+     *
+     *  @throws SAXPathException if the property is  not set, or if
+     *          the class can not be instantiated for some reason,
+     *          or if the class doesn't implement the <code>XPathReader</code>
+     *          interface
+     */
+    public static XPathReader createReader() throws SAXPathException
+    {
+        String className = null;
+
+        try
+        {
+            className = System.getProperty( DRIVER_PROPERTY );
+        }
+        catch (SecurityException e)
+        {
+            // we'll use the default
+        }
+
+        if ( className == null
+             ||
+             className.length() == 0 )
+        {
+            className = DEFAULT_DRIVER;
+        }
+
+        return createReader( className );
+    }
+    
+    /** Create an <code>XPathReader</code> using the passed
+     *  in class name.
+     *
+     *  @param className the name of the class that implements
+     *         the <code>XPathReader</code> interface.
+     * 
+     *  @return an XPathReader
+     *
+     *  @throws SAXPathException if the class cannot be
+     *          instantiated for some reason, or if the
+     *          class doesn't implement the <code>XPathReader</code>
+     *          interface
+     */
+    public static XPathReader createReader(String className) throws SAXPathException
+    {
+        Class readerClass  = null;
+        XPathReader reader = null;
+
+        try
+        {
+            // Use the full version of Class.forName(), so as to
+            // work better in sandboxed environments, such as
+            // servlet containers and applets.
+
+            readerClass = Class.forName( className,
+                                         true,
+                                         XPathReaderFactory.class.getClassLoader() );
+            
+            // Double-check that it's actually the right kind of class
+            // before attempting instantiation.
+            
+            if ( ! XPathReader.class.isAssignableFrom( readerClass ) )
+            {
+                throw new SAXPathException( "Class [" + className 
+                  + "] does not implement the org.jaxen.saxpath.XPathReader interface." );
+            }
+        }
+        catch (ClassNotFoundException e)
+        {
+            throw new SAXPathException( e );
+        }
+
+        try
+        {
+            reader = (XPathReader) readerClass.newInstance();
+        }
+        catch (IllegalAccessException e)
+        {
+            throw new SAXPathException( e );
+        }
+        catch (InstantiationException e)
+        {
+            throw new SAXPathException( e );
+        }
+        
+        return reader;
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/saxpath/helpers/package.html b/libjaxen-java/src/java/main/org/jaxen/saxpath/helpers/package.html
new file mode 100644
index 0000000..d866dcb
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/saxpath/helpers/package.html
@@ -0,0 +1,13 @@
+<html>
+	<head>
+		<title>
+			org.jaxen.saxpath.helpers.*
+		</title>
+	</head>
+
+	<body>
+		<p>
+			Helper classes for instantiating XPathReaders.
+		</p>
+	</body>
+</html>
diff --git a/libjaxen-java/src/java/main/org/jaxen/saxpath/package.html b/libjaxen-java/src/java/main/org/jaxen/saxpath/package.html
new file mode 100644
index 0000000..3c22eeb
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/saxpath/package.html
@@ -0,0 +1,14 @@
+<html>
+	<head>
+		<title>
+			org.jaxen.saxpath.*
+		</title>
+	</head>
+
+	<body>
+		<p>
+			Classes related to the event-based parsing and handling
+			of XPath expressions.
+		</p>
+	</body>
+</html>
diff --git a/libjaxen-java/src/java/main/org/jaxen/util/AncestorAxisIterator.java b/libjaxen-java/src/java/main/org/jaxen/util/AncestorAxisIterator.java
new file mode 100644
index 0000000..67bb99c
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/util/AncestorAxisIterator.java
@@ -0,0 +1,64 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/util/AncestorAxisIterator.java,v 1.13 2006/02/05 21:47:40 elharo Exp $
+ * $Revision: 1.13 $
+ * $Date: 2006/02/05 21:47:40 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: AncestorAxisIterator.java,v 1.13 2006/02/05 21:47:40 elharo Exp $
+ */
+
+
+
+package org.jaxen.util;
+
+
+import org.jaxen.Navigator;
+
+public class AncestorAxisIterator extends AncestorOrSelfAxisIterator
+{
+    public AncestorAxisIterator(Object contextNode,
+                                Navigator navigator)
+    {
+        super( contextNode,
+               navigator );
+        next();
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/util/AncestorOrSelfAxisIterator.java b/libjaxen-java/src/java/main/org/jaxen/util/AncestorOrSelfAxisIterator.java
new file mode 100644
index 0000000..8168a94
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/util/AncestorOrSelfAxisIterator.java
@@ -0,0 +1,97 @@
+package org.jaxen.util;
+
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/util/AncestorOrSelfAxisIterator.java,v 1.13 2006/02/05 21:47:40 elharo Exp $
+ * $Revision: 1.13 $
+ * $Date: 2006/02/05 21:47:40 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2005 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Jaxen Project and was originally
+ * created by bob mcwhirter <bob at werken.com> and
+ * James Strachan <jstrachan at apache.org>.  For more information on the
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ *
+ * $Id: AncestorOrSelfAxisIterator.java,v 1.13 2006/02/05 21:47:40 elharo Exp $
+*/
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+import org.jaxen.Navigator;
+import org.jaxen.UnsupportedAxisException;
+import org.jaxen.JaxenRuntimeException;
+
+public class AncestorOrSelfAxisIterator implements Iterator
+{
+    private Object    contextNode;
+    private Navigator navigator;
+
+    public AncestorOrSelfAxisIterator(Object contextNode,
+                                      Navigator navigator)
+    {
+        // XXX should we throw a NullPointerException here if contextNode is null?
+        this.contextNode = contextNode;
+        this.navigator = navigator;
+    }
+
+    public boolean hasNext()
+    {
+        return contextNode != null;
+    }
+
+    public Object next()
+    {
+        try
+        {
+            if (hasNext()) {
+                Object result = contextNode;
+                contextNode = navigator.getParentNode(contextNode);
+                return result;
+            }
+            throw new NoSuchElementException("Exhausted ancestor-or-self axis");
+        }
+        catch (UnsupportedAxisException e)
+        {
+            throw new JaxenRuntimeException(e);
+        }
+    }
+
+    public void remove()
+    {
+        throw new UnsupportedOperationException();
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/util/DescendantAxisIterator.java b/libjaxen-java/src/java/main/org/jaxen/util/DescendantAxisIterator.java
new file mode 100644
index 0000000..1714775
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/util/DescendantAxisIterator.java
@@ -0,0 +1,116 @@
+package org.jaxen.util;
+
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/util/DescendantAxisIterator.java,v 1.12 2006/02/05 21:47:40 elharo Exp $
+ * $Revision: 1.12 $
+ * $Date: 2006/02/05 21:47:40 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2005 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Jaxen Project and was originally
+ * created by bob mcwhirter <bob at werken.com> and
+ * James Strachan <jstrachan at apache.org>.  For more information on the
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ *
+ * $Id: DescendantAxisIterator.java,v 1.12 2006/02/05 21:47:40 elharo Exp $
+*/
+
+import org.jaxen.Navigator;
+import org.jaxen.UnsupportedAxisException;
+import org.jaxen.JaxenRuntimeException;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.ArrayList;
+
+public class DescendantAxisIterator implements Iterator
+{
+
+    private ArrayList stack = new ArrayList();
+    private Iterator children;
+    private Navigator navigator;
+
+    public DescendantAxisIterator(Object contextNode,
+                                  Navigator navigator) throws UnsupportedAxisException
+    {
+        this(navigator, navigator.getChildAxisIterator(contextNode));
+    }
+
+    public DescendantAxisIterator(Navigator navigator,
+                                  Iterator iterator)
+    {
+        this.navigator = navigator;
+        this.children = iterator;
+    }
+
+    public boolean hasNext()
+    {
+        while (!children.hasNext())
+        {
+            if (stack.isEmpty())
+            {
+                return false;
+            }
+            children = (Iterator) stack.remove(stack.size()-1);
+        }
+        return true;
+    }
+
+    public Object next()
+    {
+        try
+        {
+            if (hasNext())
+            {
+                Object node = children.next();
+                stack.add(children);
+                children = navigator.getChildAxisIterator(node);
+                return node;
+            }
+            throw new NoSuchElementException();
+        }
+        catch (UnsupportedAxisException e)
+        {
+            throw new JaxenRuntimeException(e);
+        }
+    }
+
+    public void remove()
+    {
+        throw new UnsupportedOperationException();
+    }
+
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/util/DescendantOrSelfAxisIterator.java b/libjaxen-java/src/java/main/org/jaxen/util/DescendantOrSelfAxisIterator.java
new file mode 100644
index 0000000..62ae17a
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/util/DescendantOrSelfAxisIterator.java
@@ -0,0 +1,60 @@
+package org.jaxen.util;
+
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/util/DescendantOrSelfAxisIterator.java,v 1.10 2006/02/05 21:47:40 elharo Exp $
+ * $Revision: 1.10 $
+ * $Date: 2006/02/05 21:47:40 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2005 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Jaxen Project and was originally
+ * created by bob mcwhirter <bob at werken.com> and
+ * James Strachan <jstrachan at apache.org>.  For more information on the
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ *
+ * $Id: DescendantOrSelfAxisIterator.java,v 1.10 2006/02/05 21:47:40 elharo Exp $
+*/
+
+import org.jaxen.Navigator;
+
+public class DescendantOrSelfAxisIterator extends DescendantAxisIterator
+{
+    public DescendantOrSelfAxisIterator(Object contextNode,
+                                        Navigator navigator)
+    {
+        super(navigator, new SingleObjectIterator(contextNode));
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/util/FollowingAxisIterator.java b/libjaxen-java/src/java/main/org/jaxen/util/FollowingAxisIterator.java
new file mode 100644
index 0000000..71a6f1e
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/util/FollowingAxisIterator.java
@@ -0,0 +1,153 @@
+package org.jaxen.util;
+
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/util/FollowingAxisIterator.java,v 1.7 2006/02/05 21:47:40 elharo Exp $
+ * $Revision: 1.7 $
+ * $Date: 2006/02/05 21:47:40 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2005 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Jaxen Project and was originally
+ * created by bob mcwhirter <bob at werken.com> and
+ * James Strachan <jstrachan at apache.org>.  For more information on the
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ *
+ * $Id: FollowingAxisIterator.java,v 1.7 2006/02/05 21:47:40 elharo Exp $
+*/
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+import org.jaxen.Navigator;
+import org.jaxen.UnsupportedAxisException;
+import org.jaxen.JaxenRuntimeException;
+import org.jaxen.JaxenConstants;
+
+public class FollowingAxisIterator implements Iterator
+{
+    private Object contextNode;
+    
+    private Navigator navigator;
+
+    private Iterator siblings;
+
+    private Iterator currentSibling;
+
+    public FollowingAxisIterator(Object contextNode,
+                                 Navigator navigator) throws UnsupportedAxisException
+    {
+        this.contextNode = contextNode;
+        this.navigator = navigator;
+        this.siblings = navigator.getFollowingSiblingAxisIterator(contextNode);
+        this.currentSibling = JaxenConstants.EMPTY_ITERATOR;
+    }
+
+    private boolean goForward()
+    {
+        while ( ! siblings.hasNext() )
+        {
+            if ( !goUp() )
+            {
+                return false;
+            }
+        }
+
+        Object nextSibling = siblings.next();
+
+        this.currentSibling = new DescendantOrSelfAxisIterator(nextSibling, navigator);
+
+        return true;
+    }
+
+    private boolean goUp()
+    {
+        if ( contextNode == null
+             ||
+             navigator.isDocument(contextNode) )
+        {
+            return false;
+        }
+
+        try
+        {
+            contextNode = navigator.getParentNode( contextNode );
+
+            if ( contextNode != null
+                 &&
+                 !navigator.isDocument(contextNode) )
+            {
+                siblings = navigator.getFollowingSiblingAxisIterator(contextNode);
+                return true;
+            }
+            else
+            {
+                return false;
+            }
+        }
+        catch (UnsupportedAxisException e)
+        {
+            throw new JaxenRuntimeException(e);
+        }
+    }
+
+    public boolean hasNext()
+    {
+        while ( ! currentSibling.hasNext() )
+        {
+            if ( ! goForward() )
+            {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    public Object next() throws NoSuchElementException
+    {
+        if ( ! hasNext() )
+        {
+            throw new NoSuchElementException();
+        }
+
+        return currentSibling.next();
+    }
+
+    public void remove() throws UnsupportedOperationException
+    {
+        throw new UnsupportedOperationException();
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/util/FollowingSiblingAxisIterator.java b/libjaxen-java/src/java/main/org/jaxen/util/FollowingSiblingAxisIterator.java
new file mode 100644
index 0000000..98f19af
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/util/FollowingSiblingAxisIterator.java
@@ -0,0 +1,108 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/util/FollowingSiblingAxisIterator.java,v 1.10 2006/02/05 21:47:40 elharo Exp $
+ * $Revision: 1.10 $
+ * $Date: 2006/02/05 21:47:40 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: FollowingSiblingAxisIterator.java,v 1.10 2006/02/05 21:47:40 elharo Exp $
+ */
+
+
+
+package org.jaxen.util;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+import org.jaxen.JaxenConstants;
+import org.jaxen.Navigator;
+import org.jaxen.UnsupportedAxisException;
+
+public class FollowingSiblingAxisIterator implements Iterator
+{
+    private Object    contextNode;
+    private Navigator navigator;
+    private Iterator  siblingIter;
+
+    public FollowingSiblingAxisIterator(Object contextNode,
+                                        Navigator navigator) throws UnsupportedAxisException
+    {
+        this.contextNode = contextNode;
+        this.navigator   = navigator;
+        init();
+    }
+
+    private void init() throws UnsupportedAxisException
+    {
+        Object parent = this.navigator.getParentNode( this.contextNode );
+
+        if ( parent != null )
+        {
+            siblingIter = this.navigator.getChildAxisIterator( parent );
+            
+            while ( siblingIter.hasNext() )
+            {
+                Object eachChild = siblingIter.next();
+                if ( eachChild.equals(this.contextNode) ) break;
+            }
+        }
+        else {
+            siblingIter = JaxenConstants.EMPTY_ITERATOR;
+        }
+
+    }
+
+    public boolean hasNext()
+    {
+        return siblingIter.hasNext();
+    }
+
+    public Object next() throws NoSuchElementException
+    {
+        return siblingIter.next();
+    }
+
+    public void remove() throws UnsupportedOperationException
+    {
+        throw new UnsupportedOperationException();
+    }
+
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/util/LinkedIterator.java b/libjaxen-java/src/java/main/org/jaxen/util/LinkedIterator.java
new file mode 100644
index 0000000..29b9c8f
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/util/LinkedIterator.java
@@ -0,0 +1,114 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/util/LinkedIterator.java,v 1.7 2006/02/05 21:47:40 elharo Exp $
+ * $Revision: 1.7 $
+ * $Date: 2006/02/05 21:47:40 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: LinkedIterator.java,v 1.7 2006/02/05 21:47:40 elharo Exp $
+ */
+
+
+package org.jaxen.util;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+
+/**
+ * @deprecated elharo this class is undocumented and untested.
+ *     It will be removed in a future release.
+ */
+public class LinkedIterator implements Iterator
+{
+    private List iterators;
+    private int  cur;
+
+    public LinkedIterator()
+    {
+        this.iterators = new ArrayList();
+        this.cur       = 0;
+    }
+
+    public void addIterator(Iterator i)
+    {
+        this.iterators.add( i );
+    }
+
+    public boolean hasNext()
+    {
+        boolean has = false;
+
+        if ( this.cur < this.iterators.size() )
+        {
+            has = ((Iterator)this.iterators.get( this.cur )).hasNext();
+
+            if ( ! has
+                 &&
+                 this.cur < this.iterators.size() )
+            {
+                ++this.cur;
+                has = hasNext();
+            }
+        }
+        else
+        {
+            has = false;
+        }
+
+        return has;
+    }
+
+    public Object next()
+    {
+        if ( ! hasNext() )
+        {
+            throw new NoSuchElementException();
+        }
+
+        return ((Iterator)this.iterators.get( this.cur )).next();
+    }
+
+    public void remove()
+    {
+        throw new UnsupportedOperationException();
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/util/PrecedingAxisIterator.java b/libjaxen-java/src/java/main/org/jaxen/util/PrecedingAxisIterator.java
new file mode 100644
index 0000000..519d77b
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/util/PrecedingAxisIterator.java
@@ -0,0 +1,178 @@
+package org.jaxen.util;
+
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/util/PrecedingAxisIterator.java,v 1.9 2006/02/05 21:47:40 elharo Exp $
+ * $Revision: 1.9 $
+ * $Date: 2006/02/05 21:47:40 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2005 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Jaxen Project and was originally
+ * created by bob mcwhirter <bob at werken.com> and
+ * James Strachan <jstrachan at apache.org>.  For more information on the
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ *
+ * $Id: PrecedingAxisIterator.java,v 1.9 2006/02/05 21:47:40 elharo Exp $
+*/
+
+import org.jaxen.JaxenConstants;
+import org.jaxen.JaxenRuntimeException;
+import org.jaxen.Navigator;
+import org.jaxen.UnsupportedAxisException;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.ListIterator;
+import java.util.NoSuchElementException;
+
+/**
+ * This implementation of 'preceding' works like so:
+ * the preceding axis includes preceding-siblings of this node and their
+ * descendants. Also, for each ancestor node of this node, it includes
+ * all preceding-siblings of that ancestor, and their descendants. Finally, it
+ * includes the ancestor nodes themselves.
+ * <p/>
+ * The reversed descendant-or-self axes that are required are calculated using a
+ * stack of reversed 'child-or-self' axes. When asked for a node, it is always taken
+ * from a child-or-self axis. If it was the last node on that axis, the node is returned.
+ * Otherwise, this axis is pushed on the stack, and the process is repeated with the child-or-self
+ * of the node. Eventually this recurses down to the last descendant of any node, then works
+ * back up to the root.
+ * <p/>
+ * I reckon most object models could provide a faster implementation of the reversed
+ * 'children-or-self' used here.
+ */
+public class PrecedingAxisIterator implements Iterator
+{
+    private Iterator ancestorOrSelf;
+    private Iterator precedingSibling;
+    private ListIterator childrenOrSelf;
+    private ArrayList stack;
+
+    private Navigator navigator;
+
+    public PrecedingAxisIterator(Object contextNode,
+                                 Navigator navigator) throws UnsupportedAxisException
+    {
+        this.navigator = navigator;
+        this.ancestorOrSelf = navigator.getAncestorOrSelfAxisIterator(contextNode);
+        this.precedingSibling = JaxenConstants.EMPTY_ITERATOR;
+        this.childrenOrSelf = JaxenConstants.EMPTY_LIST_ITERATOR;
+        this.stack = new ArrayList();
+    }
+
+
+    public boolean hasNext()
+    {
+        try
+        {
+            while (!childrenOrSelf.hasPrevious())
+            {
+                if (stack.isEmpty())
+                {
+                    while (!precedingSibling.hasNext())
+                    {
+                        if (!ancestorOrSelf.hasNext())
+                        {
+                            return false;
+                        }
+                        Object contextNode = ancestorOrSelf.next();
+                        precedingSibling = new PrecedingSiblingAxisIterator(contextNode, navigator);
+                    }
+                    Object node = precedingSibling.next();
+                    childrenOrSelf = childrenOrSelf(node);
+                }
+                else
+                {
+                    childrenOrSelf = (ListIterator) stack.remove(stack.size()-1);
+                }
+            }
+            return true;
+        }
+        catch (UnsupportedAxisException e)
+        {
+            throw new JaxenRuntimeException(e);
+        }
+    }
+
+    private ListIterator childrenOrSelf(Object node)
+    {
+        try
+        {
+            ArrayList reversed = new ArrayList();
+            reversed.add(node);
+            Iterator childAxisIterator = navigator.getChildAxisIterator(node);
+            if (childAxisIterator != null)
+            {
+                while (childAxisIterator.hasNext())
+                {
+                    reversed.add(childAxisIterator.next());
+                }
+            }
+            return reversed.listIterator(reversed.size());
+        }
+        catch (UnsupportedAxisException e)
+        {
+            throw new JaxenRuntimeException(e);
+        }
+    }
+
+    public Object next() throws NoSuchElementException
+    {
+        if (!hasNext())
+        {
+            throw new NoSuchElementException();
+        }
+        while (true)
+        {
+            Object result = childrenOrSelf.previous();
+            if (childrenOrSelf.hasPrevious())
+            {
+                // if this isn't 'self' construct 'descendant-or-self'
+                stack.add(childrenOrSelf);
+                childrenOrSelf = childrenOrSelf(result);
+                continue;
+            }
+            return result;
+        }
+    }
+
+
+    public void remove() throws UnsupportedOperationException
+    {
+        throw new UnsupportedOperationException();
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/util/PrecedingSiblingAxisIterator.java b/libjaxen-java/src/java/main/org/jaxen/util/PrecedingSiblingAxisIterator.java
new file mode 100644
index 0000000..77bd83d
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/util/PrecedingSiblingAxisIterator.java
@@ -0,0 +1,138 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/util/PrecedingSiblingAxisIterator.java,v 1.14 2006/02/05 21:47:40 elharo Exp $
+ * $Revision: 1.14 $
+ * $Date: 2006/02/05 21:47:40 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: PrecedingSiblingAxisIterator.java,v 1.14 2006/02/05 21:47:40 elharo Exp $
+ */
+
+
+
+package org.jaxen.util;
+
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.NoSuchElementException;
+
+import org.jaxen.JaxenConstants;
+import org.jaxen.Navigator;
+import org.jaxen.UnsupportedAxisException;
+
+public class PrecedingSiblingAxisIterator implements Iterator
+{
+    private Object    contextNode;
+    private Navigator navigator;
+
+    private Iterator  siblingIter;
+    private Object    nextObj;
+
+    public PrecedingSiblingAxisIterator(Object contextNode,
+                                        Navigator navigator) throws UnsupportedAxisException
+    {
+        this.contextNode = contextNode;
+        this.navigator   = navigator;
+
+        init();
+        if ( siblingIter.hasNext() )
+        {
+            this.nextObj = siblingIter.next();
+        }
+    }
+
+    private void init() throws UnsupportedAxisException
+    {
+        
+        Object parent = this.navigator.getParentNode( this.contextNode );
+
+        if ( parent != null )
+        {
+            Iterator childIter = this.navigator.getChildAxisIterator( parent );
+            LinkedList siblings = new LinkedList();
+            
+            while ( childIter.hasNext() )
+            {
+                Object eachChild = childIter.next();
+                if ( eachChild.equals(this.contextNode) )
+                {
+                    break;
+                }
+                siblings.addFirst( eachChild );
+            }
+            
+            this.siblingIter = siblings.iterator();
+            
+        }
+        else {
+            this.siblingIter = JaxenConstants.EMPTY_ITERATOR;
+        }
+        
+    }
+
+    public boolean hasNext()
+    {
+        return ( this.nextObj != null );
+    }
+
+    public Object next() throws NoSuchElementException
+    {
+        if ( ! hasNext() )
+        {
+            throw new NoSuchElementException();
+        }
+
+        Object obj = this.nextObj;
+        if ( siblingIter.hasNext() )
+        {
+            this.nextObj = siblingIter.next();
+        }
+        else {
+            this.nextObj = null;
+        }
+        return obj;
+    }
+
+    public void remove() throws UnsupportedOperationException
+    {
+        throw new UnsupportedOperationException();
+    }
+
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/util/SelfAxisIterator.java b/libjaxen-java/src/java/main/org/jaxen/util/SelfAxisIterator.java
new file mode 100644
index 0000000..0f64df7
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/util/SelfAxisIterator.java
@@ -0,0 +1,60 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/util/SelfAxisIterator.java,v 1.7 2006/02/05 21:47:40 elharo Exp $
+ * $Revision: 1.7 $
+ * $Date: 2006/02/05 21:47:40 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: SelfAxisIterator.java,v 1.7 2006/02/05 21:47:40 elharo Exp $
+ */
+
+
+
+package org.jaxen.util;
+
+public class SelfAxisIterator extends SingleObjectIterator
+{
+
+    public SelfAxisIterator(Object node)
+    {
+        super(node);
+    }
+
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/util/SingleObjectIterator.java b/libjaxen-java/src/java/main/org/jaxen/util/SingleObjectIterator.java
new file mode 100644
index 0000000..c6bc876
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/util/SingleObjectIterator.java
@@ -0,0 +1,90 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/util/SingleObjectIterator.java,v 1.6 2006/02/05 21:47:40 elharo Exp $
+ * $Revision: 1.6 $
+ * $Date: 2006/02/05 21:47:40 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: SingleObjectIterator.java,v 1.6 2006/02/05 21:47:40 elharo Exp $
+ */
+
+
+package org.jaxen.util;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+/**
+ * Simple utility class that wraps an iterator around one object.
+ * This is a little more efficent than creating a one-object list.
+ *
+ */
+public class SingleObjectIterator implements Iterator
+{
+    private Object  object;
+    private boolean seen;
+
+    public SingleObjectIterator(Object object)
+    {
+        this.object = object;
+        this.seen   = false;
+    }
+
+    public boolean hasNext()
+    {
+        return ! this.seen;
+    }
+
+    public Object next()
+    {
+        if ( hasNext() )
+        {
+            this.seen = true;
+            return this.object;
+        }
+
+        throw new NoSuchElementException();
+    }
+
+    public void remove()
+    {
+        throw new UnsupportedOperationException();
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/util/SingletonList.java b/libjaxen-java/src/java/main/org/jaxen/util/SingletonList.java
new file mode 100644
index 0000000..b15c63c
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/util/SingletonList.java
@@ -0,0 +1,77 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/util/SingletonList.java,v 1.3 2006/02/05 21:47:40 elharo Exp $
+ * $Revision: 1.3 $
+ * $Date: 2006/02/05 21:47:40 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: SingletonList.java,v 1.3 2006/02/05 21:47:40 elharo Exp $
+ */
+
+
+
+package org.jaxen.util;
+
+import java.util.AbstractList;
+
+/**
+ * A utility class that implements singleton lists
+ * (to avoid dependency on JDK 1.3).
+ * @version $Id: SingletonList.java,v 1.3 2006/02/05 21:47:40 elharo Exp $
+ * @author Attila Szegedi
+ */
+public class SingletonList extends AbstractList {
+    private final Object element;
+    
+    public SingletonList(Object element) {
+        this.element = element;
+    }
+    
+    public int size() {
+        return 1;
+    }
+
+    public Object get(int index) {
+        if(index == 0) {
+            return element;
+        }
+        throw new IndexOutOfBoundsException(index + " != 0");
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/util/StackedIterator.java b/libjaxen-java/src/java/main/org/jaxen/util/StackedIterator.java
new file mode 100644
index 0000000..d614008
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/util/StackedIterator.java
@@ -0,0 +1,172 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/util/StackedIterator.java,v 1.12 2006/02/05 21:47:40 elharo Exp $
+ * $Revision: 1.12 $
+ * $Date: 2006/02/05 21:47:40 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: StackedIterator.java,v 1.12 2006/02/05 21:47:40 elharo Exp $
+ */
+
+
+
+package org.jaxen.util;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.NoSuchElementException;
+import java.util.Set;
+
+import org.jaxen.Navigator;
+
+/**
+ * @deprecated this iterator is no longer used to implement any of the Jaxen axes. If you have implemented
+ * a navigator-specific axis based on this class, take a look at the DescendantAxisIterator for ideas 
+ * on how to remove that dependency.
+ */
+public abstract class StackedIterator implements Iterator
+{
+
+    private LinkedList iteratorStack;
+    private Navigator  navigator;
+
+    private Set        created;
+
+    public StackedIterator(Object contextNode,
+                           Navigator navigator)
+    {
+        this.iteratorStack = new LinkedList();
+        this.created       = new HashSet();
+
+        init( contextNode,
+              navigator );
+    }
+
+    protected StackedIterator()
+    {
+        this.iteratorStack = new LinkedList();
+        this.created       = new HashSet();
+    }
+
+    protected void init(Object contextNode,
+                        Navigator navigator)
+    {
+        this.navigator     = navigator;
+        
+        //pushIterator( internalCreateIterator( contextNode ) );
+    }
+
+    protected Iterator internalCreateIterator(Object contextNode)
+    {
+        if ( this.created.contains( contextNode ) )
+        {
+            return null;
+        }
+
+        this.created.add( contextNode );
+
+        return createIterator( contextNode );
+    }
+
+    public boolean hasNext()
+    {
+        Iterator curIter = currentIterator();
+
+        if ( curIter == null )
+        {
+            return false;
+        }
+
+        return curIter.hasNext();
+    }
+
+    public Object next() throws NoSuchElementException
+    {
+        if ( ! hasNext() )
+        {
+            throw new NoSuchElementException();
+        }
+
+        Iterator curIter = currentIterator();
+        Object   object  = curIter.next();
+
+        pushIterator( internalCreateIterator( object ) );
+
+        return object;
+    }
+
+    public void remove() throws UnsupportedOperationException
+    {
+        throw new UnsupportedOperationException();
+    }
+
+    abstract protected Iterator createIterator(Object contextNode);
+
+    protected void pushIterator(Iterator iter)
+    {
+        if ( iter != null )
+        {
+            this.iteratorStack.addFirst(iter); //addLast( iter );
+        }
+    }
+
+    private Iterator currentIterator()
+    {
+        while ( iteratorStack.size() > 0 )
+        {
+            Iterator curIter = (Iterator) iteratorStack.getFirst();
+
+            if ( curIter.hasNext() )
+            {
+                return curIter;
+            }
+
+            iteratorStack.removeFirst();
+        }
+
+        return null;
+    }
+
+    protected Navigator getNavigator()
+    {
+        return this.navigator;
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/util/XPath2XMLVisitor.java b/libjaxen-java/src/java/main/org/jaxen/util/XPath2XMLVisitor.java
new file mode 100644
index 0000000..1c04439
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/util/XPath2XMLVisitor.java
@@ -0,0 +1,237 @@
+package org.jaxen.util;
+
+import java.io.PrintWriter;
+import java.util.Iterator;
+import java.util.List;
+
+import org.jaxen.expr.AdditiveExpr;
+import org.jaxen.expr.AllNodeStep;
+import org.jaxen.expr.CommentNodeStep;
+import org.jaxen.expr.EqualityExpr;
+import org.jaxen.expr.Expr;
+import org.jaxen.expr.FilterExpr;
+import org.jaxen.expr.FunctionCallExpr;
+import org.jaxen.expr.LiteralExpr;
+import org.jaxen.expr.LocationPath;
+import org.jaxen.expr.LogicalExpr;
+import org.jaxen.expr.MultiplicativeExpr;
+import org.jaxen.expr.NameStep;
+import org.jaxen.expr.NumberExpr;
+import org.jaxen.expr.PathExpr;
+import org.jaxen.expr.Predicate;
+import org.jaxen.expr.ProcessingInstructionNodeStep;
+import org.jaxen.expr.RelationalExpr;
+import org.jaxen.expr.Step;
+import org.jaxen.expr.TextNodeStep;
+import org.jaxen.expr.UnaryExpr;
+import org.jaxen.expr.UnionExpr;
+import org.jaxen.expr.VariableReferenceExpr;
+import org.jaxen.expr.Visitor;
+
+public class XPath2XMLVisitor implements Visitor {
+    
+    protected PrintWriter printer;
+    protected int tabIndex;
+
+    public XPath2XMLVisitor() {
+        this.printer = new PrintWriter(System.out);
+    }
+
+    public XPath2XMLVisitor(PrintWriter printer) {
+        this.printer = printer;
+    }
+
+    public void visit(PathExpr expr) {
+        printLn("<PathExpr>");
+        if (expr.getFilterExpr() != null){
+            expr.getFilterExpr().accept(this);
+        }
+        if (expr.getLocationPath() != null){
+            expr.getLocationPath().accept(this);
+        }
+        printLn("</PathExpr>");
+    }
+    
+    public void visit(LocationPath expr) {
+        printLn("<LocationPath absolute=\"" + expr.isAbsolute() + "\">");
+        Iterator steps = expr.getSteps().iterator();
+
+        while (steps.hasNext()){
+            Step step = (Step)steps.next();
+            step.accept(this);
+        }
+        printLn("</LocationPath>");
+    }
+    
+    public void visit(LogicalExpr expr) {
+        printLn("<LogicalExpr operator=\""+ expr.getOperator() + "\">");
+        printLhsRhs(expr.getLHS(), expr.getRHS());
+        printLn("</LogicalExpr>");
+    }
+
+    void printLhsRhs(Expr lhs, Expr rhs){
+        tabIndex++;
+        printLn("<lhsExpr>");
+        lhs.accept(this);
+        printLn("</lhsExpr>");
+        printLn("<rhsExpr>");
+        rhs.accept(this);
+        printLn("</rhsExpr>");
+        tabIndex--;
+    }
+    
+    public void visit(EqualityExpr expr) {
+        printLn("<EqualityExpr operator=\""+ expr.getOperator() + "\">");
+        printLhsRhs(expr.getLHS(), expr.getRHS());
+        printLn("</EqualityExpr>");
+    }
+    
+    public void visit(FilterExpr expr) {
+        printLn("<FilterExpr>");
+        tabIndex++;
+        if (expr.getExpr() != null){
+            expr.getExpr().accept(this);
+        }
+        Iterator iter = expr.getPredicates().iterator();
+        while (iter.hasNext()){
+            ((Predicate)iter.next()).getExpr().accept(this);
+        }
+        tabIndex--;
+        printLn("</FilterExpr>");
+    }
+    
+    public void visit(RelationalExpr expr) {
+        printLn("<RelationalExpr operator=\""+ expr.getOperator() + "\">");
+        printLhsRhs(expr.getLHS(), expr.getRHS());
+        printLn("</RelationalExpr>");
+    }
+    
+    public void visit(AdditiveExpr expr) {
+        printLn("<AdditiveExpr operator=\""+ expr.getOperator() + "\">");
+        printLhsRhs(expr.getLHS(), expr.getRHS());
+        printLn("</AdditiveExpr>");
+    }
+    
+    public void visit(MultiplicativeExpr expr) {
+        printLn("<MultiplicativeExpr operator=\""+ expr.getOperator() + "\">");
+        printLhsRhs(expr.getLHS(), expr.getRHS());
+        printLn("</MultiplicativeExpr>");
+    }
+    
+    public void visit(UnaryExpr expr) {
+        printLn("<UnaryExpr>");
+        expr.getExpr().accept(this);
+        printLn("</UnaryExpr>");
+    }
+    
+    public void visit(UnionExpr expr) {
+        printLn("<UnionExpr>");
+        printLhsRhs(expr.getLHS(), expr.getRHS());
+        printLn("</UnionExpr>");
+    }
+    
+    public void visit(NumberExpr expr) {
+        printLn("<NumberExpr>");
+        printLn(expr.getNumber().toString());
+        printLn("</NumberExpr>");
+    }
+    
+    public void visit(LiteralExpr expr) {
+        printLn("<LiteralExpr literal=\"" + expr.getLiteral() + "\"/>");
+    }
+
+    public void visit(VariableReferenceExpr expr) {
+        printLn("<VariableReferenceExpr name=\"" + expr.getVariableName() + "\"/>");
+    }
+    
+    public void visit(FunctionCallExpr expr){
+        printLn("<FunctionCallExpr prefix=\"" + expr.getPrefix() +
+        "\" functionName=\"" + expr.getFunctionName() + "\">");
+
+        Iterator iterator = expr.getParameters().iterator();
+        tabIndex++;
+        printLn("<Args>");
+        while (iterator.hasNext()){
+            ((Expr)iterator.next()).accept(this);
+        }
+        printLn("</Args>");
+        tabIndex--;
+        printLn("</FunctionCallExpr>");
+    }
+
+    public void visit(NameStep step){
+        printLn("<NameStep prefix=\"" + step.getPrefix()+
+            "\" localName=\"" + step.getLocalName() + "\">");
+        Iterator iter = step.getPredicates().iterator();
+        tabIndex++;
+        while(iter.hasNext()){
+            Predicate predicate = (Predicate)iter.next();
+            predicate.accept(this);
+        }
+        tabIndex--;
+        printLn("</NameStep>");
+    }
+    
+    public void visit(ProcessingInstructionNodeStep step){
+        printLn("<ProcessingInstructionNodeStep name=\"" + step.getName() +
+            "\" axis=\"" + step.getAxis() + ">");
+
+        tabIndex++;
+        handlePredicates(step.getPredicates());
+        tabIndex--;
+        printLn("</ProcessingInstructionNodeStep>");
+    }
+    
+    public void visit(AllNodeStep step){
+        printLn("<AllNodeStep>");
+        tabIndex++;
+        handlePredicates(step.getPredicates());
+        tabIndex--;
+        printLn("</AllNodeStep>");
+    }
+    
+    public void visit(TextNodeStep step){
+        printLn("<TextNodeStep>");
+        tabIndex++;
+        handlePredicates(step.getPredicates());
+        tabIndex--;
+        printLn("</TextNodeStep>");
+    }
+    
+    public void visit(CommentNodeStep step){
+        printLn("<CommentNodeStep>");
+        tabIndex++;
+        handlePredicates(step.getPredicates());
+        tabIndex--;
+        printLn("</CommentNodeStep>");
+    }
+    
+    public void visit(Predicate predicate){
+        printLn("<Predicate>");
+        tabIndex++;
+        predicate.getExpr().accept(this);
+        tabIndex--;
+        printLn("</Predicate>");
+    }
+
+    //---------------------------------------------------------------
+    protected void printLn(String str){
+        StringBuffer buffer = new StringBuffer();
+        for (int i = 0; i < tabIndex; i++) {
+            buffer.append("\t");
+        }
+        buffer.append(str);
+
+        printer.println(buffer.toString());
+    }
+
+    protected void handlePredicates(List predicates){
+        if (predicates != null){
+            Iterator iter = predicates.iterator();
+            while(iter.hasNext()){
+                ((Predicate)iter.next()).accept(this);
+            }
+        }
+    }
+    
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/util/package.html b/libjaxen-java/src/java/main/org/jaxen/util/package.html
new file mode 100644
index 0000000..82c783c
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/util/package.html
@@ -0,0 +1,13 @@
+<html>
+	<head>
+		<title>
+			org.jaxen.util.*
+		</title>
+	</head>
+
+	<body>
+		<p>
+			Utility objects for walking object models.
+		</p>
+	</body>
+</html>
diff --git a/libjaxen-java/src/java/main/org/jaxen/xom/DocumentNavigator.java b/libjaxen-java/src/java/main/org/jaxen/xom/DocumentNavigator.java
new file mode 100644
index 0000000..6fd7362
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/xom/DocumentNavigator.java
@@ -0,0 +1,408 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/xom/DocumentNavigator.java,v 1.8 2006/06/03 20:02:50 elharo Exp $
+ * $Revision: 1.8 $
+ * $Date: 2006/06/03 20:02:50 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2003 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Jaxen Project and was originally
+ * created by bob mcwhirter <bob at werken.com> and
+ * James Strachan <jstrachan at apache.org>.  For more information on the
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ *
+ * $Id: DocumentNavigator.java,v 1.8 2006/06/03 20:02:50 elharo Exp $
+ */
+
+
+package org.jaxen.xom;
+
+
+import nu.xom.Attribute;
+import nu.xom.Comment;
+import nu.xom.Document;
+import nu.xom.Element;
+import nu.xom.ProcessingInstruction;
+import nu.xom.Text;
+import nu.xom.Node;
+import nu.xom.Builder;
+import nu.xom.NodeFactory;
+import nu.xom.ParentNode;
+
+import org.jaxen.XPath;
+import org.jaxen.UnsupportedAxisException;
+import org.jaxen.FunctionCallException;
+import org.jaxen.BaseXPath;
+import org.jaxen.JaxenConstants;
+import org.jaxen.util.SingleObjectIterator;
+
+import org.jaxen.saxpath.SAXPathException;
+
+import java.util.Iterator;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Interface for navigating around the XOM object model.
+ *
+ * <p>
+ * This class is not intended for direct usage, but is
+ * used by the Jaxen engine during evaluation.
+ * </p>
+ *
+ * @see XPath
+ *
+ */
+public class DocumentNavigator extends org.jaxen.DefaultNavigator
+{
+    /**
+     * 
+     */
+    private static final long serialVersionUID = 3159311338575942877L;
+
+    public boolean isAttribute(Object o) {
+        return o instanceof Attribute;
+    }
+
+    public boolean isComment(Object o) {
+        return o instanceof Comment;
+    }
+
+    public boolean isDocument(Object o) {
+        return o instanceof Document;
+    }
+
+    public boolean isElement(Object o) {
+        return o instanceof Element;
+    }
+
+    public boolean isNamespace(Object o) {
+        return o instanceof XPathNamespace;
+    }
+
+    public boolean isProcessingInstruction(Object o) {
+        return o instanceof ProcessingInstruction;
+    }
+
+    public boolean isText(Object o) {
+        return o instanceof Text;
+    }
+
+    //
+    
+    public String getAttributeName(Object o) {
+        return (isAttribute(o) ? ((Attribute)o).getLocalName() : null);
+    }
+
+    public String getAttributeNamespaceUri(Object o) {
+        return (isAttribute(o) ? ((Attribute)o).getNamespaceURI() : null);
+    }
+
+    public String getAttributeQName(Object o) {
+        return (isAttribute(o) ? ((Attribute)o).getQualifiedName() : null);
+    }
+
+    public String getAttributeStringValue(Object o) {
+        return (isAttribute(o) ? ((Attribute)o).getValue() : null);
+    }
+
+    //
+    
+    public String getCommentStringValue(Object o) {
+        return (isComment(o) ? ((Comment)o).getValue() : null);
+    }
+
+    public String getElementName(Object o) {
+        return (isElement(o) ? ((Element)o).getLocalName() : null);
+    }
+
+    public String getElementNamespaceUri(Object o) {
+        return (isElement(o) ? ((Element)o).getNamespaceURI() : null);
+    }
+
+    public String getElementQName(Object o) {
+        return (isElement(o) ? ((Element)o).getQualifiedName() : null);
+    }
+
+    public String getElementStringValue(Object o) {
+        return (o instanceof Node ? ((Node)o).getValue() : null);
+    }
+
+    //
+    
+    public String getNamespacePrefix(Object o) {
+        if (isElement(o)) {
+            return ((Element)o).getNamespacePrefix();
+        } else if (isAttribute(o)) {
+            return ((Attribute)o).getNamespacePrefix();
+        } else if (o instanceof XPathNamespace) {
+            return ((XPathNamespace)o).getNamespacePrefix();
+        }
+        return null;
+    }
+
+    public String getNamespaceStringValue(Object o) {
+        if (isElement(o)) {
+            return ((Element)o).getNamespaceURI();
+        } else if (isAttribute(o)) {
+            return ((Attribute)o).getNamespaceURI();
+        } else if (o instanceof XPathNamespace) {
+            return ((XPathNamespace)o).getNamespaceURI();
+        }
+        return null;
+    }
+
+    //
+    
+    public String getTextStringValue(Object o) {
+        return (o instanceof Text ? ((Text)o).getValue() : null);
+    }
+    
+    //
+
+    public Object getDocument(String s) throws FunctionCallException {
+        try {
+            return new Builder(new NodeFactory()).build(s);
+        } catch (Exception pe) {
+            throw new FunctionCallException(pe);
+        }
+    }
+
+    public Object getDocumentNode(Object o) {
+        ParentNode parent = null;
+        if (o instanceof ParentNode) {
+            parent = (ParentNode)o;
+        } else if (o instanceof Node) {
+            parent = ((Node)o).getParent();
+        }
+        return parent.getDocument();
+    }
+
+    //
+    
+    private abstract static class IndexIterator implements Iterator {
+        private Object o = null;
+        private int pos = 0, end = -1;
+        public IndexIterator(Object o, int pos, int end) {
+            this.o = o;
+            this.pos = pos;
+            this.end = end;
+        }
+        public boolean hasNext() {
+            return pos < end;
+        }
+        public abstract Object get(Object o, int i); 
+        
+        public Object next() {
+            return get(o, pos++);
+        }
+
+        public void remove() {
+            throw new UnsupportedOperationException();
+        }
+    }
+    
+    //
+    
+    public Iterator getAttributeAxisIterator(Object o) {
+        if (isElement(o)) {
+            return new IndexIterator(o, 0, ((Element)o).getAttributeCount()) {
+                public Object get(Object o, int i) {
+                    return ((Element)o).getAttribute(i);
+                }
+            };
+        }
+        return JaxenConstants.EMPTY_ITERATOR;
+    }
+
+    public Iterator getChildAxisIterator(Object o) {
+        if (isElement(o) || (o instanceof Document)) {
+            return new IndexIterator(o, 0, ((ParentNode)o).getChildCount()) {
+                public Object get(Object o, int i) {
+                    return ((ParentNode)o).getChild(i);
+                }
+            };
+        }
+        return JaxenConstants.EMPTY_ITERATOR;
+    }
+
+    //
+
+    public Iterator getParentAxisIterator(Object o) {
+        Object parent = null;
+        if (o instanceof Node) {
+            parent = ((Node)o).getParent();
+        } else if (isNamespace(o)) {
+            parent = ((XPathNamespace)o).getElement();
+        }
+        return (parent != null ? new SingleObjectIterator(parent) : null);
+    }
+
+    public Object getParentNode(Object o)  {
+        return (o instanceof Node ? ((Node)o).getParent() : null);
+    }
+
+    //
+
+    public Iterator getPrecedingAxisIterator(Object o) throws UnsupportedAxisException {
+        return super.getPrecedingAxisIterator(o);
+    }
+
+    public Iterator getPrecedingSiblingAxisIterator(Object o) throws UnsupportedAxisException {
+        return super.getPrecedingSiblingAxisIterator(o);
+    }
+    
+    //
+
+    public String getProcessingInstructionData(Object o) {
+        return (o instanceof ProcessingInstruction ? ((ProcessingInstruction)o).getValue() : null);
+    }
+
+    public String getProcessingInstructionTarget(Object o) {
+        return (o instanceof ProcessingInstruction ? ((ProcessingInstruction)o).getTarget() : null);
+    }
+
+    //
+
+    public String translateNamespacePrefixToUri(String s, Object o) {
+        Element element = null;
+        if (o instanceof Element) {
+            element = (Element) o;
+        } else if (o instanceof ParentNode) {
+        }
+        else if (o instanceof Node) {
+            element = (Element)((Node)o).getParent();
+        }
+        else if (o instanceof XPathNamespace)
+        {
+            element = ((XPathNamespace)o).getElement();
+        }
+        if (element != null) {
+            return element.getNamespaceURI(s);
+        }
+        return null;
+    }
+
+    //
+    
+    public XPath parseXPath(String s) throws SAXPathException {
+        return new BaseXPath(s, this);
+    }
+
+    //
+    
+    /** Wrapper for XOM namespace nodes to give them a parent,
+     * as required by the XPath data model.
+     *
+     *  @author Erwin Bolwidt
+     */
+    private static class XPathNamespace
+    {
+        private Element element;
+
+        private String uri, prefix;
+
+        public XPathNamespace(Element elt, String uri, String prefix)
+        {
+            element = elt;
+            this.uri = uri;
+            this.prefix = prefix;
+        }
+
+        /** Returns the XOM element from which this namespace node has been 
+         *  retrieved. The result may be null when the namespace node has not yet
+         *  been assigned to an element.
+         */
+        public Element getElement()
+        {
+            return element;
+        }
+
+        public String getNamespaceURI()
+        {
+            return uri;
+        }
+
+        public String getNamespacePrefix()
+        {
+            return prefix;
+        }
+
+        public String toString()
+        {
+            return ( "[xmlns:" + prefix + "=\"" +
+                    uri + "\", element=" +
+                    element.getLocalName() + "]" );
+        }
+    }
+
+    //
+    
+    private boolean addNamespaceForElement(Element elt, String uri, String prefix, Map map)
+    {
+        if (uri != null && uri.length() > 0 && (! map.containsKey(prefix))) {
+            map.put(prefix, new XPathNamespace(elt, uri, prefix));
+            return true;
+        }
+        return false;
+    }
+    
+    public Iterator getNamespaceAxisIterator(Object o)
+    {
+        if (! isElement(o)) {
+            return JaxenConstants.EMPTY_ITERATOR;
+        }
+        Map nsMap = new HashMap();
+        Element elt = (Element)o;
+        ParentNode parent = elt;
+        
+        while (parent instanceof Element) {
+            elt = (Element)parent;
+            String uri    = elt.getNamespaceURI();
+            String prefix = elt.getNamespacePrefix();
+            addNamespaceForElement(elt, uri, prefix, nsMap);
+            int count = elt.getNamespaceDeclarationCount();
+            for (int i = 0; i < count; i++) {
+                prefix = elt.getNamespacePrefix(i);
+                uri    = elt.getNamespaceURI(prefix);
+                addNamespaceForElement(elt, uri, prefix, nsMap);
+            }
+            parent = elt.getParent();
+        }
+        addNamespaceForElement(elt, "http://www.w3.org/XML/1998/namespace", "xml", nsMap);
+
+        return nsMap.values().iterator();
+    }
+}
diff --git a/libjaxen-java/src/java/main/org/jaxen/xom/XOMXPath.java b/libjaxen-java/src/java/main/org/jaxen/xom/XOMXPath.java
new file mode 100644
index 0000000..5ae058c
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/jaxen/xom/XOMXPath.java
@@ -0,0 +1,90 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/xom/XOMXPath.java,v 1.6 2006/06/03 20:27:59 elharo Exp $
+ * $Revision: 1.6 $
+ * $Date: 2006/06/03 20:27:59 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2003 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: XOMXPath.java,v 1.6 2006/06/03 20:27:59 elharo Exp $
+ */
+
+
+package org.jaxen.xom;
+
+import org.jaxen.BaseXPath;
+import org.jaxen.JaxenException;
+
+/** An XPath implementation for the XOM model
+ *
+ * <p>This is the main entry point for matching an XPath against a DOM
+ * tree.  You create a compiled XPath object, then match it against
+ * one or more context nodes using the {@link #selectNodes(Object)}
+ * method, as in the following example:</p>
+ *
+ * <pre>
+ * Object xomNode = ...; // Document, Element etc.
+ * XPath path = new XOMXPath("a/b/c");
+ * List results = path.selectNodes(xomNode);
+ * </pre>
+ *
+ * @see BaseXPath
+ * @see <a href="http://www.xom.nu/">The XOM website</a>
+ *
+ * @version $Revision: 1.6 $
+ */
+public class XOMXPath extends BaseXPath
+{
+    /**
+     * 
+     */
+    private static final long serialVersionUID = -5332108546921857671L;
+
+    /** Construct given an XPath expression string.
+     *
+     *  @param xpathExpr the XPath expression.
+     *
+     *  @throws JaxenException if there is a syntax error while
+     *          parsing the expression
+     */
+    public XOMXPath(String xpathExpr) throws JaxenException
+    {
+        super( xpathExpr, new DocumentNavigator());
+    }
+} 
diff --git a/libjaxen-java/src/java/main/org/w3c/dom/UserDataHandler.java b/libjaxen-java/src/java/main/org/w3c/dom/UserDataHandler.java
new file mode 100644
index 0000000..5778155
--- /dev/null
+++ b/libjaxen-java/src/java/main/org/w3c/dom/UserDataHandler.java
@@ -0,0 +1,23 @@
+/** This is a W3C interface we include here so that NamespaceNode can compile in both
+ *  Java 1.4 and 1.5. It's owned by the W3C, and available under their usual 
+ *  extremely liberal license so this shoudldn't bother anyone. (XPath itself
+ *  is under the same license after all.)
+ */
+
+package org.w3c.dom;
+
+public interface UserDataHandler {
+    // OperationType
+    public static final short NODE_CLONED               = 1;
+    public static final short NODE_IMPORTED             = 2;
+    public static final short NODE_DELETED              = 3;
+    public static final short NODE_RENAMED              = 4;
+    public static final short NODE_ADOPTED              = 5;
+
+    public void handle(short operation, 
+                       String key, 
+                       Object data, 
+                       Node src, 
+                       Node dst);
+
+}
\ No newline at end of file
diff --git a/libjaxen-java/src/java/samples/DOMDemo.java b/libjaxen-java/src/java/samples/DOMDemo.java
new file mode 100644
index 0000000..ae99f12
--- /dev/null
+++ b/libjaxen-java/src/java/samples/DOMDemo.java
@@ -0,0 +1,113 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/samples/DOMDemo.java,v 1.10 2006/02/05 21:48:50 elharo Exp $
+ * $Revision: 1.10 $
+ * $Date: 2006/02/05 21:48:50 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: DOMDemo.java,v 1.10 2006/02/05 21:48:50 elharo Exp $
+ */
+
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.w3c.dom.Document;
+
+import org.jaxen.dom.DOMXPath;
+
+import org.jaxen.XPath;
+import org.jaxen.XPathSyntaxException;
+import org.jaxen.JaxenException;
+
+import java.util.List;
+import java.util.Iterator;
+
+public class DOMDemo 
+{
+    public static void main(String[] args)
+    {
+        if ( args.length != 2 )
+        {
+            System.err.println("usage: DOMDemo <document url> <xpath expr>");
+            System.exit( 1 );
+        }
+
+        try
+        {
+            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+            factory.setNamespaceAware(true);
+            DocumentBuilder builder = factory.newDocumentBuilder();
+        
+            Document doc = builder.parse( args[0] );
+            
+            XPath xpath = new DOMXPath( args[1] );
+
+            System.out.println( "XPah:h " + xpath );
+            
+            List results = xpath.selectNodes( doc );
+
+            Iterator resultIter = results.iterator();
+            
+            System.out.println("Document :: " + args[0] );
+            System.out.println("   XPath :: " + args[1] );
+            System.out.println("");
+            System.out.println("Results" );
+            System.out.println("----------------------------------");
+            
+            while ( resultIter.hasNext() )
+            {
+                System.out.println( resultIter.next() );
+            }
+        }
+        catch (XPathSyntaxException e)
+        {
+            System.err.println( e.getMultilineMessage() );
+        }
+        catch (JaxenException e)
+        {
+            e.printStackTrace();
+        }
+        catch (Exception e)
+        {
+            e.printStackTrace();
+        }
+    }
+}
diff --git a/libjaxen-java/src/java/samples/Dom4jDemo.java b/libjaxen-java/src/java/samples/Dom4jDemo.java
new file mode 100644
index 0000000..4942343
--- /dev/null
+++ b/libjaxen-java/src/java/samples/Dom4jDemo.java
@@ -0,0 +1,117 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/samples/Dom4jDemo.java,v 1.10 2006/02/05 21:48:50 elharo Exp $
+ * $Revision: 1.10 $
+ * $Date: 2006/02/05 21:48:50 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: Dom4jDemo.java,v 1.10 2006/02/05 21:48:50 elharo Exp $
+ */
+
+
+import org.dom4j.Document;
+import org.dom4j.Node;
+import org.dom4j.io.SAXReader;
+
+import org.jaxen.XPath;
+import org.jaxen.XPathSyntaxException;
+import org.jaxen.JaxenException;
+
+import org.jaxen.dom4j.Dom4jXPath;
+
+import java.util.List;
+import java.util.Iterator;
+
+public class Dom4jDemo 
+{
+    public static void main(String[] args)
+    {
+        if ( args.length != 2 )
+        {
+            System.err.println("usage: Dom4jDemo <document url> <xpath expr>");
+            System.exit( 1 );
+        }
+
+        try
+        {
+            SAXReader reader = new SAXReader();
+            
+            Document doc = reader.read( args[0] );
+            
+            XPath xpath = new Dom4jXPath( args[1] );
+            
+            List results = xpath.selectNodes( doc );
+
+            Iterator resultIter = results.iterator();
+            
+            System.out.println("Document :: " + args[0] );
+            System.out.println("   XPath :: " + args[1] );
+            System.out.println("");
+            System.out.println("Results" );
+            System.out.println("----------------------------------");
+            
+            while ( resultIter.hasNext() )
+            {
+                Object object = resultIter.next();
+                if ( object instanceof Node ) 
+                {
+                    Node node = (Node) object;
+                    System.out.println( node.asXML() );
+                }
+                else 
+                {
+                    System.out.println( object );
+                }
+            }
+        }
+        catch (XPathSyntaxException e)
+        {
+            System.err.println( e.getMultilineMessage() );
+        }
+        catch (JaxenException e)
+        {
+            e.printStackTrace();
+        }
+        catch (Exception e)
+        {
+            e.printStackTrace();
+        }
+    }
+}
diff --git a/libjaxen-java/src/java/samples/JDOMDemo.java b/libjaxen-java/src/java/samples/JDOMDemo.java
new file mode 100644
index 0000000..ea2057a
--- /dev/null
+++ b/libjaxen-java/src/java/samples/JDOMDemo.java
@@ -0,0 +1,112 @@
+/*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/samples/JDOMDemo.java,v 1.7 2006/02/05 21:48:50 elharo Exp $
+ * $Revision: 1.7 $
+ * $Date: 2006/02/05 21:48:50 $
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id: JDOMDemo.java,v 1.7 2006/02/05 21:48:50 elharo Exp $
+ */
+
+
+import org.jdom.Document;
+import org.jdom.JDOMException;
+import org.jdom.input.SAXBuilder;
+
+import org.jaxen.XPath;
+import org.jaxen.XPathSyntaxException;
+import org.jaxen.JaxenException;
+
+import org.jaxen.jdom.JDOMXPath;
+
+import java.util.List;
+import java.util.Iterator;
+
+public class JDOMDemo 
+{
+    public static void main(String[] args)
+    {
+        if ( args.length != 2 )
+        {
+            System.err.println("usage: JDOMDemo <document url> <xpath expr>");
+            System.exit( 1 );
+        }
+
+        try
+        {
+            SAXBuilder builder = new SAXBuilder();
+            
+            Document doc = builder.build( args[0] );
+            
+            XPath xpath = new JDOMXPath( args[1] );
+            
+            List results = xpath.selectNodes( doc );
+            
+            Iterator resultIter = results.iterator();
+
+            System.out.println("Document :: " + args[0] );
+            System.out.println("   XPath :: " + args[1] );
+            System.out.println("");
+            System.out.println("Results" );
+            System.out.println("----------------------------------");
+
+            while ( resultIter.hasNext() )
+            {
+                System.out.println( resultIter.next() );
+            }
+        }
+        catch (JDOMException e)
+        {
+            e.printStackTrace();
+        }
+        catch (XPathSyntaxException e)
+        {
+            System.err.println( e.getMultilineMessage() );
+        }
+        catch (JaxenException e)
+        {
+            e.printStackTrace();
+        }
+        catch (Exception e)
+        {
+            e.printStackTrace();
+        }
+    }
+}
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/AddNamespaceTest.java b/libjaxen-java/src/java/test/org/jaxen/test/AddNamespaceTest.java
new file mode 100644
index 0000000..9bbb4aa
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/AddNamespaceTest.java
@@ -0,0 +1,80 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2003 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+
+
+package org.jaxen.test;
+
+import junit.framework.TestCase;
+
+import org.jaxen.NamespaceContext;
+import org.jaxen.XPath;
+import org.jaxen.dom.DOMXPath;
+import org.jaxen.saxpath.SAXPathException;
+
+public class AddNamespaceTest extends TestCase
+{
+    public AddNamespaceTest(String name)
+    {
+        super( name );
+    }
+    
+    public void testDefaultContext() throws SAXPathException
+    {
+        XPath xpath = new DOMXPath("foo");
+        xpath.addNamespace("cheese",
+                           "http://cheese.org");
+        xpath.addNamespace("squeeze",
+                           "http://squeeze.org");
+        NamespaceContext nsContext = xpath.getNamespaceContext();
+        assertEquals( "http://cheese.org",
+                      nsContext.translateNamespacePrefixToUri( "cheese" ) );
+        assertEquals( "http://squeeze.org",
+                      nsContext.translateNamespacePrefixToUri( "squeeze" ) );
+
+    }
+
+}
\ No newline at end of file
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/AncestorOrSelfAxisIteratorTest.java b/libjaxen-java/src/java/test/org/jaxen/test/AncestorOrSelfAxisIteratorTest.java
new file mode 100644
index 0000000..6da4efa
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/AncestorOrSelfAxisIteratorTest.java
@@ -0,0 +1,103 @@
+/* $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2005 Elliotte Rusty Harold.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+package org.jaxen.test;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.jaxen.util.AncestorOrSelfAxisIterator;
+import org.w3c.dom.Document;
+
+import junit.framework.TestCase;
+
+public class AncestorOrSelfAxisIteratorTest extends TestCase {
+
+    private Iterator iterator;
+
+    public AncestorOrSelfAxisIteratorTest(String name) {
+        super(name);
+    }
+    
+    protected void setUp() throws ParserConfigurationException {
+        
+        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        factory.setNamespaceAware(true);
+        Document doc = factory.newDocumentBuilder().newDocument();
+        doc.appendChild(doc.createElement("root"));
+        
+        iterator = new AncestorOrSelfAxisIterator(doc, new org.jaxen.dom.DocumentNavigator());
+        
+    }
+    
+    
+    public void testNoInfiniteLoops() {
+     
+        iterator.next();
+        try {
+            iterator.next();
+            fail("Iterated twice");   
+        }
+        catch (NoSuchElementException ex) {
+        }
+        
+    }
+    
+    
+    public void testRemove() {
+        
+        try {
+            iterator.remove();
+            fail("Removed from iterator");   
+        }
+        catch (UnsupportedOperationException ex) {
+        }
+        
+    }
+    
+}
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/ArithmeticTest.java b/libjaxen-java/src/java/test/org/jaxen/test/ArithmeticTest.java
new file mode 100644
index 0000000..4d9a014
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/ArithmeticTest.java
@@ -0,0 +1,113 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2005 Elliotte Rusty Harold.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+
+package org.jaxen.test;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import junit.framework.TestCase;
+
+import org.jaxen.JaxenException;
+import org.jaxen.XPath;
+import org.jaxen.dom.DOMXPath;
+import org.w3c.dom.Document;
+
+/**
+ * @author Elliotte Rusty Harold
+ *
+ */
+public class ArithmeticTest extends TestCase {
+
+    private Document doc;
+    
+    public void setUp() throws ParserConfigurationException
+    {
+        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        factory.setNamespaceAware(true);
+        DocumentBuilder builder = factory.newDocumentBuilder();
+        doc = builder.newDocument();
+        org.w3c.dom.Element a = doc.createElementNS("", "a");
+        doc.appendChild(a);
+    }
+
+
+    public ArithmeticTest(String name) {
+        super(name);
+    }
+
+    public void testNumbersThatBeginWithADecimalPoint() 
+      throws JaxenException {
+        
+        XPath xpath = new DOMXPath(".5 > .4");
+        Boolean result = (Boolean) xpath.evaluate(doc);
+        assertTrue(result.booleanValue());
+        
+    }    
+
+    
+   public void testNumbersThatBeginWithADecimalPoint2() 
+      throws JaxenException {
+        
+        XPath xpath = new DOMXPath(".3 <= .4 <= 1.1");
+        Boolean result = (Boolean) xpath.evaluate(doc);
+        assertTrue(result.booleanValue());
+        
+    }    
+
+   public void testLeftAssociativityOfLessThanOrEqual() 
+      throws JaxenException {
+        
+        XPath xpath = new DOMXPath(".3 <= .4 <= 0.9");
+        Boolean result = (Boolean) xpath.evaluate(doc);
+        assertFalse(result.booleanValue());
+        
+    }    
+
+    
+}
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/AxisTest.java b/libjaxen-java/src/java/test/org/jaxen/test/AxisTest.java
new file mode 100644
index 0000000..5bd52aa
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/AxisTest.java
@@ -0,0 +1,76 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2005 Elliotte Rusty Harold.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+
+package org.jaxen.test;
+
+import org.jaxen.JaxenRuntimeException;
+import org.jaxen.saxpath.Axis;
+
+import junit.framework.TestCase;
+
+
+/**
+ * @author Elliotte Rusty Harold
+ *
+ */
+public class AxisTest extends TestCase {
+
+    public AxisTest(String name) {
+        super(name);
+    }
+
+    public void testIllegalAxisNumber() {
+        try {
+            Axis.lookup(-10009);
+            fail("Looked up negative number");
+        }
+        catch (JaxenRuntimeException ex) {
+            assertEquals("Illegal Axis Number", ex.getMessage());
+        }
+    }    
+    
+}
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/BaseTests.java b/libjaxen-java/src/java/test/org/jaxen/test/BaseTests.java
new file mode 100644
index 0000000..2ca1195
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/BaseTests.java
@@ -0,0 +1,74 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2005 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+
+
+package org.jaxen.test;
+
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+/**
+ * <p>
+ *   Collect the org.jaxen.saxpath.base tests.
+ * </p>
+ * 
+ * @author Elliotte Rusty Harold
+ * @version 1.1b9
+ *
+ */
+public class BaseTests {
+    
+    public static Test suite() {
+        
+        TestSuite result = new TestSuite();
+        result.addTest(new TestSuite(XPathReaderTest.class));
+        return result;
+        
+    }
+    
+}
\ No newline at end of file
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/BaseXPathTest.java b/libjaxen-java/src/java/test/org/jaxen/test/BaseXPathTest.java
new file mode 100644
index 0000000..df82e3d
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/BaseXPathTest.java
@@ -0,0 +1,1163 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2005 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+
+
+package org.jaxen.test;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.ObjectOutputStream;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.jaxen.BaseXPath;
+import org.jaxen.JaxenException;
+import org.jaxen.NamespaceContext;
+import org.jaxen.SimpleNamespaceContext;
+import org.jaxen.XPath;
+import org.jaxen.dom.DOMXPath;
+import org.jaxen.dom.DocumentNavigator;
+import org.jaxen.dom.NamespaceNode;
+import org.jaxen.pattern.Pattern;
+import org.jaxen.saxpath.helpers.XPathReaderFactory;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.Text;
+import org.xml.sax.SAXException;
+
+import junit.framework.TestCase;
+
+/**
+ * <p>
+ * Tests for org.jaxen.BaseXPath.
+ * </p>
+ * 
+ * @author Elliotte Rusty Harold
+ * @version 1.1b10
+ *
+ */
+public class BaseXPathTest extends TestCase {
+
+    private org.w3c.dom.Document doc;
+    private DocumentBuilder builder;
+
+    public BaseXPathTest(String name) {
+        super(name);
+    }
+    
+    protected void setUp() throws ParserConfigurationException {
+        
+        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        factory.setNamespaceAware(true);
+        doc = factory.newDocumentBuilder().newDocument();
+        builder = factory.newDocumentBuilder();
+        
+    }
+    
+    public void testSelectSingleNodeForContext() throws JaxenException {
+        
+        BaseXPath xpath = new DOMXPath("1 + 2");
+        
+        String stringValue = xpath.stringValueOf(xpath);
+        assertEquals("3", stringValue);
+        
+        Number numberValue = xpath.numberValueOf(xpath);
+        assertEquals(3, numberValue.doubleValue(), 0.00001);
+        
+    }
+    
+    
+    public void testParentOfSelection() throws JaxenException {
+        /*
+        html
+            a
+                img
+            a        <- return that node
+                img   <- select this node
+        */
+        XPath xpath = new DOMXPath("(/html/a/img[contains(@src,'gif')])[2]/..");
+        org.w3c.dom.Element html = doc.createElementNS("", "html");
+        org.w3c.dom.Element a1 = doc.createElementNS("", "a");
+        org.w3c.dom.Element a2 = doc.createElementNS("", "a");
+        org.w3c.dom.Element img1 = doc.createElementNS("", "img");
+          org.w3c.dom.Attr img1_src = doc.createAttributeNS("", "src");
+        img1_src.setValue("1.gif");
+        org.w3c.dom.Element img2 = doc.createElementNS("", "img");
+        org.w3c.dom.Attr img2_src = doc.createAttributeNS("", "src");
+        img2_src.setValue("2.gif");
+
+        img1.setAttributeNode(img1_src);
+        img2.setAttributeNode(img2_src);
+        a1.appendChild(img1);
+        a2.appendChild(img2);
+        html.appendChild(a1);
+        html.appendChild(a2);
+        doc.appendChild(html);
+
+        List result = xpath.selectNodes(doc);
+        assertEquals(1, result.size());
+        assertEquals(a2, result.get(0));
+    }
+
+
+    
+    
+    public void testEvaluateString() throws JaxenException {
+        
+        BaseXPath xpath = new DOMXPath("string(/*)");
+        
+        doc.appendChild(doc.createElement("root"));
+        String stringValue = (String) xpath.evaluate(doc);
+        assertEquals("", stringValue);
+        
+    }
+    
+    
+    public void testNumberValueOfEmptyNodeSetIsNaN() throws JaxenException {
+        
+        BaseXPath xpath = new DOMXPath("/x");
+        
+        doc.appendChild(doc.createElement("root"));
+        Double numberValue = (Double) xpath.numberValueOf(doc);
+        assertTrue(numberValue.isNaN());
+        
+    }
+    
+    
+    public void testPathWithParentheses() throws JaxenException {
+        
+        BaseXPath xpath = new DOMXPath("(/root)/child");
+        
+        Element root = doc.createElement("root");
+        doc.appendChild(root);
+        Element child = doc.createElement("child");
+        root.appendChild(child);
+        
+        assertEquals(child, xpath.selectSingleNode(doc));
+        
+    }
+    
+    
+    public void testEvaluateWithMultiNodeAnswer() throws JaxenException {
+        
+        BaseXPath xpath = new DOMXPath("(/descendant-or-self::node())");
+        
+        doc.appendChild(doc.createElement("root"));
+        List result = (List) xpath.evaluate(doc);
+        assertEquals(2, result.size());
+        
+    }
+    
+    
+    public void testValueOfEmptyListIsEmptyString() throws JaxenException {
+        
+        BaseXPath xpath = new DOMXPath("/element");
+        doc.appendChild(doc.createElement("root"));
+        
+        String stringValue = xpath.stringValueOf(doc);
+        assertEquals("", stringValue);
+        
+    }
+
+    public void testAllNodesQuery() throws JaxenException {
+        
+        BaseXPath xpath = new DOMXPath("//. | /");
+        org.w3c.dom.Element root = doc.createElementNS("http://www.example.org/", "root");
+        doc.appendChild(root);
+        
+        String stringValue = xpath.stringValueOf(doc);
+        assertEquals("", stringValue);
+        
+    }
+
+    
+    public void testAncestorAxis() throws JaxenException {
+        
+        BaseXPath xpath = new DOMXPath("ancestor::*");
+        org.w3c.dom.Element root = doc.createElementNS("", "root");
+        org.w3c.dom.Element parent = doc.createElementNS("", "parent");
+        doc.appendChild(root);
+        org.w3c.dom.Element child = doc.createElementNS("", "child");
+        root.appendChild(parent);
+        parent.appendChild(child);
+        
+        List result = xpath.selectNodes(child);
+        assertEquals(2, result.size());
+        assertEquals(root, result.get(0));   
+        assertEquals(parent, result.get(1));
+        
+    }    
+    
+    
+    public void testPrecedingSiblingAxisIsInDocumentOrder() throws JaxenException {
+        
+        BaseXPath xpath = new DOMXPath("preceding-sibling::*");
+        org.w3c.dom.Element root = doc.createElementNS("", "root");
+        doc.appendChild(root);
+        org.w3c.dom.Element child1 = doc.createElementNS("", "child1");
+        root.appendChild(child1);
+        org.w3c.dom.Element child2 = doc.createElementNS("", "child2");
+        root.appendChild(child2);
+        org.w3c.dom.Element child3 = doc.createElementNS("", "child3");
+        root.appendChild(child3);
+        
+        List result = xpath.selectNodes(child3);
+        assertEquals(2, result.size());
+        assertEquals(child1, result.get(0));   
+        assertEquals(child2, result.get(1));
+        
+    }    
+    
+    
+    public void testPrecedingAxisIsInDocumentOrder() throws JaxenException {
+        
+        BaseXPath xpath = new DOMXPath("preceding::*");
+        org.w3c.dom.Element root = doc.createElementNS("", "root");
+        doc.appendChild(root);
+        org.w3c.dom.Element parent1 = doc.createElementNS("", "parent1");
+        root.appendChild(parent1);
+        org.w3c.dom.Element parent2 = doc.createElementNS("", "parent2");
+        root.appendChild(parent2);
+        org.w3c.dom.Element child1 = doc.createElementNS("", "child1");
+        parent2.appendChild(child1);
+        org.w3c.dom.Element child2 = doc.createElementNS("", "child2");
+        parent2.appendChild(child2);
+        org.w3c.dom.Element child3 = doc.createElementNS("", "child3");
+        parent2.appendChild(child3);
+        
+        List result = xpath.selectNodes(child3);
+        assertEquals(3, result.size());
+        assertEquals(parent1, result.get(0));   
+        assertEquals(child1, result.get(1));   
+        assertEquals(child2, result.get(2));
+        
+    }    
+    
+    
+    public void testPrecedingAxisWithPositionalPredicate() throws JaxenException {
+        
+        BaseXPath xpath = new DOMXPath("preceding::*[1]");
+        org.w3c.dom.Element root = doc.createElementNS("", "root");
+        doc.appendChild(root);
+        org.w3c.dom.Element child1 = doc.createElementNS("", "child1");
+        root.appendChild(child1);
+        org.w3c.dom.Element child2 = doc.createElementNS("", "child2");
+        root.appendChild(child2);
+        org.w3c.dom.Element child3 = doc.createElementNS("", "child3");
+        root.appendChild(child3);
+        
+        List result = xpath.selectNodes(child3);
+        assertEquals(1, result.size());  
+        assertEquals(child2, result.get(0));
+        
+    }    
+    
+    
+    public void testAncestorAxisWithPositionalPredicate() throws JaxenException {
+        
+        BaseXPath xpath = new DOMXPath("ancestor::*[1]");
+        org.w3c.dom.Element root = doc.createElementNS("", "root");
+        doc.appendChild(root);
+        org.w3c.dom.Element child1 = doc.createElementNS("", "child1");
+        root.appendChild(child1);
+        org.w3c.dom.Element child2 = doc.createElementNS("", "child2");
+        child1.appendChild(child2);
+        org.w3c.dom.Element child3 = doc.createElementNS("", "child3");
+        child2.appendChild(child3);
+        
+        List result = xpath.selectNodes(child3);
+        assertEquals(1, result.size());  
+        assertEquals(child2, result.get(0));
+        
+    }    
+    
+    
+    public void testAncestorOrSelfAxis() throws JaxenException {
+        
+        BaseXPath xpath = new DOMXPath("ancestor-or-self::*");
+        org.w3c.dom.Element root = doc.createElementNS("", "root");
+        org.w3c.dom.Element parent = doc.createElementNS("", "parent");
+        doc.appendChild(root);
+        org.w3c.dom.Element child = doc.createElementNS("", "child");
+        root.appendChild(parent);
+        parent.appendChild(child);
+        
+        List result = xpath.selectNodes(child);
+        assertEquals(3, result.size());
+        assertEquals(root, result.get(0));   
+        assertEquals(parent, result.get(1));
+        assertEquals(child, result.get(2));
+        
+    }    
+    
+    
+    // test case for JAXEN-55
+    public void testAbbreviatedDoubleSlashAxis() throws JaxenException {
+        
+        BaseXPath xpath = new DOMXPath("//x");
+        org.w3c.dom.Element a = doc.createElementNS("", "a");
+        org.w3c.dom.Element b = doc.createElementNS("", "b");
+        doc.appendChild(a);
+        org.w3c.dom.Element x1 = doc.createElementNS("", "x");
+        x1.appendChild(doc.createTextNode("1"));
+        a.appendChild(x1);
+        a.appendChild(b);
+        org.w3c.dom.Element x2 = doc.createElementNS("", "x");
+        org.w3c.dom.Element x3 = doc.createElementNS("", "x");
+        org.w3c.dom.Element x4 = doc.createElementNS("", "x");
+        a.appendChild(x4);
+        b.appendChild(x2);
+        b.appendChild(x3);
+        x2.appendChild(doc.createTextNode("2"));
+        x3.appendChild(doc.createTextNode("3"));
+        x4.appendChild(doc.createTextNode("4"));
+        
+        List result = xpath.selectNodes(doc);
+        assertEquals(4, result.size());
+        assertEquals(x1, result.get(0));   
+        assertEquals(x2, result.get(1));   
+        assertEquals(x3, result.get(2));   
+        assertEquals(x4, result.get(3));
+        
+    }    
+    
+    
+    // test case for JAXEN-55
+    public void testAncestorFollowedByChildren() throws JaxenException {
+        
+        BaseXPath xpath = new DOMXPath("/a/b/x/ancestor::*/child::x");
+        org.w3c.dom.Element a = doc.createElementNS("", "a");
+        org.w3c.dom.Element b = doc.createElementNS("", "b");
+        doc.appendChild(a);
+        org.w3c.dom.Element x1 = doc.createElementNS("", "x");
+        x1.appendChild(doc.createTextNode("1"));
+        a.appendChild(x1);
+        a.appendChild(b);
+        org.w3c.dom.Element x2 = doc.createElementNS("", "x");
+        org.w3c.dom.Element x3 = doc.createElementNS("", "x");
+        org.w3c.dom.Element x4 = doc.createElementNS("", "x");
+        a.appendChild(x4);
+        b.appendChild(x2);
+        b.appendChild(x3);
+        x2.appendChild(doc.createTextNode("2"));
+        x3.appendChild(doc.createTextNode("3"));
+        x4.appendChild(doc.createTextNode("4"));
+        
+        List result = xpath.selectNodes(doc);
+        assertEquals(4, result.size());
+        assertEquals(x1, result.get(0));   
+        assertEquals(x2, result.get(1));   
+        assertEquals(x3, result.get(2));   
+        assertEquals(x4, result.get(3));
+        
+    }    
+    
+    
+    // test case for JAXEN-55
+    public void testDescendantAxis() throws JaxenException {
+        
+        BaseXPath xpath = new DOMXPath("/descendant::x");
+        org.w3c.dom.Element a = doc.createElementNS("", "a");
+        org.w3c.dom.Element b = doc.createElementNS("", "b");
+        doc.appendChild(a);
+        org.w3c.dom.Element x1 = doc.createElementNS("", "x");
+        x1.appendChild(doc.createTextNode("1"));
+        a.appendChild(x1);
+        a.appendChild(b);
+        org.w3c.dom.Element x2 = doc.createElementNS("", "x");
+        org.w3c.dom.Element x3 = doc.createElementNS("", "x");
+        org.w3c.dom.Element x4 = doc.createElementNS("", "x");
+        a.appendChild(x4);
+        b.appendChild(x2);
+        b.appendChild(x3);
+        x2.appendChild(doc.createTextNode("2"));
+        x3.appendChild(doc.createTextNode("3"));
+        x4.appendChild(doc.createTextNode("4"));
+        
+        List result = xpath.selectNodes(doc);
+        assertEquals(4, result.size());
+        assertEquals(x1, result.get(0));   
+        assertEquals(x2, result.get(1));   
+        assertEquals(x3, result.get(2));   
+        assertEquals(x4, result.get(3));
+        
+    }    
+    
+    public void testDescendantAxisWithAttributes() throws JaxenException {
+        
+        BaseXPath xpath = new DOMXPath("/descendant::x/@*");
+        org.w3c.dom.Element a = doc.createElementNS("", "a");
+        org.w3c.dom.Element b = doc.createElementNS("", "b");
+        doc.appendChild(a);
+        org.w3c.dom.Element x1 = doc.createElementNS("", "x");
+        a.appendChild(x1);
+        a.appendChild(b);
+        org.w3c.dom.Element x2 = doc.createElementNS("", "x");
+        org.w3c.dom.Element x3 = doc.createElementNS("", "x");
+        org.w3c.dom.Element x4 = doc.createElementNS("", "x");
+        a.appendChild(x4);
+        b.appendChild(x2);
+        b.appendChild(x3);
+        
+        Attr a1 = doc.createAttribute("name");
+        a1.setNodeValue("1");
+        x1.setAttributeNode(a1);
+        Attr a2 = doc.createAttribute("name");
+        a2.setNodeValue("2");
+        x2.setAttributeNode(a2);
+        Attr a3 = doc.createAttribute("name");
+        a3.setNodeValue("3");
+        x3.setAttributeNode(a3);
+        Attr a4 = doc.createAttribute("name");
+        a4.setNodeValue("4");
+        x4.setAttributeNode(a4);
+        
+        List result = xpath.selectNodes(doc);
+        assertEquals(4, result.size());
+        assertEquals(a1, result.get(0));   
+        assertEquals(a2, result.get(1));   
+        assertEquals(a3, result.get(2));   
+        assertEquals(a4, result.get(3));
+        
+    }    
+    
+    public void testDescendantAxisWithNamespaceNodes() throws JaxenException {
+        
+        BaseXPath xpath = new DOMXPath("/descendant::x/namespace::node()");
+        org.w3c.dom.Element a = doc.createElementNS("", "a");
+        org.w3c.dom.Element b = doc.createElementNS("", "b");
+        doc.appendChild(a);
+        org.w3c.dom.Element x1 = doc.createElementNS("", "x");
+        a.appendChild(x1);
+        a.appendChild(b);
+        org.w3c.dom.Element x2 = doc.createElementNS("", "x");
+        org.w3c.dom.Element x3 = doc.createElementNS("", "x");
+        org.w3c.dom.Element x4 = doc.createElementNS("", "x");
+        a.appendChild(x4);
+        b.appendChild(x2);
+        b.appendChild(x3);
+        
+        Attr a1 = doc.createAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:a");
+        a1.setNodeValue("http://www.example.org/");
+        x1.setAttributeNode(a1);
+        Attr a2 = doc.createAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:b");
+        a2.setNodeValue("http://www.example.org/");
+        x2.setAttributeNode(a2);
+        Attr a3 = doc.createAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:c");
+        a3.setNodeValue("http://www.example.org/");
+        x3.setAttributeNode(a3);
+        Attr a4 = doc.createAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:d");
+        a4.setNodeValue("http://www.example.org/");
+        x4.setAttributeNode(a4);
+        
+        List result = xpath.selectNodes(doc);
+        assertEquals(8, result.size());
+        Iterator iterator = result.iterator();
+        StringBuffer sb = new StringBuffer(4);
+        while (iterator.hasNext()) {
+            NamespaceNode ns = (NamespaceNode) iterator.next();
+            if (ns.getNodeValue().equals("http://www.example.org/")) {
+                String name = ns.getNodeName();
+                sb.append(name);
+            }
+        }
+        assertEquals("abcd", sb.toString());
+        
+    }    
+    
+    public void testMultipleAttributesOnElement() throws JaxenException {
+        
+        BaseXPath xpath = new DOMXPath("/descendant::x/@*");
+        org.w3c.dom.Element a = doc.createElementNS("", "a");
+        org.w3c.dom.Element b = doc.createElementNS("", "b");
+        doc.appendChild(a);
+        org.w3c.dom.Element x1 = doc.createElementNS("", "x");
+        a.appendChild(x1);
+        a.appendChild(b);
+        
+        Attr a1 = doc.createAttribute("name1");
+        a1.setNodeValue("1");
+        x1.setAttributeNode(a1);
+        Attr a2 = doc.createAttribute("name2");
+        a2.setNodeValue("2");
+        x1.setAttributeNode(a2);
+        Attr a3 = doc.createAttribute("name3");
+        a3.setNodeValue("3");
+        x1.setAttributeNode(a3);
+        Attr a4 = doc.createAttribute("name4");
+        a4.setNodeValue("4");
+        x1.setAttributeNode(a4);
+        
+        List result = xpath.selectNodes(doc);
+        assertEquals(4, result.size());
+        assertTrue(result.contains(a1));
+        assertTrue(result.contains(a2));
+        assertTrue(result.contains(a3));
+        assertTrue(result.contains(a4));
+        
+    }   
+    
+    public void testXMLNamespaceAttributeOrderOnAncestorAxis() 
+      throws JaxenException {
+     
+        org.w3c.dom.Element superroot = doc.createElement("superroot");
+        doc.appendChild(superroot);
+        org.w3c.dom.Element root = doc.createElement("root");
+        superroot.appendChild(root);
+        
+        org.w3c.dom.Attr p0 = doc.createAttributeNS("http://www.w3.org/XML/1998/namespace", "xml:id");
+        p0.setValue("p0");
+        superroot.setAttributeNodeNS(p0);
+        org.w3c.dom.Attr p1 = doc.createAttributeNS("http://www.w3.org/XML/1998/namespace", "xml:id");
+        p1.setValue("p1");
+        root.setAttributeNodeNS(p1);
+        
+        org.w3c.dom.Element child = doc.createElement("child312");
+        root.appendChild(child);
+        
+        BaseXPath xpath = new DOMXPath("ancestor::*/@xml:*");
+        List result = xpath.selectNodes(child);
+        assertEquals(2, result.size());
+        assertEquals(p0, result.get(0));
+        assertEquals(p1, result.get(1));
+        
+    }
+    
+    public void testDescendantAxisWithAttributesAndChildren() throws JaxenException {
+        
+        BaseXPath xpath = new DOMXPath("/descendant::x/@* | /descendant::x");
+        org.w3c.dom.Element a = doc.createElementNS("", "a");
+        org.w3c.dom.Element b = doc.createElementNS("", "b");
+        doc.appendChild(a);
+        org.w3c.dom.Element x1 = doc.createElementNS("", "x");
+        a.appendChild(x1);
+        a.appendChild(b);
+        org.w3c.dom.Element x2 = doc.createElementNS("", "x");
+        org.w3c.dom.Element x3 = doc.createElementNS("", "x");
+        org.w3c.dom.Element x4 = doc.createElementNS("", "x");
+        a.appendChild(x4);
+        b.appendChild(x2);
+        b.appendChild(x3);
+        
+        Attr a1 = doc.createAttribute("name");
+        a1.setNodeValue("1");
+        x1.setAttributeNode(a1);
+        Attr a2 = doc.createAttribute("name");
+        a2.setNodeValue("2");
+        x2.setAttributeNode(a2);
+        Attr a3 = doc.createAttribute("name");
+        a3.setNodeValue("3");
+        x3.setAttributeNode(a3);
+        Attr a4 = doc.createAttribute("name");
+        a4.setNodeValue("4");
+        x4.setAttributeNode(a4);
+        
+        List result = xpath.selectNodes(doc);
+        assertEquals(8, result.size());
+        assertEquals(x1, result.get(0));   
+        assertEquals(a1, result.get(1));   
+        assertEquals(x2, result.get(2));   
+        assertEquals(a2, result.get(3));
+        assertEquals(x3, result.get(4));   
+        assertEquals(a3, result.get(5));   
+        assertEquals(x4, result.get(6));   
+        assertEquals(a4, result.get(7));
+        
+    }    
+    
+    public void testAncestorAxisWithAttributes() throws JaxenException {
+        
+        BaseXPath xpath = new DOMXPath("ancestor::*/@*");
+        org.w3c.dom.Element a = doc.createElementNS("", "a");
+        org.w3c.dom.Element b = doc.createElementNS("", "b");
+        doc.appendChild(a);
+        a.appendChild(b);
+        org.w3c.dom.Element x3 = doc.createElementNS("", "x");
+        b.appendChild(x3);
+        
+        Attr a1 = doc.createAttribute("name");
+        a1.setNodeValue("1");
+        a.setAttributeNode(a1);
+        Attr a2 = doc.createAttribute("name");
+        a2.setNodeValue("2");
+        b.setAttributeNode(a2);
+        Attr a3 = doc.createAttribute("name");
+        x3.setNodeValue("3");
+        x3.setAttributeNode(a3);
+        
+        List result = xpath.selectNodes(x3);
+        assertEquals(2, result.size());
+        assertEquals(a1, result.get(0));   
+        assertEquals(a2, result.get(1)); 
+        
+    }    
+    
+    // test for Jaxen-83
+    public void testPrincipalNodeTypeOfSelfAxisIsElement() throws JaxenException {
+        
+        BaseXPath xpath = new DOMXPath("child/@*[self::test]");
+        org.w3c.dom.Element a = doc.createElementNS("", "child");
+        org.w3c.dom.Attr test = doc.createAttributeNS("", "test");
+        test.setValue("value");
+        a.setAttributeNode(test);
+        doc.appendChild(a);
+        
+        List result = xpath.selectNodes(doc);
+        assertEquals(0, result.size()); 
+        
+    }
+    
+    // test to make sure Jaxen-83 fix doesn't go too far
+    public void testSelfAxisWithNodeTestCanReturnNonPrincipalNodeType() throws JaxenException {
+        
+        BaseXPath xpath = new DOMXPath("child/@*[self::node()]");
+        org.w3c.dom.Element a = doc.createElementNS("", "child");
+        org.w3c.dom.Attr test = doc.createAttributeNS("", "test");
+        test.setValue("value");
+        a.setAttributeNode(test);
+        doc.appendChild(a);
+        
+        List result = xpath.selectNodes(doc);
+        assertEquals(1, result.size());   
+        
+    } 
+    
+    // another Jaxen-55 test to try to pin down exactly what does
+    // and doesn't work
+    public void testDescendantOrSelfAxis() throws JaxenException {
+        
+        BaseXPath xpath = new DOMXPath("/descendant-or-self::x");
+        org.w3c.dom.Element a = doc.createElementNS("", "a");
+        org.w3c.dom.Element b = doc.createElementNS("", "b");
+        doc.appendChild(a);
+        org.w3c.dom.Element x1 = doc.createElementNS("", "x");
+        x1.appendChild(doc.createTextNode("1"));
+        a.appendChild(x1);
+        a.appendChild(b);
+        org.w3c.dom.Element x2 = doc.createElementNS("", "x");
+        org.w3c.dom.Element x3 = doc.createElementNS("", "x");
+        org.w3c.dom.Element x4 = doc.createElementNS("", "x");
+        a.appendChild(x4);
+        b.appendChild(x2);
+        b.appendChild(x3);
+        x2.appendChild(doc.createTextNode("2"));
+        x3.appendChild(doc.createTextNode("3"));
+        x4.appendChild(doc.createTextNode("4"));
+        
+        List result = xpath.selectNodes(doc);
+        assertEquals(4, result.size());
+        assertEquals(x1, result.get(0));   
+        assertEquals(x2, result.get(1));   
+        assertEquals(x3, result.get(2));   
+        assertEquals(x4, result.get(3));
+        
+    }    
+    
+    
+    public void testDuplicateNodes() throws JaxenException {
+        
+        BaseXPath xpath = new DOMXPath("//x | //*");
+        org.w3c.dom.Element a = doc.createElementNS("", "a");
+        org.w3c.dom.Element b = doc.createElementNS("", "b");
+        doc.appendChild(a);
+        org.w3c.dom.Element x1 = doc.createElementNS("", "x");
+        x1.appendChild(doc.createTextNode("1"));
+        a.appendChild(x1);
+        a.appendChild(b);
+        org.w3c.dom.Element x2 = doc.createElementNS("", "x");
+        org.w3c.dom.Element x3 = doc.createElementNS("", "x");
+        org.w3c.dom.Element x4 = doc.createElementNS("", "x");
+        a.appendChild(x4);
+        b.appendChild(x2);
+        b.appendChild(x3);
+        x2.appendChild(doc.createTextNode("2"));
+        x3.appendChild(doc.createTextNode("3"));
+        x4.appendChild(doc.createTextNode("4"));
+        
+        List result = xpath.selectNodes(doc);
+        assertEquals(6, result.size());
+        
+    }    
+       
+    public void testUnionOfNodesWithNonNodes() throws JaxenException {
+        
+        BaseXPath xpath = new DOMXPath("count(//*) | //x ");
+        org.w3c.dom.Element a = doc.createElementNS("", "a");
+        org.w3c.dom.Element b = doc.createElementNS("", "b");
+        doc.appendChild(a);
+        org.w3c.dom.Element x1 = doc.createElementNS("", "x");
+        x1.appendChild(doc.createTextNode("1"));
+        a.appendChild(x1);
+        a.appendChild(b);
+        org.w3c.dom.Element x2 = doc.createElementNS("", "x");
+        org.w3c.dom.Element x3 = doc.createElementNS("", "x");
+        org.w3c.dom.Element x4 = doc.createElementNS("", "x");
+        a.appendChild(x4);
+        b.appendChild(x2);
+        b.appendChild(x3);
+        x2.appendChild(doc.createTextNode("2"));
+        x3.appendChild(doc.createTextNode("3"));
+        x4.appendChild(doc.createTextNode("4"));
+        
+        try {
+            xpath.selectNodes(doc);
+            fail("Allowed union with non-node-set");
+        }
+        catch (JaxenException ex) {
+            assertNotNull(ex.getMessage());
+        }
+        
+    }    
+    
+    public void testUnionOfEmptyNodeSetWithNonNodes() throws JaxenException {
+        
+        BaseXPath xpath = new DOMXPath("//y | count(//*)");
+        org.w3c.dom.Element a = doc.createElementNS("", "a");
+        org.w3c.dom.Element b = doc.createElementNS("", "b");
+        doc.appendChild(a);
+        org.w3c.dom.Element x1 = doc.createElementNS("", "x");
+        x1.appendChild(doc.createTextNode("1"));
+        a.appendChild(x1);
+        a.appendChild(b);
+        org.w3c.dom.Element x2 = doc.createElementNS("", "x");
+        b.appendChild(x2);
+        x2.appendChild(doc.createTextNode("2"));
+        
+        try {
+            xpath.selectNodes(doc);
+            fail("Allowed union with non-node-set");
+        }
+        catch (JaxenException ex) {
+            assertNotNull(ex.getMessage());
+        }
+        
+    } 
+    
+    public void testSelectSingleNodeSelectsNothing() 
+      throws JaxenException {
+        
+        BaseXPath xpath = new DOMXPath("id('p1')");
+        org.w3c.dom.Element a = doc.createElementNS("", "a");
+        doc.appendChild(a);
+        Object result = xpath.selectSingleNode(doc);
+        assertNull(result);
+        
+    }  
+    
+    public void testSAXPathExceptionThrownFromConstructor() {
+        
+        System.setProperty( XPathReaderFactory.DRIVER_PROPERTY,
+                            "java.lang.String" );
+        
+        try {
+            new DOMXPath("id('p1')");
+        }
+        catch (JaxenException e) {
+            assertNotNull(e.getMessage());
+        }
+        finally {
+            System.setProperty( XPathReaderFactory.DRIVER_PROPERTY,
+                            "" );
+        }
+        
+    }  
+    
+    public void testBooleanValueOfEmptyNodeSetIsFalse() 
+      throws JaxenException {
+        
+        BaseXPath xpath = new DOMXPath("/b/c");
+        org.w3c.dom.Element a = doc.createElementNS("", "a");
+        doc.appendChild(a);
+        List result = xpath.selectNodes(doc);
+        assertTrue(! xpath.booleanValueOf(result));
+        
+    } 
+    
+    public void testAddNamespaceWithNonSimpleNamespaceContext() throws JaxenException {
+        
+        BaseXPath xpath = new DOMXPath("/b/c");
+        xpath.setNamespaceContext(new NamespaceContext() {
+
+            public String translateNamespacePrefixToUri(String prefix) {
+                return prefix;
+            }
+            
+        });
+        try {
+            xpath.addNamespace("pre", "foo");            
+            fail("Added namespace");
+        }
+        catch (JaxenException ex) {
+            assertNotNull(ex.getMessage());
+        }
+        
+    } 
+    
+    public void testDebug() throws JaxenException {
+        BaseXPath xpath = new DOMXPath("/b/c");
+        assertEquals(
+          "[(DefaultXPath): [(DefaultAbsoluteLocationPath): [(DefaultNameStep): b]/[(DefaultNameStep): c]]]", 
+          xpath.debug()
+        );
+        
+    } 
+    
+    public void testGetRootExpr() throws JaxenException {
+        BaseXPath xpath = new DOMXPath("/b/c");
+        assertTrue(xpath.getRootExpr() instanceof org.jaxen.expr.LocationPath);
+    } 
+    
+    public void testUnionUsesDocumentOrder() throws JaxenException {
+        
+        BaseXPath xpath = new DOMXPath("/descendant::x | /a | /a/b");
+        org.w3c.dom.Element a = doc.createElementNS("", "a");
+        org.w3c.dom.Element b = doc.createElementNS("", "b");
+        doc.appendChild(a);
+        org.w3c.dom.Element x1 = doc.createElementNS("", "x");
+        x1.appendChild(doc.createTextNode("1"));
+        a.appendChild(x1);
+        a.appendChild(b);
+        org.w3c.dom.Element x2 = doc.createElementNS("", "x");
+        org.w3c.dom.Element x3 = doc.createElementNS("", "x");
+        org.w3c.dom.Element x4 = doc.createElementNS("", "x");
+        a.appendChild(x4);
+        b.appendChild(x2);
+        b.appendChild(x3);
+        x2.appendChild(doc.createTextNode("2"));
+        x3.appendChild(doc.createTextNode("3"));
+        x4.appendChild(doc.createTextNode("4"));
+        
+        List result = xpath.selectNodes(doc);
+        assertEquals(6, result.size());
+        assertEquals(a, result.get(0));   
+        assertEquals(x1, result.get(1));   
+        assertEquals(b, result.get(2));   
+        assertEquals(x2, result.get(3));   
+        assertEquals(x3, result.get(4));   
+        assertEquals(x4, result.get(5));
+        
+    }
+    
+    public void testArithmeticAssociativity() throws JaxenException {
+        XPath xpath = new DOMXPath("2+1-1+1");
+        Double result = (Double) xpath.evaluate(doc);
+        assertEquals(3, result.intValue());
+    }
+    
+    public void testLogicalAssociativity() throws JaxenException {
+        XPath xpath = new DOMXPath("false() or true() and true() and false()");
+        Boolean result = (Boolean) xpath.evaluate(doc);
+        assertFalse(result.booleanValue());
+    }
+    
+    public void testRelationalAssociativity3() throws JaxenException {
+        XPath xpath = new DOMXPath("3 > 2 > 1");
+        Boolean result = (Boolean) xpath.evaluate(doc);
+        assertFalse(result.booleanValue());
+    }
+    
+    public void testRelationalAssociativity4() throws JaxenException {
+        XPath xpath = new DOMXPath("4 > 3 > 2 > 1");
+        Boolean result = (Boolean) xpath.evaluate(doc);
+        assertFalse(result.booleanValue());
+    }
+    
+    public void testRelationalGTAssociativity5() throws JaxenException {
+        XPath xpath = new DOMXPath("5 > 4 > 3 > 2 > 1");
+        Boolean result = (Boolean) xpath.evaluate(doc);
+        assertFalse(result.booleanValue());
+    }
+    
+    public void testRelationalLTAssociativity5() throws JaxenException {
+        XPath xpath = new DOMXPath("1 < 2 < 3 < 4 < 5");
+        Boolean result = (Boolean) xpath.evaluate(doc);
+        assertTrue(result.booleanValue());
+    }
+    
+    public void testRelationalLEAssociativity5() throws JaxenException {
+        XPath xpath = new DOMXPath("1 <= 2 <= 3 <= 4 <= 5");
+        Boolean result = (Boolean) xpath.evaluate(doc);
+        assertTrue(result.booleanValue());
+    }
+    
+    public void testRelationalGEAssociativity5() throws JaxenException {
+        XPath xpath = new DOMXPath("5 >= 4 >= 3 >= 2 >= 1");
+        Boolean result = (Boolean) xpath.evaluate(doc);
+        assertFalse(result.booleanValue());
+    }
+    
+    public void testRelationalGEAssociativity3() throws JaxenException {
+        XPath xpath = new DOMXPath("3 >= 2 >= 1");
+        Boolean result = (Boolean) xpath.evaluate(doc);
+        assertTrue(result.booleanValue());
+    }
+    
+    public void testRelationalGEAssociativity2() throws JaxenException {
+        XPath xpath = new DOMXPath("2 >= 1");
+        Boolean result = (Boolean) xpath.evaluate(doc);
+        assertTrue(result.booleanValue());
+    }
+    
+    public void testRelationalGEAssociativity4() throws JaxenException {
+        XPath xpath = new DOMXPath("4 >= 3 >= 2 >= 1");
+        Boolean result = (Boolean) xpath.evaluate(doc);
+        assertFalse(result.booleanValue());
+    }
+    
+    // This is the same test but with parentheses to make explicit
+    // how the previous test should be evaluated.
+    public void testRelationalAssociativity5P() throws JaxenException {
+        XPath xpath = new DOMXPath("((((5 > 4) > 3) > 2) > 1)");
+        Boolean result = (Boolean) xpath.evaluate(doc);
+        assertFalse(result.booleanValue());
+    }
+    
+    public void testInequalityAssociativity5() throws JaxenException {
+        XPath xpath = new DOMXPath("2 != 3 != 1 != 4 != 0");
+        Boolean result = (Boolean) xpath.evaluate(doc);
+        assertTrue(result.booleanValue());
+    }
+    
+    // This is the same test but with parentheses to make explicit
+    // how the previous test should be evaluated.
+    public void testInequalityAssociativity5P() throws JaxenException {
+        XPath xpath = new DOMXPath("(((2 != 3) != 1) != 4) != 0");
+        Boolean result = (Boolean) xpath.evaluate(doc);
+        assertTrue(result.booleanValue());
+    }
+    
+    public void testInequalityAssociativity5B() throws JaxenException {
+        XPath xpath = new DOMXPath("2 != 3 != 1 != 4 != 1");
+        Boolean result = (Boolean) xpath.evaluate(doc);
+        assertFalse(result.booleanValue());
+    }
+    
+    // This is the same test but with parentheses to make explicit
+    // how the previous test should be evaluated.
+    public void testInequalityAssociativity5BP() throws JaxenException {
+        XPath xpath = new DOMXPath("(((2 != 3) != 1) != 4) != 1");
+        Boolean result = (Boolean) xpath.evaluate(doc);
+        assertFalse(result.booleanValue());
+    }
+    
+    public void testEqualityAssociativity5() throws JaxenException {
+        XPath xpath = new DOMXPath("2 = 3 = 1 = 4 = 0");
+        Boolean result = (Boolean) xpath.evaluate(doc);
+        assertTrue(result.booleanValue());
+    }
+    
+    // This is the same test but with parentheses to make explicit
+    // how the previous test should be evaluated.
+    public void testEqualityAssociativity5P() throws JaxenException {
+        XPath xpath = new DOMXPath("(((2 = 3) = 1) = 4) = 0");
+        Boolean result = (Boolean) xpath.evaluate(doc);
+        assertTrue(result.booleanValue());
+    }
+    
+    public void testEqualityAssociativity5B() throws JaxenException {
+        XPath xpath = new DOMXPath("2 = 3 = 1 = 4 = 1");
+        Boolean result = (Boolean) xpath.evaluate(doc);
+        assertFalse(result.booleanValue());
+    }
+    
+    // This is the same test but with parentheses to make explicit
+    // how the previous test should be evaluated.
+    public void testEqualityAssociativity5BP() throws JaxenException {
+        XPath xpath = new DOMXPath("(((2 = 3) = 1) = 4) = 1");
+        Boolean result = (Boolean) xpath.evaluate(doc);
+        assertFalse(result.booleanValue());
+    }
+    
+    public void testMoreComplexArithmeticAssociativity() throws JaxenException {
+        XPath xpath = new DOMXPath("1+2+1-1+1");
+        Double result = (Double) xpath.evaluate(doc);
+        assertEquals(4, result.intValue());
+    }
+    
+    
+    public void testMostComplexArithmeticAssociativity() throws JaxenException {
+        XPath xpath = new DOMXPath("1+1+2+1-1+1");
+        Double result = (Double) xpath.evaluate(doc);
+        assertEquals(5, result.intValue());
+    }
+    
+    
+    public void testSimplerArithmeticAssociativity() throws JaxenException {
+        XPath xpath = new DOMXPath("1-1+1");
+        Double result = (Double) xpath.evaluate(doc);
+        assertEquals(1, result.intValue());
+    }
+    
+    
+    public void testNamespaceNodesComeBeforeAttributeNodesInDocumentOrder() throws JaxenException {
+        
+        org.w3c.dom.Element root = doc.createElementNS("http://www.example.org", "pre:b");
+        doc.appendChild(root);
+        root.setAttribute("name", "value");
+        XPath xpath = new DOMXPath("/*/attribute::* | /*/namespace::node()");
+        List result = xpath.selectNodes(doc);
+        assertTrue(((org.w3c.dom.Node) result.get(0)).getNodeType() == Pattern.NAMESPACE_NODE);
+        assertTrue(((org.w3c.dom.Node) result.get(1)).getNodeType() == Pattern.NAMESPACE_NODE);
+        assertTrue(((org.w3c.dom.Node) result.get(2)).getNodeType() == Node.ATTRIBUTE_NODE);
+        
+        // now flip the order of the statement and retest
+        xpath = new DOMXPath("/*/namespace::node() | /*/attribute::* ");
+        result = xpath.selectNodes(doc);
+        assertTrue(((org.w3c.dom.Node) result.get(0)).getNodeType() == Pattern.NAMESPACE_NODE);
+        assertTrue(((org.w3c.dom.Node) result.get(1)).getNodeType() == Pattern.NAMESPACE_NODE);
+        assertTrue(((org.w3c.dom.Node) result.get(2)).getNodeType() == Node.ATTRIBUTE_NODE);
+   
+    }
+
+    public void testJaxen97() throws JaxenException {
+        // jaxen 97 claims this expression throws an exception.
+        new DOMXPath("/aaa:element/text()");
+    }
+
+    public void testAttributeNodesOnParentComeBeforeNamespaceNodesInChildInDocumentOrder() 
+     throws JaxenException {
+        
+        org.w3c.dom.Element root = doc.createElement("root");
+        doc.appendChild(root);
+        root.setAttribute("name", "value");
+        Element child = doc.createElementNS("http://www.example.org", "pre:child");
+        root.appendChild(child);
+        
+        XPath xpath = new DOMXPath("/*/*/namespace::node() | //attribute::* ");
+        List result = xpath.selectNodes(doc);
+        assertEquals(3, result.size());
+        assertTrue(((org.w3c.dom.Node) result.get(0)).getNodeType() == Node.ATTRIBUTE_NODE);
+        assertTrue(((org.w3c.dom.Node) result.get(1)).getNodeType() == Pattern.NAMESPACE_NODE);
+   
+    }
+
+    public void testJaxen107() throws JaxenException {
+        
+        org.w3c.dom.Element a = doc.createElementNS("http://www.a.com/", "a:foo");
+        doc.appendChild(a);
+        Element b = doc.createElementNS("http://www.b.com/", "b:bar");
+        a.appendChild(b);
+        
+        XPath xpath = new DOMXPath("/a:foo/b:bar/namespace::*/parent::*");
+        SimpleNamespaceContext context1 = new SimpleNamespaceContext();
+        context1.addNamespace("a", "http://www.a.com/");
+        context1.addNamespace("b", "http://www.b.com/");
+        xpath.setNamespaceContext(context1);
+        List result = xpath.selectNodes(doc);
+        assertEquals(1, result.size());
+        assertEquals(b, result.get(0));
+   
+    }
+    
+    
+    public void testJaxen107FromFile() throws JaxenException, SAXException, IOException {
+        
+        doc = builder.parse(new File("xml/testNamespaces.xml"));
+        XPath xpath = new DOMXPath("/Template/Application2/namespace::*/parent::*");
+        List result = xpath.selectNodes(doc);
+        assertEquals(1, result.size());
+   
+    }
+    
+    public void testSelectNodesReturnsANonNodeSet() throws JaxenException {
+        XPath xpath = new DOMXPath("1 + 2 + 3");
+        List result = xpath.selectNodes(doc);
+        assertEquals(1, result.size());
+    }
+    
+    public void testNonElementContextNode() throws JaxenException {
+        
+        org.w3c.dom.Element a = doc.createElementNS("http://www.a.com/", "a:foo");
+        doc.appendChild(a);
+        Text b = doc.createTextNode("ready");
+        a.appendChild(b);
+        
+        XPath xpath = new DOMXPath("..");
+        List result = (List) xpath.evaluate(b);
+        assertEquals(1, result.size());
+        assertEquals(a, result.get(0));
+   
+    }
+    
+    public void testNonNodeContext() throws JaxenException {
+        
+        org.w3c.dom.Element a = doc.createElementNS("http://www.a.com/", "a:foo");
+        doc.appendChild(a);
+        Text b = doc.createTextNode("ready");
+        a.appendChild(b);
+        
+        XPath xpath = new DOMXPath("..");
+        try {
+            xpath.evaluate("String");
+            fail("Allowed String as context");
+        }
+        catch (ClassCastException ex) {
+            // success
+        }
+   
+    }
+    
+    public void testIsSerializable() throws JaxenException, IOException {
+        
+        BaseXPath path = new BaseXPath("//foo", new DocumentNavigator());
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        ObjectOutputStream oos = new ObjectOutputStream(out);
+        oos.writeObject(path);
+        oos.close();
+        assertTrue(out.toByteArray().length > 0);
+        
+    }
+    
+    
+    
+}
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/BooleanTest.java b/libjaxen-java/src/java/test/org/jaxen/test/BooleanTest.java
new file mode 100644
index 0000000..a63a2a0
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/BooleanTest.java
@@ -0,0 +1,211 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2005 Elliotte Rusty Harold.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+
+package org.jaxen.test;
+
+import java.util.List;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import junit.framework.TestCase;
+
+import org.jaxen.BaseXPath;
+import org.jaxen.FunctionCallException;
+import org.jaxen.JaxenException;
+import org.jaxen.dom.DOMXPath;
+import org.w3c.dom.Document;
+
+/**
+ * @author Elliotte Rusty Harold
+ *
+ */
+public class BooleanTest extends TestCase {
+
+    private Document doc;
+    
+    public void setUp() throws ParserConfigurationException
+    {
+        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        factory.setNamespaceAware(true);
+        DocumentBuilder builder = factory.newDocumentBuilder();
+        doc = builder.newDocument();
+    }
+
+
+    public BooleanTest(String name) {
+        super(name);
+    }
+
+    // test case for JAXEN-55
+    public void testNonEmptyNodeSetsAreTrue() 
+      throws JaxenException {
+        
+        BaseXPath xpath = new DOMXPath("boolean(//x)");
+        org.w3c.dom.Element a = doc.createElementNS("", "a");
+        org.w3c.dom.Element b = doc.createElementNS("", "b");
+        doc.appendChild(a);
+        a.appendChild(b);
+        org.w3c.dom.Element x2 = doc.createElementNS("", "x");
+        org.w3c.dom.Element x3 = doc.createElementNS("", "x");
+        org.w3c.dom.Element x4 = doc.createElementNS("", "x");
+        a.appendChild(x4);
+        b.appendChild(x2);
+        b.appendChild(x3);
+        x2.appendChild(doc.createTextNode("false"));
+        x3.appendChild(doc.createTextNode("false"));
+        x4.appendChild(doc.createTextNode("false"));
+        
+        List result = xpath.selectNodes(doc);
+        assertEquals(1, result.size());
+        assertEquals(Boolean.TRUE, result.get(0));
+        
+    }    
+
+    public void testEmptyNodeSetsAreFalse() 
+      throws JaxenException {
+        
+        BaseXPath xpath = new DOMXPath("boolean(//y)");
+        org.w3c.dom.Element a = doc.createElementNS("", "a");
+        org.w3c.dom.Element b = doc.createElementNS("", "b");
+        doc.appendChild(a);
+        a.appendChild(b);
+        org.w3c.dom.Element x2 = doc.createElementNS("", "x");
+        org.w3c.dom.Element x3 = doc.createElementNS("", "x");
+        org.w3c.dom.Element x4 = doc.createElementNS("", "x");
+        a.appendChild(x4);
+        b.appendChild(x2);
+        b.appendChild(x3);
+        x2.appendChild(doc.createTextNode("false"));
+        x3.appendChild(doc.createTextNode("false"));
+        x4.appendChild(doc.createTextNode("false"));
+        
+        List result = xpath.selectNodes(doc);
+        assertEquals(1, result.size());
+        assertEquals(Boolean.FALSE, result.get(0));
+        
+    }    
+
+    public void testZeroIsFalse() 
+      throws JaxenException {
+        
+        BaseXPath xpath = new DOMXPath("boolean(0)");
+        org.w3c.dom.Element a = doc.createElementNS("", "a");
+        
+        List result = xpath.selectNodes(a);
+        assertEquals(1, result.size());
+        assertEquals(Boolean.FALSE, result.get(0));
+        
+    }    
+
+    public void testEmptyStringIsFalse() 
+      throws JaxenException {
+        
+        BaseXPath xpath = new DOMXPath("boolean('')");
+        org.w3c.dom.Element a = doc.createElementNS("", "a");
+        
+        List result = xpath.selectNodes(a);
+        assertEquals(1, result.size());
+        assertEquals(Boolean.FALSE, result.get(0));
+        
+    }    
+
+    public void testNaNIsFalse() 
+      throws JaxenException {
+        
+        BaseXPath xpath = new DOMXPath("boolean(0 div 0)");
+        Object result = xpath.evaluate(null);
+        assertEquals(Boolean.FALSE, result);
+        
+    }    
+
+    public void testNonEmptyStringIsTrue() 
+      throws JaxenException {
+        
+        BaseXPath xpath = new DOMXPath("boolean('false')");
+        org.w3c.dom.Element a = doc.createElementNS("", "a");
+        
+        List result = xpath.selectNodes(a);
+        assertEquals(1, result.size());
+        assertEquals(Boolean.TRUE, result.get(0));
+        
+    }    
+
+    public void testBooleanFunctionRequiresOneArgument() 
+      throws JaxenException {
+        
+        BaseXPath xpath = new DOMXPath("boolean()");
+        org.w3c.dom.Element a = doc.createElementNS("", "a");
+        
+        try {
+            xpath.selectNodes(a);
+            fail("Allowed boolean function with no arguments");
+        }
+        catch (FunctionCallException ex) {
+            assertNotNull(ex.getMessage());
+        }
+        
+    }    
+
+    public void testBooleanFunctionRequiresExactlyOneArgument() 
+      throws JaxenException {
+        
+        BaseXPath xpath = new DOMXPath("boolean('', '')");
+        org.w3c.dom.Element a = doc.createElementNS("", "a");
+        
+        try {
+            xpath.selectNodes(a);
+            fail("Allowed boolean function with two arguments");
+        }
+        catch (FunctionCallException ex) {
+            assertNotNull(ex.getMessage());
+        }
+        
+    }    
+
+}
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/CeilingTest.java b/libjaxen-java/src/java/test/org/jaxen/test/CeilingTest.java
new file mode 100644
index 0000000..63878db
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/CeilingTest.java
@@ -0,0 +1,141 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2005 Elliotte Rusty Harold.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+
+package org.jaxen.test;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import junit.framework.TestCase;
+
+import org.jaxen.BaseXPath;
+import org.jaxen.FunctionCallException;
+import org.jaxen.JaxenException;
+import org.jaxen.dom.DOMXPath;
+import org.w3c.dom.Document;
+
+/**
+ * @author Elliotte Rusty Harold
+ *
+ */
+public class CeilingTest extends TestCase {
+
+    private Document doc;
+    
+    public void setUp() throws ParserConfigurationException
+    {
+        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        factory.setNamespaceAware(true);
+        DocumentBuilder builder = factory.newDocumentBuilder();
+        doc = builder.newDocument();
+        org.w3c.dom.Element a = doc.createElementNS("", "a");
+        doc.appendChild(a);
+    }
+
+
+    public CeilingTest(String name) {
+        super(name);
+    }
+
+
+
+    public void testCeiling() throws JaxenException {
+        
+        BaseXPath xpath = new DOMXPath("ceiling(1.5)");
+        
+        Object result = xpath.evaluate(doc);
+        assertEquals(2, ((Double) result).doubleValue(), 0.0001);
+        
+    }    
+
+    public void testNegativeCeiling() throws JaxenException {
+        
+        BaseXPath xpath = new DOMXPath("ceiling(-1.5)");
+        
+        Object result = xpath.evaluate(doc);
+        assertEquals(-1, ((Double) result).doubleValue(), 0.0001);
+        
+    }    
+
+    public void testNaNCeilingIsNaN() throws JaxenException {
+        BaseXPath xpath = new DOMXPath("ceiling(1.0 div 0.0 - 2.0 div 0.0)");
+        double result = ((Double) xpath.evaluate(doc)).doubleValue();
+        assertTrue(Double.isNaN(result));
+    }    
+
+    public void testCeilingFunctionRequiresAtLeastOneArgument() 
+      throws JaxenException {
+        
+        BaseXPath xpath = new DOMXPath("ceiling()");
+        
+        try {
+            xpath.selectNodes(doc);
+            fail("Allowed ceiling function with no arguments");
+        }
+        catch (FunctionCallException ex) {
+            assertNotNull(ex.getMessage());
+        }
+        
+    }    
+
+    public void testCeilingFunctionRequiresAtMostOneArgument() 
+      throws JaxenException {
+        
+        BaseXPath xpath = new DOMXPath("ceiling(2.2, 1.2)");
+        
+        try {
+            xpath.selectNodes(doc);
+            fail("Allowed ceiling function with two arguments");
+        }
+        catch (FunctionCallException ex) {
+            assertNotNull(ex.getMessage());
+        }
+        
+    }    
+
+}
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/ConcatTest.java b/libjaxen-java/src/java/test/org/jaxen/test/ConcatTest.java
new file mode 100644
index 0000000..98801db
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/ConcatTest.java
@@ -0,0 +1,99 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2005 Elliotte Rusty Harold.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+
+package org.jaxen.test;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import junit.framework.TestCase;
+
+import org.jaxen.BaseXPath;
+import org.jaxen.FunctionCallException;
+import org.jaxen.JaxenException;
+import org.jaxen.dom.DOMXPath;
+import org.w3c.dom.Document;
+
+/**
+ * @author Elliotte Rusty Harold
+ *
+ */
+public class ConcatTest extends TestCase {
+
+    private Document doc;
+    
+    public void setUp() throws ParserConfigurationException
+    {
+        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        factory.setNamespaceAware(true);
+        DocumentBuilder builder = factory.newDocumentBuilder();
+        doc = builder.newDocument();
+        doc.appendChild(doc.createElement("root"));
+    }
+
+
+    public ConcatTest(String name) {
+        super(name);
+    }
+
+    public void testConcatFunctionRequiresAtLeastTwoArguments() 
+      throws JaxenException {
+        
+        BaseXPath xpath = new DOMXPath("concat('a')");
+        
+        try {
+            xpath.selectNodes(doc);
+            fail("Allowed concat function with one argument");
+        }
+        catch (FunctionCallException ex) {
+            assertNotNull(ex.getMessage());
+        }
+        
+    } 
+
+}
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/ConformanceXPathHandler.java b/libjaxen-java/src/java/test/org/jaxen/test/ConformanceXPathHandler.java
new file mode 100644
index 0000000..29db94f
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/ConformanceXPathHandler.java
@@ -0,0 +1,327 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Jaxen Project and was originally
+ * created by bob mcwhirter <bob at werken.com> and
+ * James Strachan <jstrachan at apache.org>.  For more information on the
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ *
+ * $Id$
+ */
+
+
+
+
+package org.jaxen.test;
+
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.jaxen.saxpath.XPathHandler;
+
+class ConformanceXPathHandler implements XPathHandler
+{
+    private List events;
+
+    ConformanceXPathHandler()
+    {
+        this.events = new LinkedList();
+    }
+
+    public void startXPath()
+    {
+        addEvent( "startXPath()" );
+    }
+
+    public void endXPath()
+    {
+        addEvent( "endXPath()" );
+    }
+
+    public void startPathExpr()
+    {
+        addEvent( "startPathExpr()" );
+    }
+
+    public void endPathExpr()
+    {
+        addEvent( "endPathExpr()" );
+    }
+
+    public void startAbsoluteLocationPath()
+    {
+        addEvent( "startAbsoluteLocationPath()" );
+    }
+    public void endAbsoluteLocationPath()
+    {
+        addEvent( "endAbsoluteLocationPath()" );
+    }
+
+    public void startRelativeLocationPath()
+    {
+        addEvent( "startRelativeLocationPath()" );
+    }
+
+    public void endRelativeLocationPath()
+    {
+        addEvent( "endRelativeLocationPath()" );
+    }
+
+    public void startNameStep(int axis,
+                              String prefix,
+                              String localName)
+    {
+        addEvent( "startNameStep(" + axis + ", \"" + prefix + "\", \"" + localName + "\")" );
+    }
+
+    public void endNameStep()
+    {
+        addEvent( "endNameStep()" );
+    }
+
+    public void startTextNodeStep(int axis)
+    {
+        addEvent( "startTextNodeStep(" + axis + ")" );
+    }
+    public void endTextNodeStep()
+    {
+        addEvent( "endTextNodeStep()" );
+    }
+
+    public void startCommentNodeStep(int axis)
+    {
+        addEvent( "startCommentNodeStep(" + axis + ")" );
+    }
+
+    public void endCommentNodeStep()
+    {
+        addEvent( "endCommentNodeStep()" );
+    }
+
+    public void startAllNodeStep(int axis)
+    {
+        addEvent( "startAllNodeStep(" + axis + ")" );
+    }
+
+    public void endAllNodeStep()
+    {
+        addEvent( "endAllNodeStep()" );
+    }
+
+    public void startProcessingInstructionNodeStep(int axis,
+                                                   String name)
+    {
+        addEvent( "startProcessingInstructionNodeStep(" + axis + ", \"" + name + "\")" );
+    }
+    public void endProcessingInstructionNodeStep()
+    {
+        addEvent( "endProcessingInstructionNodeStep()" );
+    }
+
+    public void startPredicate()
+    {
+        addEvent( "startPredicate()" );
+    }
+
+    public void endPredicate()
+    {
+        addEvent( "endPredicate()" );
+    }
+
+    public void startFilterExpr()
+    {
+        addEvent( "startFilterExpr()" );
+    }
+
+    public void endFilterExpr()
+    {
+        addEvent( "endFilterExpr()" );
+    }
+
+    public void startOrExpr()
+    {
+        addEvent( "startOrExpr()" );
+    }
+
+    public void endOrExpr(boolean create)
+    {
+        addEvent( "endOrExpr(" + create + ")" );
+    }
+
+    public void startAndExpr()
+    {
+        addEvent( "startAndExpr()" );
+    }
+
+    public void endAndExpr(boolean create)
+    {
+        addEvent( "endAndExpr(" + create + ")" );
+    }
+
+    public void startEqualityExpr()
+    {
+        addEvent( "startEqualityExpr()" );
+    }
+
+    public void endEqualityExpr(int operator)
+    {
+        addEvent( "endEqualityExpr(" + operator + ")" );
+    }
+
+    public void startRelationalExpr()
+    {
+        addEvent( "startRelationalExpr()" );
+    }
+
+    public void endRelationalExpr(int operator)
+    {
+        addEvent( "endRelationalExpr(" + operator + ")" );
+    }
+
+    public void startAdditiveExpr()
+    {
+        addEvent( "startAdditiveExpr()" );
+    }
+
+    public void endAdditiveExpr(int operator)
+    {
+        addEvent( "endAdditiveExpr(" + operator + ")" );
+    }
+
+    public void startMultiplicativeExpr()
+    {
+        addEvent( "startMultiplicativeExpr()" );
+    }
+
+    public void endMultiplicativeExpr(int operator)
+    {
+        addEvent( "endMultiplicativeExpr(" + operator + ")" );
+    }
+
+    public void startUnaryExpr()
+    {
+        addEvent( "startUnaryExpr()" );
+    }
+
+    public void endUnaryExpr(int operator)
+    {
+        addEvent( "endUnaryExpr(" + operator + ")" );
+    }
+
+    public void startUnionExpr()
+    {
+        addEvent( "startUnionExpr()" );
+    }
+
+    public void endUnionExpr(boolean create)
+    {
+        addEvent( "endUnionExpr(" + create + ")" );
+    }
+
+    public void number(int number)
+    {
+        addEvent( "number(" + number + ")" );
+    }
+
+    public void number(double number)
+    {
+        addEvent( "number(" + number + ")" );
+    }
+
+    public void literal(String literal)
+    {
+        addEvent( "literal(\"" + literal + "\")" );
+    }
+
+    public void variableReference(String prefix,
+                                  String variableName)
+    {
+        addEvent( "variableReference(\"" + prefix + ":" + variableName + "\")" );
+    }
+
+    public void startFunction(String prefix,
+                              String functionName)
+    {
+        addEvent( "startFunction(\"" + prefix + ":" + functionName + "\")" );
+    }
+
+    public void endFunction()
+    {
+        addEvent( "endFunction()" );
+    }
+
+    private void addEvent(String eventStr)
+    {
+        this.events.add( eventStr );
+    }
+
+    public boolean equals(Object thatObj)
+    {
+        if ( thatObj instanceof ConformanceXPathHandler )
+        {
+            ConformanceXPathHandler that = (ConformanceXPathHandler) thatObj;
+
+            return ( this.events.equals( that.events ) );
+        }
+
+        return false;
+    }
+    
+    public int hashCode() {
+        return this.events.hashCode();
+    }
+    
+
+    public String toString()
+    {
+        Iterator eventIter = this.events.iterator();
+        int      i = 0;
+
+        StringBuffer buf = new StringBuffer();
+
+        while( eventIter.hasNext() )
+        {
+            buf.append("(").append(i).append(") ").append( eventIter.next().toString() ).append("\n");
+            ++i;
+        }
+
+        return buf.toString();
+    }
+}
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/ContainsTest.java b/libjaxen-java/src/java/test/org/jaxen/test/ContainsTest.java
new file mode 100644
index 0000000..cc79442
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/ContainsTest.java
@@ -0,0 +1,172 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2005 Elliotte Rusty Harold.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+
+package org.jaxen.test;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import junit.framework.TestCase;
+
+import org.jaxen.BaseXPath;
+import org.jaxen.FunctionCallException;
+import org.jaxen.JaxenException;
+import org.jaxen.XPath;
+import org.jaxen.dom.DOMXPath;
+import org.w3c.dom.Document;
+
+/**
+ * @author Elliotte Rusty Harold
+ *
+ */
+public class ContainsTest extends TestCase {
+
+    private Document doc;
+    
+    public void setUp() throws ParserConfigurationException
+    {
+        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        factory.setNamespaceAware(true);
+        DocumentBuilder builder = factory.newDocumentBuilder();
+        doc = builder.newDocument();
+        doc.appendChild(doc.createElement("root"));
+    }
+
+
+    public ContainsTest(String name) {
+        super(name);
+    }
+
+    public void testContainsNumber() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "contains(33, '3')" );
+        Boolean result = (Boolean) xpath.evaluate( doc );
+        assertEquals(Boolean.TRUE, result);
+    }    
+  
+    public void testContainsString() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "contains('test', 'es')" );
+        Boolean result = (Boolean) xpath.evaluate( doc );
+        assertEquals(Boolean.TRUE, result);
+    }    
+  
+    public void testContainsString3() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "contains('superlative', 'superlative')" );
+        Boolean result = (Boolean) xpath.evaluate( doc );
+        assertEquals(Boolean.TRUE, result);
+    }    
+  
+    public void testContainsNumber2() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "contains(43, '0')" );
+        Boolean result = (Boolean) xpath.evaluate( doc );
+        assertEquals(Boolean.FALSE, result);
+    }    
+  
+    public void testContainsString2() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "contains('1234567890', '1234567a')" );
+        Boolean result = (Boolean) xpath.evaluate( doc );
+        assertEquals(Boolean.FALSE, result);
+    }    
+  
+  
+    public void testEmptyStringContainsNonEmptyString() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "contains('', 'a')" );
+        Boolean result = (Boolean) xpath.evaluate( doc );
+        assertEquals(Boolean.FALSE, result);
+    }
+  
+    public void testEmptyStringContainsEmptyString() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "contains('', '')" );
+        Boolean result = (Boolean) xpath.evaluate( doc );
+        assertEquals(Boolean.TRUE, result);
+    }
+  
+    public void testContainsEmptyString() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "contains('a', '')" );
+        Boolean result = (Boolean) xpath.evaluate( doc );
+        assertEquals(Boolean.TRUE, result);
+    }    
+  
+    public void testContainsFunctionRequiresAtLeastTwoArguments() 
+      throws JaxenException {
+        
+        BaseXPath xpath = new DOMXPath("contains('a')");
+        
+        try {
+            xpath.selectNodes(doc);
+            fail("Allowed contains function with one argument");
+        }
+        catch (FunctionCallException ex) {
+            assertNotNull(ex.getMessage());
+        }
+        
+    }    
+
+    public void testContainsFunctionRequiresAtMostTwoArguments() 
+      throws JaxenException {
+        
+        BaseXPath xpath = new DOMXPath("contains('a', 'a', 'a')");
+        
+        try {
+            xpath.selectNodes(doc);
+            fail("Allowed contains function with three arguments");
+        }
+        catch (FunctionCallException ex) {
+            assertNotNull(ex.getMessage());
+        }
+        
+    }    
+
+}
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/ContextTest.java b/libjaxen-java/src/java/test/org/jaxen/test/ContextTest.java
new file mode 100644
index 0000000..4378d0b
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/ContextTest.java
@@ -0,0 +1,173 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+
+
+package org.jaxen.test;
+
+import junit.framework.TestCase;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectOutputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.jaxen.Context;
+import org.jaxen.ContextSupport;
+import org.jaxen.JaxenException;
+import org.jaxen.XPath;
+import org.jaxen.dom.DOMXPath;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.xml.sax.SAXException;
+
+public class ContextTest extends TestCase
+{
+    private List           nodeSet;
+    private ContextSupport support;
+
+    public ContextTest(String name)
+    {
+        super( name );
+    }
+
+    public void setUp()
+    {
+        this.nodeSet = new ArrayList();
+
+        this.nodeSet.add( "one" );
+        this.nodeSet.add( "two" );
+        this.nodeSet.add( "three" );
+        this.nodeSet.add( "four" );
+
+        this.support = new ContextSupport();
+    }
+
+    public void tearDown()
+    {
+        this.nodeSet = null;
+    }
+
+    public void testDuplicate()
+    {
+        Context original = new Context( this.support );
+
+        original.setNodeSet( this.nodeSet );
+
+        original.setSize( 4 );
+        original.setPosition( 2 );
+
+        Context dupe = original.duplicate();
+
+        assertTrue( original != dupe );
+
+        List dupeNodeSet = dupe.getNodeSet();
+
+        assertTrue( original.getNodeSet() != dupe.getNodeSet() );
+
+        dupeNodeSet.clear();
+
+        assertSame( dupeNodeSet,
+                    dupe.getNodeSet() );
+
+        assertEquals( 0,
+                      dupe.getNodeSet().size() );
+
+
+        assertEquals( 4,
+                      original.getNodeSet().size() );
+
+        dupe.setSize( 0 );
+        dupe.setPosition( 0 );
+
+        assertEquals( 0,
+                      dupe.getSize() );
+
+        assertEquals( 0,
+                      dupe.getPosition() );
+
+        assertEquals( 4,
+                      original.getSize() );
+
+        assertEquals( 2,
+                      original.getPosition() );
+    }
+
+    public void testXMLPrefixIsAlwaysBound() 
+      throws ParserConfigurationException, SAXException, IOException, JaxenException
+    {  
+
+       DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+       factory.setNamespaceAware(true);
+       DocumentBuilder builder = factory.newDocumentBuilder();
+       Document doc = builder.parse( "xml/basic.xml" );
+       Element root = doc.getDocumentElement();
+       root.setAttributeNS("http://www.w3.org/XML/1998/namespace", "xml:lang", "en");
+       XPath xpath = new DOMXPath( "/*/@xml:lang" );
+       List result = xpath.selectNodes( doc );
+       assertEquals(1, result.size());
+
+    }    
+
+    
+    public void testIsSerializable() throws IOException {
+
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        ObjectOutputStream oos = new ObjectOutputStream(out);
+        oos.writeObject(support);
+        oos.close();
+        assertTrue(out.toByteArray().length > 0);
+        
+    }    
+    
+    
+}
+
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/CoreTests.java b/libjaxen-java/src/java/test/org/jaxen/test/CoreTests.java
new file mode 100644
index 0000000..2ec7b75
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/CoreTests.java
@@ -0,0 +1,95 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2005 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+
+
+package org.jaxen.test;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+/**
+ * <p>
+ *   Collect the org.jaxen. tests.
+ * </p>
+ * 
+ * @author Elliotte Rusty Harold
+ * @version 1.1b9
+ *
+ */
+public class CoreTests extends TestCase {
+
+    
+    public CoreTests(String name) {
+        super(name);   
+    }
+
+    
+    public static Test suite() {
+        
+        TestSuite result = new TestSuite();
+        result.addTest(new TestSuite(AddNamespaceTest.class));
+        result.addTest(new TestSuite(BaseXPathTest.class));
+        result.addTest(new TestSuite(FunctionContextTest.class));
+        result.addTest(new TestSuite(SimpleNamespaceContextTest.class));
+        result.addTest(new TestSuite(ContextTest.class));
+        result.addTest(new TestSuite(JaxenHandlerTest.class));
+        result.addTest(new TestSuite(JaxenRuntimeExceptionTest.class));
+        result.addTest(new TestSuite(FunctionCallExceptionTest.class));
+        result.addTest(new TestSuite(UnresolvableExceptionTest.class));
+        result.addTest(new TestSuite(VariableContextTest.class));
+        result.addTest(new TestSuite(SimpleNamespaceContextTest.class));
+        result.addTest(new TestSuite(XPathSyntaxExceptionTest.class));
+        result.addTest(new TestSuite(UnsupportedAxisExceptionTest.class));
+        result.addTest(new TestSuite(JaxenExceptionTest.class));
+        result.addTest(new TestSuite(ArithmeticTest.class));
+        return result;
+        
+    }
+
+    
+}
\ No newline at end of file
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/CountTest.java b/libjaxen-java/src/java/test/org/jaxen/test/CountTest.java
new file mode 100644
index 0000000..aa88c86
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/CountTest.java
@@ -0,0 +1,146 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+
+package org.jaxen.test;
+
+import java.io.IOException;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import junit.framework.TestCase;
+
+import org.jaxen.BaseXPath;
+import org.jaxen.FunctionCallException;
+import org.jaxen.JaxenException;
+import org.jaxen.XPath;
+import org.jaxen.dom.DOMXPath;
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+/**
+ * @author Elliotte Rusty Harold
+ *
+ */
+public class CountTest extends TestCase {
+
+    private Document doc;
+    
+    public void setUp() throws ParserConfigurationException, SAXException, IOException
+    {
+        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        factory.setNamespaceAware(true);
+        DocumentBuilder builder = factory.newDocumentBuilder();
+        doc = builder.parse( "xml/basic.xml" );
+    }
+
+
+    public CountTest(String name) {
+        super(name);
+    }
+
+    public void testCount3()
+    {
+        try
+        {
+            XPath xpath = new DOMXPath( "count(3)" );
+            xpath.selectNodes( doc );
+            fail("Allowed count of number");
+       }
+       catch (FunctionCallException e) 
+        {
+           assertEquals("count() function can only be used for node-sets", e.getMessage());
+        }
+       catch (Exception e)
+        {
+            e.printStackTrace();
+            fail( e.getMessage() );
+        }
+    }    
+    
+    public void testCountFunctionRequiresAtLeastOneArgument() 
+      throws JaxenException {
+        
+        BaseXPath xpath = new DOMXPath("count()");
+        
+        try {
+            xpath.selectNodes(doc);
+            fail("Allowed count function with no arguments");
+        }
+        catch (FunctionCallException ex) {
+            assertNotNull(ex.getMessage());
+        }
+        
+    }    
+
+    public void testCountFunctionRequiresAtMostOneArgument() 
+      throws JaxenException {
+        
+        BaseXPath xpath = new DOMXPath("count(/*, /@*)");
+        
+        try {
+            xpath.selectNodes(doc);
+            fail("Allowed count function with two arguments");
+        }
+        catch (FunctionCallException ex) {
+            assertNotNull(ex.getMessage());
+        }
+        
+    } 
+    
+    public void testCountRootElement() 
+      throws JaxenException {
+        
+        BaseXPath xpath = new DOMXPath("count(/*)");
+        Double result = (Double) xpath.evaluate(doc);
+        assertEquals(1.0, result.doubleValue(), 0.00001);
+        
+    }  
+    
+    
+}
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/DOM3NamespaceTest.java b/libjaxen-java/src/java/test/org/jaxen/test/DOM3NamespaceTest.java
new file mode 100644
index 0000000..b7f111f
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/DOM3NamespaceTest.java
@@ -0,0 +1,130 @@
+/* $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2005 Elliotte Rusty Harold.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+package org.jaxen.test;
+
+import java.util.Iterator;
+import java.util.List;
+
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.jaxen.*;
+import org.jaxen.dom.DOMXPath;
+import org.jaxen.dom.NamespaceNode;
+import org.w3c.dom.*;
+
+import junit.framework.TestCase;
+
+public class DOM3NamespaceTest extends TestCase {
+    
+    
+    private NamespaceNode xmlNS;
+    private NamespaceNode rootNS;
+    private NamespaceNode attributeNS;
+    
+
+    public DOM3NamespaceTest(String name) {
+        super(name);
+    }
+    
+    protected void setUp() throws ParserConfigurationException, JaxenException {
+        
+        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        factory.setNamespaceAware(true);
+        Document doc = factory.newDocumentBuilder().newDocument();
+        org.w3c.dom.Element root = doc.createElementNS("http://www.root.com/", "root");
+        doc.appendChild(root);
+        Attr a = doc.createAttributeNS("http://www.example.org/", "pre:a");
+        a.setNodeValue("value");
+        root.setAttributeNode(a);
+        
+        XPath xpath = new DOMXPath("namespace::node()");
+        List result = xpath.selectNodes(root);
+        
+        Iterator iterator = result.iterator();
+        while (iterator.hasNext()) {
+            NamespaceNode node = (NamespaceNode) iterator.next();
+            if (node.getLocalName() == null) rootNS = node;
+            else if (node.getLocalName().equals("xml")) xmlNS = node;
+            else if (node.getLocalName().equals("pre")) attributeNS = node;
+        }
+        
+    }     
+    
+    
+    public void testGetTextContent() {
+        assertEquals("http://www.w3.org/XML/1998/namespace", xmlNS.getTextContent());
+    }
+    
+    public void testSetTextContent() {
+        
+        try {
+            rootNS.setTextContent("http://www.a.com");
+            fail("set text content");
+        }
+        catch (DOMException ex) {
+            assertEquals(DOMException.NO_MODIFICATION_ALLOWED_ERR, ex.code);
+        }
+    }
+    
+    
+    public void testGetFeature() {
+        assertNull(attributeNS.getFeature("name", "value"));
+    }
+    
+    
+    // XXX need to distinguish these two cases
+    public void testIsEqualNode() {
+        assertFalse(rootNS.isEqualNode(xmlNS));
+        assertTrue(rootNS.isEqualNode(rootNS));
+    }
+    
+    public void testIsSameNode() {
+        assertFalse(rootNS.isSameNode(xmlNS));
+        assertTrue(rootNS.isSameNode(rootNS));
+    }
+    
+}
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/DOM4JNavigatorTest.java b/libjaxen-java/src/java/test/org/jaxen/test/DOM4JNavigatorTest.java
new file mode 100644
index 0000000..fc48f94
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/DOM4JNavigatorTest.java
@@ -0,0 +1,111 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+
+
+package org.jaxen.test;
+
+import java.util.Iterator;
+
+import org.dom4j.Document;
+import org.dom4j.DocumentHelper;
+import org.dom4j.io.SAXReader;
+import org.jaxen.FunctionCallException;
+import org.jaxen.JaxenException;
+import org.jaxen.Navigator;
+import org.jaxen.UnsupportedAxisException;
+import org.jaxen.XPath;
+import org.jaxen.dom4j.DocumentNavigator;
+import org.jaxen.dom4j.Dom4jXPath;
+
+public class DOM4JNavigatorTest extends XPathTestBase
+{
+    private SAXReader reader; 
+
+    public DOM4JNavigatorTest(String name)
+    {
+        super( name );
+        this.reader = new SAXReader();
+        this.reader.setMergeAdjacentText( true );
+    }
+    
+    public Navigator getNavigator()
+    {
+        return new DocumentNavigator();
+    }
+
+    public Object getDocument(String url) throws Exception
+    {
+        return reader.read( url );
+    }
+    
+    /**
+     * reported as JAXEN-104.
+     * @throws FunctionCallException
+     * @throws UnsupportedAxisException
+     */
+    public void testConcurrentModification() throws FunctionCallException, UnsupportedAxisException
+    {
+        Navigator nav = new DocumentNavigator();
+        Object document = nav.getDocument("xml/testNamespaces.xml");
+        Iterator descendantOrSelfAxisIterator = nav.getDescendantOrSelfAxisIterator(document);
+        while (descendantOrSelfAxisIterator.hasNext()) {
+            Object node = descendantOrSelfAxisIterator.next();
+            Iterator namespaceAxisIterator = nav.getNamespaceAxisIterator(node);
+            while (namespaceAxisIterator.hasNext()) {
+                namespaceAxisIterator.next();
+            }
+        }
+    }
+    
+    public void testNullPointerException() throws JaxenException {
+        Document doc = DocumentHelper.createDocument();
+        XPath xpath = new Dom4jXPath("/foo");
+        xpath.selectSingleNode(doc);
+    }    
+    
+    
+}
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/DOM4JPerformance.java b/libjaxen-java/src/java/test/org/jaxen/test/DOM4JPerformance.java
new file mode 100644
index 0000000..44c9edc
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/DOM4JPerformance.java
@@ -0,0 +1,68 @@
+/*
+ $Id$
+
+ Copyright 2003 The Werken Company. All Rights Reserved.
+ 
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+  * Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+
+  * Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+
+  * Neither the name of the Jaxen Project nor the names of its
+    contributors may be used to endorse or promote products derived 
+    from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ */
+package org.jaxen.test;
+
+import java.net.URL;
+
+import org.dom4j.Document;
+import org.dom4j.Element;
+import org.dom4j.io.SAXReader;
+import org.jaxen.dom4j.Dom4jXPath;
+
+class DOM4JPerformance {
+    
+    public static void main(String[] args) {
+        try {
+            URL u = new URL("http://www.ibiblio.org/xml/examples/shakespeare/much_ado.xml");
+            Document doc = new SAXReader().read(u);
+            Dom4jXPath xpath = new Dom4jXPath("PLAY/ACT/SCENE/SPEECH/SPEAKER");
+            
+            long start = System.currentTimeMillis();
+            
+            int count = 0;
+            for (int i = 0; i < 1000; i++) {
+                Element speaker = (Element) xpath.selectSingleNode(doc);
+                count += (speaker == null ? 0 : 1);
+            }
+            
+            long end = System.currentTimeMillis();
+            System.out.println((end - start));
+            System.out.println(count);
+            
+        } catch (Exception ex) {
+            ex.printStackTrace();
+        }
+    }
+    
+}
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/DOM4JTests.java b/libjaxen-java/src/java/test/org/jaxen/test/DOM4JTests.java
new file mode 100644
index 0000000..722b889
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/DOM4JTests.java
@@ -0,0 +1,75 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2005 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+
+
+package org.jaxen.test;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+/**
+ * <p>
+ *   Collect Jaxen's dom4j tests.
+ * </p>
+ * 
+ * @author Elliotte Rusty Harold
+ * @version 1.1b9
+ *
+ */
+public class DOM4JTests {
+
+    
+    public static Test suite() {
+        
+        TestSuite result = new TestSuite();
+        result.addTest(new TestSuite(DOM4JNavigatorTest.class));
+        result.addTest(new TestSuite(DOM4JXPathTest.class));
+        return result;
+        
+    }
+
+}
\ No newline at end of file
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/DOM4JXPathTest.java b/libjaxen-java/src/java/test/org/jaxen/test/DOM4JXPathTest.java
new file mode 100644
index 0000000..cd02181
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/DOM4JXPathTest.java
@@ -0,0 +1,187 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2003 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+
+
+package org.jaxen.test;
+
+import junit.framework.TestCase;
+
+import java.io.StringReader;
+import java.util.Iterator;
+import java.util.List;
+
+import org.dom4j.Attribute;
+import org.dom4j.Document;
+import org.dom4j.DocumentException;
+import org.dom4j.Element;
+import org.dom4j.Namespace;
+import org.dom4j.io.SAXReader;
+import org.dom4j.tree.DefaultAttribute;
+import org.dom4j.tree.DefaultDocument;
+import org.dom4j.tree.DefaultElement;
+import org.jaxen.JaxenException;
+import org.jaxen.XPath;
+import org.jaxen.XPathSyntaxException;
+import org.jaxen.dom4j.Dom4jXPath;
+import org.jaxen.saxpath.helpers.XPathReaderFactory;
+
+public class DOM4JXPathTest extends TestCase
+{
+
+    private static final String BASIC_XML = "xml/basic.xml";
+    
+    public DOM4JXPathTest(String name)
+    {
+        super( name );
+    }
+
+    public void setUp()
+    {
+        System.setProperty( XPathReaderFactory.DRIVER_PROPERTY,
+                            "" );
+    }
+
+    public void testConstruction() throws JaxenException
+    {
+        new Dom4jXPath( "/foo/bar/baz" );
+    }
+
+    public void testSelection() throws JaxenException, DocumentException
+    {
+
+        XPath xpath = new Dom4jXPath( "/foo/bar/baz" );
+        SAXReader reader = new SAXReader();
+        Document doc = reader.read( BASIC_XML );
+        List results = xpath.selectNodes( doc );
+        assertEquals( 3, results.size() );
+        Iterator iter = results.iterator();
+        assertEquals( "baz",
+                      ((Element)iter.next()).getName() );
+        assertEquals( "baz",
+                      ((Element)iter.next()).getName() );
+        assertEquals( "baz",
+                      ((Element)iter.next()).getName() );
+        assertTrue( ! iter.hasNext() );
+
+    }
+    
+    public void testAsBoolean() throws JaxenException, DocumentException
+    {
+        XPath xpath = new Dom4jXPath( "/root/a = 'a'" );
+        SAXReader reader = new SAXReader();
+        Document doc = reader.read( "xml/simple.xml" );
+        boolean answer = xpath.booleanValueOf( doc );
+        assertTrue( "Xpath worked: " + xpath, answer );
+        xpath = new Dom4jXPath( "'a' = 'b'" );
+        answer = xpath.booleanValueOf( doc );
+        assertTrue( "XPath should return false: " + xpath, ! answer );
+    }
+    
+    public void testJaxen20AttributeNamespaceNodes() throws JaxenException
+    {
+
+        Namespace ns1 = Namespace.get("p1", "www.acme1.org");
+        Namespace ns2 = Namespace.get("p2", "www.acme2.org");
+        Element element = new DefaultElement("test", ns1);
+        Attribute attribute = new DefaultAttribute("pre:foo", "bar", ns2);
+        element.add(attribute); 
+        Document doc = new DefaultDocument(element);
+        
+        XPath xpath = new Dom4jXPath( "//namespace::node()" );
+        List results = xpath.selectNodes( doc );
+        assertEquals( 3, results.size() );
+
+    }
+    
+    public void testJaxen16() throws JaxenException, DocumentException
+    {
+
+        String document = "<a xmlns:b=\"...\"/>";
+        SAXReader reader = new SAXReader();
+        Document doc = reader.read( new StringReader(document) );
+        
+        XPath xpath = new Dom4jXPath( "/a/b" );
+        List results = xpath.selectNodes( doc );
+        assertEquals( 0, results.size() );
+
+    }
+    
+    public void testNamespaceNodesAreInherited() throws JaxenException
+    {
+            Namespace ns0 = Namespace.get("p0", "www.acme0.org");
+            Namespace ns1 = Namespace.get("p1", "www.acme1.org");
+            Namespace ns2 = Namespace.get("p2", "www.acme2.org");
+            Element element = new DefaultElement("test", ns1);
+            Attribute attribute = new DefaultAttribute("pre:foo", "bar", ns2);
+            element.add(attribute);
+            Element root = new DefaultElement("root", ns0);
+            root.add(element);
+            Document doc = new DefaultDocument(root);
+            
+            XPath xpath = new Dom4jXPath( "/*/*/namespace::node()" );
+
+            List results = xpath.selectNodes( doc );
+
+            assertEquals( 4,
+                          results.size() );
+    }
+    
+    public void testSyntaxException() throws JaxenException {
+        
+        String path = "/row/[some_node='val1']|[some_node='val2']";
+        try {
+            new Dom4jXPath(path);
+            fail("Allowed union of non-node-sets");
+        }
+        catch (XPathSyntaxException success) {
+            assertNotNull(success.getMessage());
+        }
+        
+    }
+    
+    
+}
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/DOMNavigatorTest.java b/libjaxen-java/src/java/test/org/jaxen/test/DOMNavigatorTest.java
new file mode 100644
index 0000000..7d249f1
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/DOMNavigatorTest.java
@@ -0,0 +1,163 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+
+
+package org.jaxen.test;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.jaxen.Navigator;
+import org.jaxen.dom.DocumentNavigator;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+public class DOMNavigatorTest extends XPathTestBase
+{    
+    
+    private DocumentBuilder builder;
+    
+    
+    public DOMNavigatorTest(String name)
+    {
+        super( name );
+    }
+    
+    public Navigator getNavigator()
+    {
+        return new DocumentNavigator();
+    }
+    
+    protected void setUp() throws Exception {
+        super.setUp();
+        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        factory.setNamespaceAware(true);
+        builder = factory.newDocumentBuilder();
+    }
+
+    public Object getDocument(String url) throws Exception
+    {
+        return builder.parse( url );
+    }
+    
+    public void testGetAttributeQNameOnElement() {
+        Navigator nav = getNavigator();
+        Document doc = builder.newDocument();
+        Element a = doc.createElement("a");
+        String qname = nav.getAttributeQName(a);
+        assertNull(qname);
+    }
+    
+    public void testGetElementQNameOnAttr() {
+        Navigator nav = getNavigator();
+        Document doc = builder.newDocument();
+        Attr a = doc.createAttribute("a");
+        String qname = nav.getElementQName(a);
+        assertNull(qname);
+    }
+    
+    public void testGetAttributeLocalNameOnElement() {
+        Navigator nav = getNavigator();
+        Document doc = builder.newDocument();
+        Element a = doc.createElementNS("http://www.ex.com", "pre:a");
+        String name = nav.getAttributeName(a);
+        assertNull(name);
+    }
+    
+    public void testGetElementLocalNameOnAttr() {
+        Navigator nav = getNavigator();
+        Document doc = builder.newDocument();
+        Attr a = doc.createAttributeNS("http://www.ex.com", "a");
+        String name = nav.getElementName(a);
+        assertNull(name);
+    }
+    
+    public void testGetAttributeNamespaceURIOnElement() {
+        Navigator nav = getNavigator();
+        Document doc = builder.newDocument();
+        Element a = doc.createElementNS("http://www.example.org/", "a");
+        String qname = nav.getAttributeNamespaceUri(a);
+        assertNull(qname);
+    }
+    
+    public void testGetElementNamespaceURIOnAttr() {
+        Navigator nav = getNavigator();
+        Document doc = builder.newDocument();
+        Attr a = doc.createAttributeNS("http://www.element.org/", "a");
+        String qname = nav.getElementNamespaceUri(a);
+        assertNull(qname);
+    }
+    
+    public void testGetTargetOfNonPI() {
+        Navigator nav = getNavigator();
+        Document doc = builder.newDocument();
+        Attr a = doc.createAttributeNS("http://www.element.org/", "a");
+        try {
+            nav.getProcessingInstructionTarget(a);
+            fail("got target of non processing instruction");
+        }
+        catch (ClassCastException ex) {
+            assertNotNull(ex.getMessage());
+        }
+    }
+    
+    public void testGetDataOfNonPI() {
+        Navigator nav = getNavigator();
+        Document doc = builder.newDocument();
+        Attr a = doc.createAttributeNS("http://www.element.org/", "a");
+        try {
+            nav.getProcessingInstructionData(a);
+            fail("got data of non processing instruction");
+        }
+        catch (ClassCastException ex) {
+            assertNotNull(ex.getMessage());
+        }
+    }
+    
+    
+}
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/DOMTests.java b/libjaxen-java/src/java/test/org/jaxen/test/DOMTests.java
new file mode 100644
index 0000000..971137b
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/DOMTests.java
@@ -0,0 +1,78 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2005 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+
+
+package org.jaxen.test;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+/**
+ * <p>
+ *   Collect Jaxen's DOM tests.
+ * </p>
+ * 
+ * @author Elliotte Rusty Harold
+ * @version 1.1b9
+ *
+ */
+public class DOMTests {
+
+    
+    public static Test suite() {
+        
+        TestSuite result = new TestSuite();
+        result.addTest(new TestSuite(DOMNavigatorTest.class));
+        result.addTest(new TestSuite(DOMXPathTest.class));
+        result.addTest(new TestSuite(NamespaceTest.class));
+        result.addTest(new TestSuite(DOM3NamespaceTest.class));
+        return result;
+        
+    }
+
+    
+}
\ No newline at end of file
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/DOMXPathTest.java b/libjaxen-java/src/java/test/org/jaxen/test/DOMXPathTest.java
new file mode 100644
index 0000000..4e038d1
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/DOMXPathTest.java
@@ -0,0 +1,297 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2003 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+
+
+package org.jaxen.test;
+
+import junit.framework.TestCase;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.List;
+
+import org.jaxen.JaxenException;
+import org.jaxen.XPath;
+import org.jaxen.dom.DOMXPath;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.xml.sax.SAXException;
+
+public class DOMXPathTest extends TestCase
+{
+
+    private static final String BASIC_XML = "xml/basic.xml";
+    private Document doc;
+    private DocumentBuilderFactory factory;
+
+    public DOMXPathTest(String name)
+    {
+        super( name );
+    }
+    
+    public void setUp() throws ParserConfigurationException {
+        factory = DocumentBuilderFactory.newInstance();
+        factory.setNamespaceAware(true);
+        doc = factory.newDocumentBuilder().newDocument();        
+    }
+    
+
+    public void testConstruction() throws JaxenException
+    {
+        DOMXPath xpath = new DOMXPath( "/foo/bar/baz" );
+        assertEquals("/foo/bar/baz", xpath.toString());
+    }
+    
+    public void testConstructionWithNamespacePrefix() throws JaxenException
+    {
+        DOMXPath xpath = new DOMXPath( "/p:foo/p:bar/a:baz" );
+        assertEquals("/p:foo/p:bar/a:baz", xpath.toString());
+    }
+    
+    public void testNamespaceDeclarationsAreNotAttributes() 
+      throws JaxenException {
+        
+        Element root = doc.createElementNS("http://www.example.org/", "root");
+        doc.appendChild(root);
+        root.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns", "http://www.example.org/");
+        
+        DOMXPath xpath = new DOMXPath( "count(/*/@*)" );
+        
+        Number value = xpath.numberValueOf(doc);
+        assertEquals(0, value.intValue());
+        
+    }
+
+    
+    // see JAXEN-105
+    public void testConsistentNamespaceDeclarations() 
+      throws JaxenException {
+        
+        Element root = doc.createElement("root");
+        doc.appendChild(root);
+        Element child = doc.createElementNS("http://www.example.org", "foo:child");
+        root.appendChild(child);
+        // different prefix
+        child.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:foo2", "http://www.contradictory.org");
+        
+        XPath xpath = new DOMXPath("//namespace::node()");
+        List result = xpath.selectNodes(doc);
+        assertEquals(4, result.size());
+        
+    }
+
+    // see JAXEN-105
+    public void testInconsistentNamespaceDeclarations() 
+      throws JaxenException {
+        
+        Element root = doc.createElement("root");
+        doc.appendChild(root);
+        Element child = doc.createElementNS("http://www.example.org", "foo:child");
+        root.appendChild(child);
+        // same prefix
+        child.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:foo", "http://www.contradictory.org");
+        
+        XPath xpath = new DOMXPath("//namespace::node()");
+        List result = xpath.selectNodes(doc);
+        assertEquals(3, result.size());
+        
+    }
+
+    // see JAXEN-105
+    public void testIntrinsicNamespaceDeclarationOfElementBeatsContradictoryXmlnsPreAttr() 
+      throws JaxenException {
+        
+        Element root = doc.createElement("root");
+        doc.appendChild(root);
+        Element child = doc.createElementNS("http://www.example.org", "foo:child");
+        root.appendChild(child);
+        // same prefix
+        child.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:foo", "http://www.contradictory.org");
+        
+        XPath xpath = new DOMXPath("//namespace::node()[name(.)='foo']");
+        List result = xpath.selectNodes(doc);
+        assertEquals(1, result.size());
+        Node node = (Node) result.get(0);
+        assertEquals("http://www.example.org", node.getNodeValue());
+        
+    }    
+    
+    // see JAXEN-105
+    public void testIntrinsicNamespaceDeclarationOfAttrBeatsContradictoryXmlnsPreAttr() 
+      throws JaxenException {
+        
+        Element root = doc.createElement("root");
+        doc.appendChild(root);
+        root.setAttributeNS("http://www.example.org/", "foo:a", "value");
+        // same prefix, different namespace
+        root.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:foo", "http://www.contradictory.org");
+        
+        XPath xpath = new DOMXPath("//namespace::node()[name(.)='foo']");
+        List result = xpath.selectNodes(doc);
+        assertEquals(1, result.size());
+        Node node = (Node) result.get(0);
+        assertEquals("http://www.example.org/", node.getNodeValue());
+        
+    }    
+    
+    // see JAXEN-105
+    public void testIntrinsicNamespaceDeclarationOfElementBeatsContradictoryIntrinsicNamespaceOfAttr() 
+      throws JaxenException {
+        
+        Element root = doc.createElementNS("http://www.example.org", "pre:root");
+        doc.appendChild(root);
+        // same prefix
+        root.setAttributeNS("http://www.contradictory.org", "pre:foo", "value");
+        
+        XPath xpath = new DOMXPath("//namespace::node()[name(.)='pre']");
+        List result = xpath.selectNodes(doc);
+        assertEquals(1, result.size());
+        Node node = (Node) result.get(0);
+        assertEquals("http://www.example.org", node.getNodeValue());
+        
+    }    
+    
+    // Jaxen-54
+    public void testUpdateDOMNodesReturnedBySelectNodes() 
+      throws JaxenException {
+        
+        Element root = doc.createElementNS("http://www.example.org/", "root");
+        doc.appendChild(root);
+        root.appendChild(doc.createComment("data"));
+        
+        DOMXPath xpath = new DOMXPath( "//comment()" );
+        
+        List results = xpath.selectNodes(doc);
+        Node backroot = (Node) results.get(0);
+        backroot.setNodeValue("test");
+        assertEquals("test", backroot.getNodeValue());
+        
+    }
+
+    public void testSelection() 
+      throws JaxenException, ParserConfigurationException, SAXException, IOException {
+        XPath xpath = new DOMXPath( "/foo/bar/baz" );
+
+        DocumentBuilder builder = factory.newDocumentBuilder();
+    
+        Document document = builder.parse( BASIC_XML );
+
+        List results = xpath.selectNodes( document );
+
+        assertEquals( 3,
+                      results.size() );
+
+        Iterator iter = results.iterator();
+
+        assertEquals( "baz",
+                      ((Element)iter.next()).getLocalName() );
+
+        assertEquals( "baz",
+                      ((Element)iter.next()).getLocalName() );
+
+        assertEquals( "baz",
+                      ((Element)iter.next()).getLocalName() );
+
+        assertTrue( ! iter.hasNext() );
+
+    }
+    
+    // Jaxen-22
+    public void testPrecedingAxisWithPositionalPredicate() 
+      throws JaxenException, ParserConfigurationException, SAXException, IOException {
+        
+        XPath xpath = new DOMXPath( "//c/preceding::*[1][name()='d']" );
+        DocumentBuilder builder = factory.newDocumentBuilder();
+    
+        Document document = builder.parse( "xml/web2.xml" );
+        List result = xpath.selectNodes(document);
+        assertEquals(1, result.size());
+        
+    }
+    
+     
+    // Jaxen-22
+    public void testJaxen22() 
+      throws JaxenException, ParserConfigurationException, SAXException, IOException {
+        
+        XPath xpath = new DOMXPath( "name(//c/preceding::*[1])" );
+        DocumentBuilder builder = factory.newDocumentBuilder();
+    
+        doc = builder.parse("xml/web2.xml");
+        Object result = xpath.evaluate(doc);
+        assertEquals("d", result);
+    }
+    
+     
+    public void testPrecedingAxisInDocumentOrder() 
+      throws JaxenException {
+        
+        XPath xpath = new DOMXPath( "preceding::*" );
+    
+        Element root = doc.createElement("root");
+        doc.appendChild(root);
+        
+        Element a = doc.createElement("a");
+        root.appendChild(a);
+        Element b = doc.createElement("b");
+        root.appendChild(b);
+        Element c = doc.createElement("c");
+        a.appendChild(c);
+        
+        List result = xpath.selectNodes(b);
+        assertEquals(2, result.size());
+        assertEquals(a, result.get(0));
+        assertEquals(c, result.get(1));
+    }
+    
+     
+}
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/DefaultXPathExprTest.java b/libjaxen-java/src/java/test/org/jaxen/test/DefaultXPathExprTest.java
new file mode 100644
index 0000000..65eebb5
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/DefaultXPathExprTest.java
@@ -0,0 +1,128 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+
+
+
+package org.jaxen.test;
+
+import java.util.List;
+
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.jaxen.JaxenException;
+import org.jaxen.dom.DOMXPath;
+import org.jaxen.expr.Expr;
+import org.jaxen.expr.PathExpr;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import junit.framework.TestCase;
+
+/**
+ * <p>
+ *  Test for function context.
+ * </p>
+ * 
+ * @author Elliotte Rusty Harold
+ * @version 1.1b11
+ *
+ */
+public class DefaultXPathExprTest extends TestCase
+{
+
+    
+    // http://jira.codehaus.org/browse/JAXEN-40
+    public void testJAXEN40() throws JaxenException, ParserConfigurationException {
+        
+        DOMXPath xpath = new DOMXPath("root/child1/grandchild1 | root/child2/grandchild2");
+        
+        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        factory.setNamespaceAware(true);
+        Document doc = factory.newDocumentBuilder().newDocument();
+        Element root = doc.createElement("root");
+        Element child1 = doc.createElement("child1");
+        Element child2 = doc.createElement("child2");
+        Element grandchild1 = doc.createElement("grandchild1");
+        Element grandchild2 = doc.createElement("grandchild2");
+        root.appendChild(child1);
+        root.appendChild(child2);
+        child1.appendChild(grandchild1);
+        child2.appendChild(grandchild2);
+        
+        doc.appendChild(root);
+        
+        List results = xpath.selectNodes(doc);
+        assertEquals(2, results.size());
+        assertTrue(results.indexOf(grandchild1) >= 0);
+        assertTrue(results.indexOf(grandchild2) >= 0);
+        
+    }
+
+    
+    // http://jira.codehaus.org/browse/JAXEN-160
+    public void testJAXEN160GetText()
+    throws JaxenException, ParserConfigurationException {
+      
+      DOMXPath xpath = new DOMXPath("$var1/foo");
+      Expr expr = xpath.getRootExpr();
+      assertEquals("$var1/child::foo", expr.getText());
+      
+  }
+
+    public void testJAXEN160ToString()
+    throws JaxenException, ParserConfigurationException {
+      
+      DOMXPath xpath = new DOMXPath("$var1/foo");
+      Expr expr = xpath.getRootExpr();
+      assertEquals(
+        "[(DefaultPathExpr): [(DefaultVariableReferenceExpr): var1], [(DefaultRelativeLocationPath): [(DefaultNameStep): foo]]]", 
+        expr.toString()
+      );
+    }
+
+}
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/DescendantAxisIteratorTest.java b/libjaxen-java/src/java/test/org/jaxen/test/DescendantAxisIteratorTest.java
new file mode 100644
index 0000000..11e1862
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/DescendantAxisIteratorTest.java
@@ -0,0 +1,104 @@
+/* $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2005 Elliotte Rusty Harold.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+package org.jaxen.test;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.jaxen.UnsupportedAxisException;
+import org.jaxen.util.DescendantAxisIterator;
+import org.w3c.dom.Document;
+
+import junit.framework.TestCase;
+
+public class DescendantAxisIteratorTest extends TestCase {
+
+    private Iterator iterator;
+
+    public DescendantAxisIteratorTest(String name) {
+        super(name);
+    }
+    
+    protected void setUp() throws ParserConfigurationException, UnsupportedAxisException {
+        
+        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        factory.setNamespaceAware(true);
+        Document doc = factory.newDocumentBuilder().newDocument();
+        doc.appendChild(doc.createElement("root"));
+        
+        iterator = new DescendantAxisIterator(doc, new org.jaxen.dom.DocumentNavigator());
+        
+    }
+    
+    
+    public void testNoInfiniteLoops() {
+     
+        iterator.next();
+        try {
+            iterator.next();
+            fail("Iterated too far");   
+        }
+        catch (NoSuchElementException ex) {
+        }
+        
+    }
+    
+    
+    public void testRemove() {
+        
+        try {
+            iterator.remove();
+            fail("Removed from descendant axis iterator");   
+        }
+        catch (UnsupportedOperationException ex) {
+        }
+        
+    }
+    
+}
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/EqualsTest.java b/libjaxen-java/src/java/test/org/jaxen/test/EqualsTest.java
new file mode 100644
index 0000000..902909c
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/EqualsTest.java
@@ -0,0 +1,118 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+
+
+
+package org.jaxen.test;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.List;
+
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.jaxen.JaxenException;
+import org.jaxen.dom.DOMXPath;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+import junit.framework.TestCase;
+
+/**
+ * <p>
+ *  Test for function context.
+ * </p>
+ * 
+ * @author Elliotte Rusty Harold
+ * @version 1.1b9
+ *
+ */
+public class EqualsTest extends TestCase
+{
+
+    public void testEqualityAgainstNonExistentNodes() 
+      throws JaxenException, ParserConfigurationException {
+        
+        DOMXPath xpath = new DOMXPath("/a/b[c = ../d]");
+        
+        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        factory.setNamespaceAware(true);
+        Document doc = factory.newDocumentBuilder().newDocument();
+        Element root = doc.createElement("a");
+        doc.appendChild(root);
+        Element b = doc.createElement("b");
+        root.appendChild(b);
+        Element c = doc.createElement("c");
+        b.appendChild(c);
+        
+        List result = (List) xpath.evaluate(doc);
+        assertEquals(0, result.size());
+        
+    }
+ 
+    public void testOlander() 
+      throws JaxenException, SAXException, IOException, ParserConfigurationException {
+        
+        DOMXPath xpath = new DOMXPath("//BlockStatement//IfStatement[./Statement =  ./ancestor::BlockStatement/following-sibling::BlockStatement//IfStatement/Statement]");
+        
+        String data = "<?xml version='1.0'?><Block><BlockStatement><LocalVariableDeclaration><Type><PrimitiveType>boolean</PrimitiveType></Type><VariableDeclarator><VariableDeclaratorId/></VariableDeclarator><VariableDeclarator><VariableDeclaratorId/></VariableDeclarator></LocalVariableDeclaration></BlockStatement><BlockStatement><Statement><IfStatement><Expression><PrimaryExpression><PrimaryPrefix><Name>a</Name></PrimaryPrefix></PrimaryExpression></Expression><Statement><StatementExpres [...]
+        StringReader reader = new StringReader(data);
+        InputSource in = new InputSource(reader);
+        
+        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        factory.setNamespaceAware(true);
+        Document doc = factory.newDocumentBuilder().parse(in);
+        
+        List result = (List) xpath.evaluate(doc);
+        assertEquals(1, result.size());
+        
+    }
+ 
+}
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/ExprTests.java b/libjaxen-java/src/java/test/org/jaxen/test/ExprTests.java
new file mode 100644
index 0000000..ac1aeae
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/ExprTests.java
@@ -0,0 +1,77 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2005 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+
+
+package org.jaxen.test;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+/**
+ * <p>
+ *   Collect Jaxen's expression tests.
+ * </p>
+ * 
+ * @author Elliotte Rusty Harold
+ * @version 1.1b9
+ *
+ */
+public class ExprTests {
+
+    
+    public static Test suite() {
+        
+        TestSuite result = new TestSuite();
+        result.addTest(new TestSuite(DefaultXPathExprTest.class));
+        result.addTest(new TestSuite(ModTest.class));
+        result.addTest(new TestSuite(EqualsTest.class));
+        return result;
+        
+    }
+
+    
+}
\ No newline at end of file
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/ExtensionFunctionTest.java b/libjaxen-java/src/java/test/org/jaxen/test/ExtensionFunctionTest.java
new file mode 100644
index 0000000..ce60e08
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/ExtensionFunctionTest.java
@@ -0,0 +1,143 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2005, 2006 Elliotte Rusty Harold.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+
+package org.jaxen.test;
+
+import java.util.Iterator;
+import java.util.List;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import junit.framework.TestCase;
+
+import org.jaxen.*;
+import org.jaxen.dom.DOMXPath;
+import org.jaxen.function.NumberFunction;
+import org.jaxen.saxpath.SAXPathException;
+import org.w3c.dom.Document;
+
+/**
+ * @author Elliotte Rusty Harold
+ *
+ */
+public class ExtensionFunctionTest extends TestCase {
+
+    private Document doc;
+    
+    public void setUp() throws ParserConfigurationException
+    {
+        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        factory.setNamespaceAware(true);
+        DocumentBuilder builder = factory.newDocumentBuilder();
+        doc = builder.newDocument();
+    }
+
+
+    public ExtensionFunctionTest(String name) {
+        super(name);
+    }
+    
+    class MinFunction implements Function {
+
+        public Object call(Context context, List args) {
+            
+            if (args.isEmpty()) return new Double(Double.NaN);
+            
+            Navigator navigator = context.getNavigator();
+            double min = Double.MAX_VALUE;
+            Iterator iterator = args.iterator();
+            while (iterator.hasNext()) {
+                double next = NumberFunction.evaluate(iterator.next(), navigator).doubleValue();
+                min = Math.min(min, next);
+            }
+            return new Double(min);
+        }
+        
+    }
+    
+    
+    public void testRegisterExtensionFunction() throws JaxenException {
+        
+        SimpleFunctionContext fc = new XPathFunctionContext(false);
+        fc.registerFunction("http://exslt.org/math", "min", new MinFunction());
+        
+        SimpleNamespaceContext nc = new SimpleNamespaceContext();
+        nc.addNamespace("math", "http://exslt.org/math");
+        
+        BaseXPath xpath = new DOMXPath("math:min(//x)");
+        
+        xpath.setFunctionContext(fc);
+        xpath.setNamespaceContext(nc);
+        
+        org.w3c.dom.Element a = doc.createElementNS("", "a");
+        org.w3c.dom.Element b = doc.createElementNS("", "b");
+        doc.appendChild(a);
+        a.appendChild(b);
+        org.w3c.dom.Element x2 = doc.createElementNS("", "x");
+        org.w3c.dom.Element x3 = doc.createElementNS("", "x");
+        org.w3c.dom.Element x4 = doc.createElementNS("", "x");
+        a.appendChild(x4);
+        b.appendChild(x2);
+        b.appendChild(x3);
+        x2.appendChild(doc.createTextNode("2"));
+        x3.appendChild(doc.createTextNode("3"));
+        x4.appendChild(doc.createTextNode("4"));
+        
+        Double result = (Double) xpath.evaluate(doc);
+        assertEquals(new Double(2), result);
+       
+        
+    }
+    
+    
+    public void testJaxen47() throws SAXPathException {
+       org.jaxen.dom.DocumentNavigator.getInstance().parseXPath("a:b()");
+    }
+    
+}
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/FalseTest.java b/libjaxen-java/src/java/test/org/jaxen/test/FalseTest.java
new file mode 100644
index 0000000..492cfa5
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/FalseTest.java
@@ -0,0 +1,105 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2005 Elliotte Rusty Harold.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+
+package org.jaxen.test;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import junit.framework.TestCase;
+
+import org.jaxen.FunctionCallException;
+import org.jaxen.JaxenException;
+import org.jaxen.XPath;
+import org.jaxen.dom.DOMXPath;
+import org.w3c.dom.Document;
+
+/**
+ * @author Elliotte Rusty Harold
+ *
+ */
+public class FalseTest extends TestCase {
+
+    private Document doc;
+    
+    public void setUp() throws ParserConfigurationException
+    {
+        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        factory.setNamespaceAware(true);
+        DocumentBuilder builder = factory.newDocumentBuilder();
+        doc = builder.newDocument();
+        doc.appendChild(doc.createElement("root"));
+    }
+
+
+    public FalseTest(String name) {
+        super(name);
+    }
+
+    public void testFalseOfNumber() throws JaxenException
+    {
+        try
+        {
+            XPath xpath = new DOMXPath( "false(3)" );
+            xpath.selectNodes( doc );
+            fail("false() function took arguments");
+        }
+        catch (FunctionCallException e) 
+        {
+            assertEquals("false() requires no arguments.", e.getMessage());
+        }
+    }    
+
+    public void testFalse() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "false()" );
+        Object result = xpath.evaluate( doc );
+        assertEquals(Boolean.FALSE, result);
+    }    
+
+}
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/FloorTest.java b/libjaxen-java/src/java/test/org/jaxen/test/FloorTest.java
new file mode 100644
index 0000000..26cf144
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/FloorTest.java
@@ -0,0 +1,155 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2005 Elliotte Rusty Harold.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+
+package org.jaxen.test;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import junit.framework.TestCase;
+
+import org.jaxen.BaseXPath;
+import org.jaxen.FunctionCallException;
+import org.jaxen.JaxenException;
+import org.jaxen.dom.DOMXPath;
+import org.w3c.dom.Document;
+
+/**
+ * @author Elliotte Rusty Harold
+ *
+ */
+public class FloorTest extends TestCase {
+
+    private Document doc;
+    
+    public void setUp() throws ParserConfigurationException
+    {
+        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        factory.setNamespaceAware(true);
+        DocumentBuilder builder = factory.newDocumentBuilder();
+        doc = builder.newDocument();
+        org.w3c.dom.Element a = doc.createElementNS("", "a");
+        doc.appendChild(a);
+    }
+
+
+    public FloorTest(String name) {
+        super(name);
+    }
+
+
+
+    public void testFloor() throws JaxenException {
+        
+        BaseXPath xpath = new DOMXPath("floor(1.5)");
+        
+        Object result = xpath.evaluate(doc);
+        assertEquals(1, ((Double) result).doubleValue(), 0.0001);
+        
+    }    
+
+    public void testNegativeFloor() throws JaxenException {
+        
+        BaseXPath xpath = new DOMXPath("floor(-1.5)");
+        
+        Object result = xpath.evaluate(doc);
+        assertEquals(-2, ((Double) result).doubleValue(), 0.0001);
+        
+    }    
+
+    public void testNaNFloorIsNaN() throws JaxenException {
+        BaseXPath xpath = new DOMXPath("floor(1.0 div 0.0 - 2.0 div 0.0)");
+        double result = ((Double) xpath.evaluate(doc)).doubleValue();
+        assertTrue(Double.isNaN(result));
+    }    
+
+    public void testInfFloorIsInf() throws JaxenException {
+        BaseXPath xpath = new DOMXPath("floor(1.0 div 0.0)");
+        double result = ((Double) xpath.evaluate(doc)).doubleValue();
+        assertTrue(Double.isInfinite(result));
+        assertTrue(result > 0);
+    }    
+
+    public void testNegativeInfFloorIsNegativeInf() throws JaxenException {
+        BaseXPath xpath = new DOMXPath("floor(-1.0 div 0.0)");
+        double result = ((Double) xpath.evaluate(doc)).doubleValue();
+        assertTrue(Double.isInfinite(result));
+        assertTrue(result < 0);
+    }    
+
+    public void testFloorFunctionRequiresAtLeastArgument() 
+      throws JaxenException {
+        
+        BaseXPath xpath = new DOMXPath("floor()");
+        
+        try {
+            xpath.selectNodes(doc);
+            fail("Allowed floor function with no arguments");
+        }
+        catch (FunctionCallException ex) {
+            assertNotNull(ex.getMessage());
+        }
+        
+    }    
+
+    public void testBooleanFunctionRequiresExactlyOneArgument() 
+      throws JaxenException {
+        
+        BaseXPath xpath = new DOMXPath("floor(2.2, 1.2)");
+        
+        try {
+            xpath.selectNodes(doc);
+            fail("Allowed floor function with two arguments");
+        }
+        catch (FunctionCallException ex) {
+            assertNotNull(ex.getMessage());
+        }
+        
+    }    
+
+}
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/FollowingAxisIteratorTest.java b/libjaxen-java/src/java/test/org/jaxen/test/FollowingAxisIteratorTest.java
new file mode 100644
index 0000000..a59088f
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/FollowingAxisIteratorTest.java
@@ -0,0 +1,109 @@
+/* $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2005 Elliotte Rusty Harold.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+package org.jaxen.test;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.jaxen.UnsupportedAxisException;
+import org.jaxen.util.FollowingAxisIterator;
+import org.w3c.dom.Document;
+
+import junit.framework.TestCase;
+
+public class FollowingAxisIteratorTest extends TestCase {
+
+    private Iterator iterator;
+
+    public FollowingAxisIteratorTest(String name) {
+        super(name);
+    }
+    
+    protected void setUp() throws ParserConfigurationException, UnsupportedAxisException {
+        
+        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        factory.setNamespaceAware(true);
+        Document doc = factory.newDocumentBuilder().newDocument();
+        doc.appendChild(doc.createElement("root"));
+        
+        iterator = new FollowingAxisIterator(doc, new org.jaxen.dom.DocumentNavigator());
+        
+    }
+    
+    
+    public void testNoInfiniteLoops() {
+     
+        try {
+            iterator.next();
+            fail("Iterated too far");   
+        }
+        catch (NoSuchElementException ex) {
+            pass();
+        }
+        
+    }
+    
+    
+    private void pass() {
+        // Just to make checkstyle and the like happy
+    }
+
+    public void testRemove() {
+        
+        try {
+            iterator.remove();
+            fail("Removed from descendant axis iterator");   
+        }
+        catch (UnsupportedOperationException ex) {
+            pass();
+        }
+        
+    }
+    
+}
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/FollowingSiblingAxisIteratorTest.java b/libjaxen-java/src/java/test/org/jaxen/test/FollowingSiblingAxisIteratorTest.java
new file mode 100644
index 0000000..fac32be
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/FollowingSiblingAxisIteratorTest.java
@@ -0,0 +1,109 @@
+/* $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2005 Elliotte Rusty Harold.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+package org.jaxen.test;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.jaxen.UnsupportedAxisException;
+import org.jaxen.util.FollowingSiblingAxisIterator;
+import org.w3c.dom.Document;
+
+import junit.framework.TestCase;
+
+public class FollowingSiblingAxisIteratorTest extends TestCase {
+
+    private Iterator iterator;
+
+    public FollowingSiblingAxisIteratorTest(String name) {
+        super(name);
+    }
+    
+    protected void setUp() throws ParserConfigurationException, UnsupportedAxisException {
+        
+        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        factory.setNamespaceAware(true);
+        Document doc = factory.newDocumentBuilder().newDocument();
+        doc.appendChild(doc.createElement("root"));
+        
+        iterator = new FollowingSiblingAxisIterator(doc, new org.jaxen.dom.DocumentNavigator());
+        
+    }
+    
+    
+    public void testNoInfiniteLoops() {
+     
+        try {
+            iterator.next();
+            fail("Iterated too far");   
+        }
+        catch (NoSuchElementException ex) {
+            pass();
+        }
+        
+    }
+    
+    
+    private void pass() {
+        // Just to make checkstyle and the like happy
+    }
+
+    public void testRemove() {
+        
+        try {
+            iterator.remove();
+            fail("Removed from descendant axis iterator");   
+        }
+        catch (UnsupportedOperationException ex) {
+            pass();
+        }
+        
+    }
+    
+}
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/FunctionCallExceptionTest.java b/libjaxen-java/src/java/test/org/jaxen/test/FunctionCallExceptionTest.java
new file mode 100644
index 0000000..e7b7491
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/FunctionCallExceptionTest.java
@@ -0,0 +1,86 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2005 Elliotte Rusty Harold.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+
+package org.jaxen.test;
+
+
+import org.jaxen.FunctionCallException;
+import org.jaxen.JaxenException;
+
+import junit.framework.TestCase;
+
+
+/**
+ * @author Elliotte Rusty Harold
+ *
+ */
+public class FunctionCallExceptionTest extends TestCase {
+
+    public FunctionCallExceptionTest(String name) {
+        super(name);
+    }
+
+    public void testMessageIsNonNull() {
+        
+        JaxenException ex = new JaxenException("Hello");
+        FunctionCallException rex = new FunctionCallException(ex);
+        assertEquals(ex.getMessage(), rex.getMessage());
+        assertEquals(ex, rex.getCause());
+        
+    }    
+  
+    public void testMessageIsSaved() {
+        
+        JaxenException ex = new JaxenException("Hello");
+        FunctionCallException rex = new FunctionCallException("Goodbye", ex);
+        assertEquals("Goodbye", rex.getMessage());
+        assertEquals(ex, rex.getCause());
+        
+    }    
+  
+
+}
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/FunctionContextTest.java b/libjaxen-java/src/java/test/org/jaxen/test/FunctionContextTest.java
new file mode 100644
index 0000000..c8bce83
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/FunctionContextTest.java
@@ -0,0 +1,158 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+
+
+
+package org.jaxen.test;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.NotSerializableException;
+import java.io.ObjectOutputStream;
+
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.jaxen.FunctionContext;
+import org.jaxen.JaxenException;
+import org.jaxen.SimpleNamespaceContext;
+import org.jaxen.UnresolvableException;
+import org.jaxen.dom.DOMXPath;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import junit.framework.TestCase;
+
+/**
+ * <p>
+ *  Test for function context.
+ * </p>
+ * 
+ * @author Elliotte Rusty Harold
+ * @version 1.1b9
+ *
+ */
+public class FunctionContextTest extends TestCase
+{
+
+    private Document doc;
+    
+    public void setUp() throws ParserConfigurationException {
+        
+        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        factory.setNamespaceAware(true);
+        doc = factory.newDocumentBuilder().newDocument();
+        Element root = doc.createElementNS("http://www.example.org/", "root");
+        doc.appendChild(root);
+        root.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns", "http://www.example.org/");
+              
+    }
+    
+    public void testJAXEN50() throws JaxenException {
+        
+        DOMXPath xpath = new DOMXPath("true()");
+        
+        SimpleNamespaceContext nsContext = new SimpleNamespaceContext();
+        // Add all namespace declarations from the node
+        nsContext.addElementNamespaces(xpath.getNavigator(), doc);
+        xpath.setNamespaceContext(nsContext);
+        
+        boolean result = xpath.booleanValueOf(doc);
+        assertTrue(result);
+        
+    }
+ 
+    public void testUnresolvableFunction() throws JaxenException {
+        
+        DOMXPath xpath = new DOMXPath("nonesuch()");
+        
+        try {
+            xpath.evaluate(doc);
+            fail("Evaluated nonexistent function");
+        }
+        catch (UnresolvableException ex) {
+            assertNotNull(ex.getMessage());
+        }
+        
+    }
+ 
+    public void testUnresolvableFunctionExceptionMessage() throws JaxenException {
+        
+        DOMXPath xpath = new DOMXPath("nonesuch()");
+        
+        try {
+            xpath.evaluate(doc);
+            fail("Evaluated nonexistent function");
+        }
+        catch (UnresolvableException ex) {
+            assertEquals(-1, ex.getMessage().indexOf(':'));
+        }
+        
+    }
+ 
+    public void testGetFunctionContext() throws JaxenException {      
+        DOMXPath xpath = new DOMXPath("/root/child");
+        assertNotNull(xpath.getFunctionContext());
+    }
+ 
+    public void testSerializeFunctionContext() throws JaxenException, IOException { 
+        
+        DOMXPath xpath = new DOMXPath("/root/child");
+        FunctionContext context = xpath.getFunctionContext();
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        ObjectOutputStream oout = new ObjectOutputStream(out);
+        try {
+            oout.writeObject(context);
+            fail("serialized function context");
+        }
+        catch (NotSerializableException ex) {
+            assertNotNull(ex.getMessage());
+        }
+        
+    }
+ 
+}
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/FunctionTests.java b/libjaxen-java/src/java/test/org/jaxen/test/FunctionTests.java
new file mode 100644
index 0000000..2e1a3c1
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/FunctionTests.java
@@ -0,0 +1,100 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2005 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+
+
+package org.jaxen.test;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+/**
+ * <p>
+ *   Suite for Jaxen's function tests.
+ * </p>
+ * 
+ * @author Elliotte Rusty Harold
+ * @version 1.1b9
+ *
+ */
+public class FunctionTests {
+    
+    public static Test suite() {
+        
+        TestSuite result = new TestSuite();
+        result.addTest(new TestSuite(TranslateFunctionTest.class));
+        result.addTest(new TestSuite(SubstringTest.class));
+        result.addTest(new TestSuite(SubstringBeforeTest.class));
+        result.addTest(new TestSuite(SubstringAfterTest.class));
+        result.addTest(new TestSuite(LangTest.class));
+        result.addTest(new TestSuite(LastTest.class));
+        result.addTest(new TestSuite(ConcatTest.class));
+        result.addTest(new TestSuite(ContainsTest.class));
+        result.addTest(new TestSuite(StringLengthTest.class));
+        result.addTest(new TestSuite(StartsWithTest.class));
+        result.addTest(new TestSuite(CountTest.class));
+        result.addTest(new TestSuite(LocalNameTest.class));
+        result.addTest(new TestSuite(NameTest.class));
+        result.addTest(new TestSuite(NamespaceURITest.class));
+        result.addTest(new TestSuite(SumTest.class));
+        result.addTest(new TestSuite(NumberTest.class));
+        result.addTest(new TestSuite(RoundTest.class));
+        result.addTest(new TestSuite(StringTest.class));
+        result.addTest(new TestSuite(BooleanTest.class));
+        result.addTest(new TestSuite(CeilingTest.class));
+        result.addTest(new TestSuite(FloorTest.class));
+        result.addTest(new TestSuite(IdTest.class));
+        result.addTest(new TestSuite(TrueTest.class));
+        result.addTest(new TestSuite(FalseTest.class));
+        result.addTest(new TestSuite(NotTest.class));
+        result.addTest(new TestSuite(NormalizeSpaceTest.class));
+        result.addTest(new TestSuite(PositionTest.class));
+        result.addTest(new TestSuite(ExtensionFunctionTest.class));
+        return result;
+        
+    }
+
+}
\ No newline at end of file
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/HelpersTests.java b/libjaxen-java/src/java/test/org/jaxen/test/HelpersTests.java
new file mode 100644
index 0000000..27cf0e4
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/HelpersTests.java
@@ -0,0 +1,73 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2005 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+
+
+package org.jaxen.test;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+/**
+ * <p>
+ *   Collect the org.jaxen.saxpath.helpers tests.
+ * </p>
+ * 
+ * @author Elliotte Rusty Harold
+ * @version 1.1b9
+ *
+ */
+public class HelpersTests {
+    
+    public static Test suite() {
+        
+        TestSuite result = new TestSuite();
+        result.addTest(new TestSuite(XPathReaderFactoryTest.class));
+        return result;
+        
+    }
+    
+}
\ No newline at end of file
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/IdTest.java b/libjaxen-java/src/java/test/org/jaxen/test/IdTest.java
new file mode 100644
index 0000000..a057b96
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/IdTest.java
@@ -0,0 +1,212 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2005 Elliotte Rusty Harold
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+
+package org.jaxen.test;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.List;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import junit.framework.TestCase;
+
+import org.jaxen.BaseXPath;
+import org.jaxen.FunctionCallException;
+import org.jaxen.JaxenException;
+import org.jaxen.dom.DOMXPath;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+/**
+ * @author Elliotte Rusty Harold
+ *
+ */
+public class IdTest extends TestCase {
+
+    private Document doc;
+    private DocumentBuilder builder;
+    
+    public void setUp() throws ParserConfigurationException
+    {
+        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        factory.setNamespaceAware(true);
+        builder = factory.newDocumentBuilder();
+        doc = builder.newDocument();
+    }
+
+    public IdTest(String name) {
+        super(name);
+    }
+
+    public void testIDFunctionSelectsNothingInDocumentWithNoIds() 
+      throws JaxenException {
+        
+        BaseXPath xpath = new DOMXPath("id('p1')");
+        org.w3c.dom.Element a = doc.createElementNS("", "a");
+        org.w3c.dom.Element b = doc.createElementNS("", "b");
+        doc.appendChild(a);
+        a.appendChild(b);
+        org.w3c.dom.Element x2 = doc.createElementNS("", "x");
+        org.w3c.dom.Element x3 = doc.createElementNS("", "x");
+        org.w3c.dom.Element x4 = doc.createElementNS("", "x");
+        a.appendChild(x4);
+        b.appendChild(x2);
+        b.appendChild(x3);
+        x2.appendChild(doc.createTextNode("2"));
+        x3.appendChild(doc.createTextNode("3"));
+        x4.appendChild(doc.createTextNode("4"));
+        Attr id = doc.createAttribute("id");
+        id.setNodeValue("p1");
+        x2.setAttributeNode(id);
+        
+        List result = xpath.selectNodes(doc);
+        assertEquals(0, result.size());
+        
+    }    
+
+    public void testIDFunctionRequiresAtLeastOneArgument() 
+      throws JaxenException {
+        
+        try {
+            BaseXPath xpath = new DOMXPath("id()");
+            org.w3c.dom.Element a = doc.createElementNS("", "a");
+            doc.appendChild(a);
+            xpath.selectNodes(doc);
+            fail("Allowed empty id() function");
+        }
+        catch (FunctionCallException success) {
+            assertNotNull(success.getMessage());
+        }
+        
+    }    
+
+    public void testIDFunctionRequiresAtMostOneArgument() 
+      throws JaxenException {
+        
+        try {
+            BaseXPath xpath = new DOMXPath("id('p', 'q')");
+            org.w3c.dom.Element a = doc.createElementNS("", "a");
+            doc.appendChild(a);
+            xpath.selectNodes(doc);
+            fail("Allowed two-argument id() function");
+        }
+        catch (FunctionCallException success) {
+            assertNotNull(success.getMessage());
+        }
+        
+    }    
+
+    public void testFindElementById() 
+      throws JaxenException, SAXException, IOException {
+        
+        BaseXPath xpath = new DOMXPath("id('p1')");
+        String text = "<!DOCTYPE root [<!ATTLIST a id ID #REQUIRED>]><root><a id='p1'/></root>";
+        StringReader reader = new StringReader(text);
+        InputSource in = new InputSource(reader);
+        Document doc = builder.parse(in);
+        List result = xpath.selectNodes(doc);
+        assertEquals(1, result.size());
+        Element a = (Element) result.get(0);
+        assertEquals("a", a.getNodeName());
+        
+    }    
+
+    /* public void testFindElementByXMLId() 
+      throws JaxenException, SAXException, IOException {
+        
+        BaseXPath xpath = new DOMXPath("id('p1')");
+        String text = "<root><a xml:id='p1'/></root>";
+        StringReader reader = new StringReader(text);
+        InputSource in = new InputSource(reader);
+        Document doc = builder.parse(in);
+        List result = xpath.selectNodes(doc);
+        assertEquals(1, result.size());
+        Element a = (Element) result.get(0);
+        assertEquals("a", a.getNodeName());
+        
+    }    */
+
+    public void testFindMultipleElementsByMultipleIDs() 
+      throws JaxenException, SAXException, IOException {
+        
+        BaseXPath xpath = new DOMXPath("id(//id)");
+        String text = "<!DOCTYPE root [<!ATTLIST a id ID #REQUIRED>]><root><id>p1</id><id>p2</id><id>p3</id><a id='p1'/><a id='p2'/></root>";
+        StringReader reader = new StringReader(text);
+        InputSource in = new InputSource(reader);
+        Document doc = builder.parse(in);
+        List result = xpath.selectNodes(doc);
+        assertEquals(2, result.size());
+        Element a1 = (Element) result.get(0);
+        Element a2 = (Element) result.get(1);
+        assertEquals("a", a1.getNodeName());
+        assertEquals("a", a2.getNodeName());
+        
+    }    
+
+    public void testIdReturnsFirstElementWithMatchingId() 
+      throws JaxenException, SAXException, IOException {
+        
+        BaseXPath xpath = new DOMXPath("id('p1')");
+        String text = "<!DOCTYPE root [<!ATTLIST a id ID #REQUIRED>" +
+                "<!ATTLIST b id ID #REQUIRED>]><root><a id='p1'/><b id='p1'/></root>";
+        StringReader reader = new StringReader(text);
+        InputSource in = new InputSource(reader);
+        Document doc = builder.parse(in);
+        List result = xpath.selectNodes(doc);
+        assertEquals(1, result.size());
+        Element a = (Element) result.get(0);
+        assertEquals("a", a.getNodeName());
+        
+    }    
+
+}
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/JDOMNavigatorTest.java b/libjaxen-java/src/java/test/org/jaxen/test/JDOMNavigatorTest.java
new file mode 100644
index 0000000..9b8ff57
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/JDOMNavigatorTest.java
@@ -0,0 +1,95 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+
+
+package org.jaxen.test;
+
+import java.util.List;
+
+import org.jaxen.JaxenException;
+import org.jaxen.Navigator;
+import org.jaxen.XPath;
+import org.jaxen.jdom.DocumentNavigator;
+import org.jaxen.jdom.JDOMXPath;
+import org.jdom.Document;
+import org.jdom.Element;
+import org.jdom.Namespace;
+import org.jdom.input.SAXBuilder;
+
+public class JDOMNavigatorTest extends XPathTestBase
+{
+    private SAXBuilder builder = new SAXBuilder();
+
+    public JDOMNavigatorTest(String name)
+    {
+        super( name );
+    }
+
+    public Navigator getNavigator()
+    {
+        return new DocumentNavigator();
+    }
+
+    public Object getDocument(String url) throws Exception
+    {
+        return this.builder.build( url );
+    }
+    
+    
+    public void testNullNamespace() throws JaxenException {
+
+        Namespace my = Namespace.getNamespace("foo", "http://mynamespace.org/");
+        Document doc = new Document();
+        Element root = new Element("root", my);
+        doc.setRootElement(root);
+        XPath nullNamespacePath = new JDOMXPath("/root");
+        List selectedNodes = nullNamespacePath.selectNodes(doc);
+        assertEquals(0, selectedNodes.size());
+        
+    }
+    
+}
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/JDOMPerformance.java b/libjaxen-java/src/java/test/org/jaxen/test/JDOMPerformance.java
new file mode 100644
index 0000000..8826880
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/JDOMPerformance.java
@@ -0,0 +1,68 @@
+/*
+ $Id$
+
+ Copyright 2003 The Werken Company. All Rights Reserved.
+ 
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+  * Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+
+  * Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+
+  * Neither the name of the Jaxen Project nor the names of its
+    contributors may be used to endorse or promote products derived 
+    from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ */
+package org.jaxen.test;
+
+import java.net.URL;
+
+import org.jaxen.jdom.JDOMXPath;
+import org.jdom.Document;
+import org.jdom.Element;
+import org.jdom.input.SAXBuilder;
+
+class JDOMPerformance {
+    
+    public static void main(String[] args) {
+        try {
+            URL u = new URL("http://www.ibiblio.org/xml/examples/shakespeare/much_ado.xml");
+            Document doc = new SAXBuilder().build(u);
+            JDOMXPath xpath = new JDOMXPath("PLAY/ACT/SCENE/SPEECH/SPEAKER");
+            
+            long start = System.currentTimeMillis();
+            
+            int count = 0;
+            for (int i = 0; i < 1000; i++) {
+                Element speaker = (Element) xpath.selectSingleNode(doc);
+                count += (speaker == null ? 0 : 1);
+            }
+            
+            long end = System.currentTimeMillis();
+            System.out.println((end - start));
+            System.out.println(count);
+            
+        } catch (Exception ex) {
+            ex.printStackTrace();
+        }
+    }
+    
+}
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/JDOMTests.java b/libjaxen-java/src/java/test/org/jaxen/test/JDOMTests.java
new file mode 100644
index 0000000..a2bea60
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/JDOMTests.java
@@ -0,0 +1,74 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2005 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+
+
+package org.jaxen.test;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+/**
+ * <p>
+ *   Collect Jaxen's JDOM tests.
+ * </p>
+ * 
+ * @author Elliotte Rusty Harold
+ * @version 1.1b9
+ *
+ */
+public class JDOMTests {
+    
+    public static Test suite() {
+        
+        TestSuite result = new TestSuite();
+        result.addTest(new TestSuite(JDOMNavigatorTest.class));
+        result.addTest(new TestSuite(JDOMXPathTest.class));
+        return result;
+        
+    }
+    
+}
\ No newline at end of file
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/JDOMXPathTest.java b/libjaxen-java/src/java/test/org/jaxen/test/JDOMXPathTest.java
new file mode 100644
index 0000000..8f23511
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/JDOMXPathTest.java
@@ -0,0 +1,207 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2003 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+
+
+package org.jaxen.test;
+
+import junit.framework.TestCase;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.Iterator;
+import java.util.List;
+
+import org.jaxen.JaxenException;
+import org.jaxen.XPath;
+import org.jaxen.jdom.JDOMXPath;
+import org.jdom.Attribute;
+import org.jdom.Document;
+import org.jdom.Element;
+import org.jdom.JDOMException;
+import org.jdom.Namespace;
+import org.jdom.Text;
+import org.jdom.input.SAXBuilder;
+import org.xml.sax.InputSource;
+
+public class JDOMXPathTest extends TestCase
+{
+
+    private static final String BASIC_XML = "xml/basic.xml";
+
+    public JDOMXPathTest(String name)
+    {
+        super( name );
+    }
+
+    public void testConstruction() throws JaxenException
+    {
+        new JDOMXPath( "/foo/bar/baz" );
+    }
+
+    public void testSelection() throws JaxenException, JDOMException, IOException
+    {
+        XPath xpath = new JDOMXPath( "/foo/bar/baz" );
+
+        SAXBuilder builder = new SAXBuilder();
+
+        Document doc = builder.build( BASIC_XML );
+
+        List results = xpath.selectNodes( doc );
+
+        assertEquals( 3,
+                      results.size() );
+
+        Iterator iter = results.iterator();
+
+        assertEquals( "baz",
+                      ((Element)iter.next()).getName() );
+
+        assertEquals( "baz",
+                      ((Element)iter.next()).getName() );
+
+        assertEquals( "baz",
+                      ((Element)iter.next()).getName() );
+
+        assertTrue( ! iter.hasNext() );
+    }
+    
+    
+    public void testGetDocumentNode() throws JaxenException, JDOMException, IOException
+    {
+        XPath xpath = new JDOMXPath( "/" );
+
+        SAXBuilder builder = new SAXBuilder();
+
+        Document doc = builder.build( BASIC_XML );
+
+        Element root = doc.getRootElement();
+        List results = xpath.selectNodes( root );
+
+        assertEquals( 1,
+                      results.size() );
+
+        Iterator iter = results.iterator();
+
+        assertEquals( doc, iter.next());
+
+    }
+    
+    public void testJaxen148() throws JaxenException, JDOMException, IOException  {
+        String xml = "<xml-document><nodes><node>" +
+        "\ntest\n" + 
+        "</node></nodes></xml-document>";
+
+        SAXBuilder builder = new SAXBuilder();
+        Document document = builder.build( new InputSource( new StringReader(xml) ) );
+        
+        JDOMXPath x = new JDOMXPath("/xml-document/nodes/node/text()");
+        Text t = (Text) x.selectSingleNode(document);
+        
+        assertEquals( "\ntest\n" , t.getText() );
+        
+    }
+    
+    
+    public void testJaxen53Text() throws JaxenException, JDOMException, IOException
+    {
+        XPath xpath = new JDOMXPath( "//data/text() " );
+
+        SAXBuilder builder = new SAXBuilder();
+
+        Document doc = builder.build( new StringReader("<root>\n<data>1</data>\n</root>") );
+
+        List results = xpath.selectNodes( doc );
+
+        assertEquals( 1,
+                      results.size() );
+
+        Iterator iter = results.iterator();
+
+        Text result = (Text) iter.next();
+        assertEquals( "1", result.getValue());
+
+    }
+    
+    public void testJaxen20AttributeNamespaceNodes() throws JaxenException
+    {
+        Namespace ns1 = Namespace.getNamespace("p1", "www.acme1.org");
+        Namespace ns2 = Namespace.getNamespace("p2", "www.acme2.org");
+        Element element = new Element("test", ns1);
+        Attribute attribute = new Attribute("foo", "bar", ns2);
+        element.setAttribute(attribute); 
+        Document doc = new Document(element);
+        
+        XPath xpath = new JDOMXPath( "//namespace::node()" );
+
+        List results = xpath.selectNodes( doc );
+
+        assertEquals( 3,
+                      results.size() );
+
+    }
+    
+    public void testNamespaceNodesAreInherited() throws JaxenException
+    {
+        Namespace ns0 = Namespace.getNamespace("p0", "www.acme0.org");
+        Namespace ns1 = Namespace.getNamespace("p1", "www.acme1.org");
+        Namespace ns2 = Namespace.getNamespace("p2", "www.acme2.org");
+        Element element = new Element("test", ns1);
+        Attribute attribute = new Attribute("foo", "bar", ns2);
+        element.setAttribute(attribute);
+        Element root = new Element("root", ns0);
+        root.addContent(element);
+        Document doc = new Document(root);
+        
+        XPath xpath = new JDOMXPath( "/*/*/namespace::node()" );
+
+        List results = xpath.selectNodes( doc );
+
+        assertEquals( 4, results.size() );
+
+    }
+    
+}
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/JavaBeanNavigatorTest.java b/libjaxen-java/src/java/test/org/jaxen/test/JavaBeanNavigatorTest.java
new file mode 100644
index 0000000..62e678a
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/JavaBeanNavigatorTest.java
@@ -0,0 +1,42 @@
+package org.jaxen.test;
+
+import java.util.List;
+
+import junit.framework.TestCase;
+
+import org.jaxen.JaxenException;
+import org.jaxen.javabean.JavaBeanXPath;
+import org.jaxen.saxpath.helpers.XPathReaderFactory;
+
+public class JavaBeanNavigatorTest
+    extends TestCase
+{
+
+    protected void setUp() throws Exception
+    {
+        System.setProperty( XPathReaderFactory.DRIVER_PROPERTY,
+                            "" );
+    }
+
+    public void testSomething() throws JaxenException {
+        
+        // The position() function does not really have any meaning 
+        // for JavaBeans, but we know three of them will come before the fourth,
+        // even if we don't know which ones.
+        JavaBeanXPath xpath = new JavaBeanXPath( "brother[position()<4]/name" );
+
+        Person bob = new Person( "bob", 30 );
+
+        bob.addBrother( new Person( "billy", 34 ) );
+        bob.addBrother( new Person( "seth", 29 ) );
+        bob.addBrother( new Person( "dave", 32 ) );
+        bob.addBrother( new Person( "jim", 29 ) );
+        bob.addBrother( new Person( "larry", 42 ) );
+        bob.addBrother( new Person( "ted", 22 ) );
+
+        List result = (List) xpath.evaluate( bob );
+        assertEquals(3, result.size());
+        
+    }
+
+}
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/JavaBeanTests.java b/libjaxen-java/src/java/test/org/jaxen/test/JavaBeanTests.java
new file mode 100644
index 0000000..982db0a
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/JavaBeanTests.java
@@ -0,0 +1,73 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2005 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+
+
+package org.jaxen.test;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+/**
+ * <p>
+ *   Collect Jaxen's JavaBean tests.
+ * </p>
+ * 
+ * @author Elliotte Rusty Harold
+ * @version 1.1b9
+ *
+ */
+public class JavaBeanTests {
+    
+    public static Test suite() {
+        
+        TestSuite result = new TestSuite();
+        result.addTest(new TestSuite(JavaBeanNavigatorTest.class));
+        return result;
+        
+    }
+    
+}
\ No newline at end of file
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/JaxenExceptionTest.java b/libjaxen-java/src/java/test/org/jaxen/test/JaxenExceptionTest.java
new file mode 100644
index 0000000..4757dd3
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/JaxenExceptionTest.java
@@ -0,0 +1,87 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2005 Elliotte Rusty Harold.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+
+package org.jaxen.test;
+
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+import org.jaxen.JaxenException;
+
+import junit.framework.TestCase;
+
+
+/**
+ * @author Elliotte Rusty Harold
+ *
+ */
+public class JaxenExceptionTest extends TestCase {
+
+    public JaxenExceptionTest(String name) {
+        super(name);
+    }
+
+    public void testMessageIsNonNull() {
+        JaxenException ex = new JaxenException("Hello");
+        assertEquals("Hello", ex.getMessage());
+    }    
+  
+    public void testPrintStackTrace() {
+        StringIndexOutOfBoundsException cause = new StringIndexOutOfBoundsException("1234");
+        JaxenException ex = new JaxenException(cause);
+        StringWriter out = new StringWriter();
+        PrintWriter pw = new PrintWriter(out);
+        ex.printStackTrace(pw);
+        pw.close();
+        String trace = out.toString();
+        assertEquals(-1, trace.indexOf("Root cause:"));
+        assertTrue(trace.indexOf("Caused by: java.lang.StringIndexOutOfBoundsException") > 0);
+        assertTrue(trace.indexOf("1234") > 0);
+    }
+    
+}
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/JaxenHandlerTest.java b/libjaxen-java/src/java/test/org/jaxen/test/JaxenHandlerTest.java
new file mode 100644
index 0000000..0e3fcbf
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/JaxenHandlerTest.java
@@ -0,0 +1,169 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+
+
+
+package org.jaxen.test;
+
+import junit.framework.TestCase;
+
+import org.jaxen.JaxenHandler;
+import org.jaxen.expr.DefaultXPathFactory;
+import org.jaxen.expr.XPathExpr;
+import org.jaxen.saxpath.SAXPathException;
+import org.jaxen.saxpath.XPathReader;
+import org.jaxen.saxpath.XPathSyntaxException;
+import org.jaxen.saxpath.helpers.XPathReaderFactory;
+
+public class JaxenHandlerTest extends TestCase
+{
+    
+    private String[] paths = {
+        "foo[.='bar']",
+        "foo[.!='bar']",
+        "/",
+        "*",
+        "//foo",
+        "/*",
+        "/.",
+        "/foo[/bar[/baz]]",
+        "/foo/bar/baz[(1 or 2) + 3 * 4 + 8 and 9]",
+        "/foo/bar/baz",
+        ".[1]",
+        "self::node()",
+        ".",
+        "count(/)",
+        "foo[1]",
+        "/baz[(1 or 2) + 3 * 4 + 8 and 9]",
+        "foo/bar[/baz[(1 or 2) - 3 mod 4 + 8 and 9 div 8]]",
+        "foo/bar/yeah:baz[a/b/c and toast]",
+        "/foo/bar[../x='123']",
+        "/foo[@bar='1234']",
+        "foo|bar",
+        "/foo|/bar[@id='1234']",
+        "count(//author/attribute::*)",
+        "$author",
+         "10 + $foo",
+        "10 + (count(descendant::author) * 5)",
+        "10 + count(descendant::author) * 5",
+        "2 + (2 * 5)",
+        "sum(count(//author), 5)",
+        "sum(count(//author),count(//author/attribute::*))",
+        "12 + sum(count(//author),count(//author/attribute::*)) div 2",
+        "text()[.='foo']",
+        "/*/*[@id='123']",
+        "/child::node()/child::node()[@id='_13563275']",
+        "$foo:bar",
+        "//foo:bar",
+        "/foo/bar[@a='1' and @c!='2']",
+    };
+
+    private String[] bogusPaths = { "//:p" ,       
+        // this path is bogus because of a trailing /
+        "/foo/bar/",
+        
+        // This path is bogus because '/' is not division, but
+        // rather just the step separator.
+        "12 + sum(count(//author),count(//author/attribute::*)) / 2",
+        "id()/2",
+        "+"
+    };
+    
+    public JaxenHandlerTest(String name)
+    {
+        super( name );
+    }
+
+    public void testValidPaths()
+    {
+            
+        String path = null;
+
+        try
+        {
+            // XXX Jiffie solution?
+            XPathReader reader = XPathReaderFactory.createReader();
+            JaxenHandler handler = new JaxenHandler();
+            handler.setXPathFactory( new DefaultXPathFactory() );
+            reader.setXPathHandler( handler );
+
+            for ( int i = 0; i < paths.length; i++ ) {
+                path = paths[i];
+                reader.parse(path);
+                handler.getXPathExpr(false);
+                handler.getXPathExpr();
+            }
+        }
+        catch (Exception e)
+        {
+            e.printStackTrace();
+            fail( path + " -> " + e.getMessage() );
+        }
+    }
+
+    public void testBogusPaths() throws SAXPathException
+    {
+        XPathReader reader = XPathReaderFactory.createReader();
+        JaxenHandler handler = new JaxenHandler();
+        handler.setXPathFactory( new DefaultXPathFactory() );
+        reader.setXPathHandler( handler );
+        
+        for ( int i = 0; i < bogusPaths.length; i++ ) {
+            String path = bogusPaths[i];
+
+            try
+            {                    
+                reader.parse(path);
+                XPathExpr xpath = handler.getXPathExpr(false);
+                fail( "Parsed bogus path as: " + xpath );
+            }
+            catch (XPathSyntaxException e)
+            {
+            }
+        }
+    }
+}
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/JaxenRuntimeExceptionTest.java b/libjaxen-java/src/java/test/org/jaxen/test/JaxenRuntimeExceptionTest.java
new file mode 100644
index 0000000..8a19fa0
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/JaxenRuntimeExceptionTest.java
@@ -0,0 +1,90 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2005 Elliotte Rusty Harold.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+
+package org.jaxen.test;
+
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+import org.jaxen.JaxenException;
+import org.jaxen.JaxenRuntimeException;
+
+import junit.framework.TestCase;
+
+
+/**
+ * @author Elliotte Rusty Harold
+ *
+ */
+public class JaxenRuntimeExceptionTest extends TestCase {
+
+    public JaxenRuntimeExceptionTest(String name) {
+        super(name);
+    }
+
+    public void testMessageIsNonNull() {
+        
+        JaxenException ex = new JaxenException("Hello");
+        JaxenRuntimeException rex = new JaxenRuntimeException(ex);
+        assertEquals(ex.getMessage(), rex.getMessage());
+        assertEquals(ex, rex.getCause());
+        
+    }    
+  
+    public void testPrintStackTrace() {
+        JaxenException cause = new JaxenException("1234");
+        JaxenRuntimeException ex = new JaxenRuntimeException(cause);
+        StringWriter out = new StringWriter();
+        PrintWriter pw = new PrintWriter(out);
+        ex.printStackTrace(pw);
+        pw.close();
+        assertTrue(out.toString().indexOf("Caused by: org.jaxen.JaxenException") > 0);
+        assertTrue(out.toString().indexOf("1234") > 0);
+    }
+    
+}
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/JaxenTests.java b/libjaxen-java/src/java/test/org/jaxen/test/JaxenTests.java
new file mode 100644
index 0000000..4e2b172
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/JaxenTests.java
@@ -0,0 +1,86 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2005 Elliotte Rusty Harold.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+
+
+package org.jaxen.test;
+
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+/**
+ * <p>
+ *   Collect all the Jaxen tests into one suite.
+ * </p>
+ * 
+ * @author Elliotte Rusty Harold
+ * @version 1.1b9
+ *
+ */
+public class JaxenTests {
+
+    
+    public static Test suite() {
+        
+        TestSuite result = new TestSuite();
+        result.addTest(SAXPathTests.suite());
+        result.addTest(FunctionTests.suite());
+        result.addTest(CoreTests.suite());
+        result.addTest(DOMTests.suite());
+        result.addTest(JDOMTests.suite());
+        result.addTest(JavaBeanTests.suite());
+        result.addTest(PatternTests.suite());
+        result.addTest(BaseTests.suite());
+        result.addTest(HelpersTests.suite());
+        result.addTest(ExprTests.suite());
+        result.addTest(UtilTests.suite());
+        return result;
+        
+    }
+
+    
+}
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/LangTest.java b/libjaxen-java/src/java/test/org/jaxen/test/LangTest.java
new file mode 100644
index 0000000..f12d492
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/LangTest.java
@@ -0,0 +1,347 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2005 Elliotte Rusty Harold
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+
+package org.jaxen.test;
+
+import java.util.List;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import junit.framework.TestCase;
+
+import org.jaxen.BaseXPath;
+import org.jaxen.FunctionCallException;
+import org.jaxen.JaxenException;
+import org.jaxen.dom.DOMXPath;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ * @author Elliotte Rusty Harold
+ *
+ */
+public class LangTest extends TestCase {
+
+    private Document doc;
+    private DocumentBuilder builder;
+    
+    public void setUp() throws ParserConfigurationException
+    {
+        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        factory.setNamespaceAware(true);
+        builder = factory.newDocumentBuilder();
+        doc = builder.newDocument();
+    }
+
+    public LangTest(String name) {
+        super(name);
+    }
+
+    public void testLangFunction() 
+      throws JaxenException {
+        
+        BaseXPath xpath = new DOMXPath("//*[lang('en')]");
+        Element a = doc.createElementNS("", "a");
+        Element b = doc.createElementNS("", "b");
+        b.setAttributeNS("http://www.w3.org/XML/1998/namespace", "xml:lang", "en");
+        doc.appendChild(a);
+        a.appendChild(b);
+        Element x2 = doc.createElementNS("", "x");
+        Element x3 = doc.createElementNS("", "x");
+        Element x4 = doc.createElementNS("", "x");
+        a.appendChild(x4);
+        b.appendChild(x2);
+        b.appendChild(x3);
+        x2.appendChild(doc.createTextNode("2"));
+        x3.appendChild(doc.createTextNode("3"));
+        x4.appendChild(doc.createTextNode("4"));
+        
+        List result = xpath.selectNodes(doc);
+        assertEquals(3, result.size());
+        assertEquals(b, result.get(0));
+        assertEquals(x2, result.get(1));
+        assertEquals(x3, result.get(2));
+        
+    }    
+
+    public void testLangFunctionSelectsNothing() 
+      throws JaxenException {
+        
+        BaseXPath xpath = new DOMXPath("//*[lang('fr')]");
+        Element a = doc.createElementNS("", "a");
+        Element b = doc.createElementNS("", "b");
+        b.setAttributeNS("http://www.w3.org/XML/1998/namespace", "xml:lang", "en");
+        doc.appendChild(a);
+        a.appendChild(b);
+        Element x2 = doc.createElementNS("", "x");
+        Element x3 = doc.createElementNS("", "x");
+        Element x4 = doc.createElementNS("", "x");
+        a.appendChild(x4);
+        b.appendChild(x2);
+        b.appendChild(x3);
+        x2.appendChild(doc.createTextNode("2"));
+        x3.appendChild(doc.createTextNode("3"));
+        x4.appendChild(doc.createTextNode("4"));
+        
+        List result = xpath.selectNodes(doc);
+        assertEquals(0, result.size());
+        
+    }    
+
+    public void testLangFunctionSelectsSubcode() 
+      throws JaxenException {
+        
+        BaseXPath xpath = new DOMXPath("//*[lang('fr')]");
+        Element a = doc.createElementNS("", "a");
+        Element b = doc.createElementNS("", "b");
+        b.setAttributeNS("http://www.w3.org/XML/1998/namespace", "xml:lang", "fr-CA");
+        doc.appendChild(a);
+        a.appendChild(b);
+        Element x2 = doc.createElementNS("", "x");
+        Element x3 = doc.createElementNS("", "x");
+        Element x4 = doc.createElementNS("", "x");
+        a.appendChild(x4);
+        b.appendChild(x2);
+        b.appendChild(x3);
+        x2.appendChild(doc.createTextNode("2"));
+        x3.appendChild(doc.createTextNode("3"));
+        x4.appendChild(doc.createTextNode("4"));
+        
+        List result = xpath.selectNodes(doc);
+        assertEquals(3, result.size());
+        assertEquals(b, result.get(0));
+        assertEquals(x2, result.get(1));
+        assertEquals(x3, result.get(2));
+        
+    }    
+
+    public void testHyphenRequiredAtEnd() 
+      throws JaxenException {
+        
+        BaseXPath xpath = new DOMXPath("//*[lang('f')]");
+        Element a = doc.createElementNS("", "a");
+        Element b = doc.createElementNS("", "b");
+        b.setAttributeNS("http://www.w3.org/XML/1998/namespace", "xml:lang", "fr-CA");
+        doc.appendChild(a);
+        a.appendChild(b);
+        Element x2 = doc.createElementNS("", "x");
+        Element x3 = doc.createElementNS("", "x");
+        Element x4 = doc.createElementNS("", "x");
+        a.appendChild(x4);
+        b.appendChild(x2);
+        b.appendChild(x3);
+        x2.appendChild(doc.createTextNode("2"));
+        x3.appendChild(doc.createTextNode("3"));
+        x4.appendChild(doc.createTextNode("4"));
+        
+        List result = xpath.selectNodes(doc);
+        assertEquals(0, result.size());
+        
+    }    
+
+    public void testLangFunctionSelectsEmptyNodeSet() 
+      throws JaxenException {
+        
+        BaseXPath xpath = new DOMXPath("//*[lang(d)]");
+        // This node-set will be empty. Therefore it's the same as the
+        // empty string. Therefore it matches all languages.
+        Element a = doc.createElementNS("", "a");
+        Element b = doc.createElementNS("", "b");
+        b.setAttributeNS("http://www.w3.org/XML/1998/namespace", "xml:lang", "fr-CA");
+        doc.appendChild(a);
+        a.appendChild(b);
+        Element x2 = doc.createElementNS("", "x");
+        Element x3 = doc.createElementNS("", "x");
+        Element x4 = doc.createElementNS("", "x");
+        a.appendChild(x4);
+        b.appendChild(x2);
+        b.appendChild(x3);
+        x2.appendChild(doc.createTextNode("2"));
+        x3.appendChild(doc.createTextNode("3"));
+        x4.appendChild(doc.createTextNode("4"));
+        
+        List result = xpath.selectNodes(doc);
+        assertEquals(0, result.size());
+        
+    }    
+
+    public void testLangFunctionSelectsNonEmptyNodeSet() 
+      throws JaxenException {
+        
+        BaseXPath xpath = new DOMXPath("//*[lang(x)]");
+        Element a = doc.createElementNS("", "a");
+        Element b = doc.createElementNS("", "b");
+        b.setAttributeNS("http://www.w3.org/XML/1998/namespace", "xml:lang", "fr-CA");
+        doc.appendChild(a);
+        a.appendChild(b);
+        Element x2 = doc.createElementNS("", "x");
+        Element x3 = doc.createElementNS("", "x");
+        Element x4 = doc.createElementNS("", "x");
+        a.appendChild(x4);
+        b.appendChild(x2);
+        b.appendChild(x3);
+        x2.appendChild(doc.createTextNode("fr"));
+        x3.appendChild(doc.createTextNode("3"));
+        x4.appendChild(doc.createTextNode("4"));
+        
+        List result = xpath.selectNodes(doc);
+        assertEquals(1, result.size());
+        assertEquals(b, result.get(0));
+        
+    }    
+
+    public void testLangFunctionAppliedToNonElement() 
+      throws JaxenException {
+        
+        BaseXPath xpath = new DOMXPath("//text()[lang('fr')]");
+        Element a = doc.createElementNS("", "a");
+        Element b = doc.createElementNS("", "b");
+        b.setAttributeNS("http://www.w3.org/XML/1998/namespace", "xml:lang", "fr-CA");
+        doc.appendChild(a);
+        a.appendChild(b);
+        Element x2 = doc.createElementNS("", "x");
+        Element x3 = doc.createElementNS("", "x");
+        Element x4 = doc.createElementNS("", "x");
+        a.appendChild(x4);
+        b.appendChild(x2);
+        b.appendChild(x3);
+        x2.appendChild(doc.createTextNode("fr"));
+        x3.appendChild(doc.createTextNode("3"));
+        x4.appendChild(doc.createTextNode("4"));
+        
+        List result = xpath.selectNodes(doc);
+        assertEquals(2, result.size());
+        assertEquals(x2.getFirstChild(), result.get(0));
+        assertEquals(x3.getFirstChild(), result.get(1));
+        
+    }    
+
+    public void testLangFunctionAppliedToDocument() 
+      throws JaxenException {
+        
+        BaseXPath xpath = new DOMXPath("lang('fr')");
+        Element a = doc.createElementNS("", "a");
+        Element b = doc.createElementNS("", "b");
+        b.setAttributeNS("http://www.w3.org/XML/1998/namespace", "xml:lang", "fr-CA");
+        doc.appendChild(a);
+        a.appendChild(b);
+        Element x2 = doc.createElementNS("", "x");
+        Element x3 = doc.createElementNS("", "x");
+        Element x4 = doc.createElementNS("", "x");
+        a.appendChild(x4);
+        b.appendChild(x2);
+        b.appendChild(x3);
+        x2.appendChild(doc.createTextNode("fr"));
+        x3.appendChild(doc.createTextNode("3"));
+        x4.appendChild(doc.createTextNode("4"));
+        
+        Boolean result = (Boolean) xpath.evaluate(doc);
+        assertEquals(Boolean.FALSE, result);
+        
+    }    
+
+    public void testLangFunctionSelectsNumber() 
+      throws JaxenException {
+        
+        BaseXPath xpath = new DOMXPath("//*[lang(3)]");
+        
+        Element a = doc.createElementNS("", "a");
+        Element b = doc.createElementNS("", "b");
+        b.setAttributeNS("http://www.w3.org/XML/1998/namespace", "xml:lang", "fr-CA");
+        doc.appendChild(a);
+        a.appendChild(b);
+        Element x2 = doc.createElementNS("", "x");
+        Element x3 = doc.createElementNS("", "x");
+        Element x4 = doc.createElementNS("", "x");
+        a.appendChild(x4);
+        b.appendChild(x2);
+        b.appendChild(x3);
+        x2.appendChild(doc.createTextNode("2"));
+        x3.appendChild(doc.createTextNode("3"));
+        x4.appendChild(doc.createTextNode("4"));
+        
+        List result = xpath.selectNodes(doc);
+        assertEquals(0, result.size());
+        
+    }    
+
+    public void testLangFunctionRequiresOneArgument() 
+      throws JaxenException {
+        
+        try {
+            BaseXPath xpath = new DOMXPath("lang()");
+            org.w3c.dom.Element a = doc.createElementNS("", "a");
+            doc.appendChild(a);
+            xpath.selectNodes(doc);
+            fail("Allowed empty lang() function");
+        }
+        catch (FunctionCallException success) {
+            assertNotNull(success.getMessage());
+        }
+        
+    }    
+
+    public void testLangFunctionRequiresAtMostOneArgument() 
+      throws JaxenException {
+        
+        try {
+            BaseXPath xpath = new DOMXPath("lang('en', 'fr')");
+            org.w3c.dom.Element a = doc.createElementNS("", "a");
+            doc.appendChild(a);
+            xpath.selectNodes(doc);
+            fail("Allowed empty lang() function");
+        }
+        catch (FunctionCallException success) {
+            assertNotNull(success.getMessage());
+        }
+        
+    }    
+
+
+}
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/LastTest.java b/libjaxen-java/src/java/test/org/jaxen/test/LastTest.java
new file mode 100644
index 0000000..0195b42
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/LastTest.java
@@ -0,0 +1,142 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2005 Elliotte Rusty Harold
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+
+package org.jaxen.test;
+
+import java.util.List;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import junit.framework.TestCase;
+
+import org.jaxen.BaseXPath;
+import org.jaxen.FunctionCallException;
+import org.jaxen.JaxenException;
+import org.jaxen.dom.DOMXPath;
+import org.w3c.dom.Document;
+
+/**
+ * @author Elliotte Rusty Harold
+ *
+ */
+public class LastTest extends TestCase {
+
+    private Document doc;
+    
+    public void setUp() throws ParserConfigurationException
+    {
+        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        factory.setNamespaceAware(true);
+        DocumentBuilder builder = factory.newDocumentBuilder();
+        doc = builder.newDocument();
+    }
+
+
+    public LastTest(String name) {
+        super(name);
+    }
+
+    // test case for JAXEN-55
+    public void testLastFunction() 
+      throws JaxenException {
+        
+        BaseXPath xpath = new DOMXPath("//x[position()=last()]");
+        org.w3c.dom.Element a = doc.createElementNS("", "a");
+        org.w3c.dom.Element b = doc.createElementNS("", "b");
+        doc.appendChild(a);
+        a.appendChild(b);
+        org.w3c.dom.Element x2 = doc.createElementNS("", "x");
+        org.w3c.dom.Element x3 = doc.createElementNS("", "x");
+        org.w3c.dom.Element x4 = doc.createElementNS("", "x");
+        a.appendChild(x4);
+        b.appendChild(x2);
+        b.appendChild(x3);
+        x2.appendChild(doc.createTextNode("2"));
+        x3.appendChild(doc.createTextNode("3"));
+        x4.appendChild(doc.createTextNode("4"));
+        
+        List result = xpath.selectNodes(doc);
+        assertEquals(2, result.size());
+        assertEquals(x3, result.get(0));
+        assertEquals(x4, result.get(1));
+        
+    }    
+
+    public void testLastFunctionAllowsNoArguments() throws JaxenException
+    {
+        try
+        {
+            BaseXPath xpath = new DOMXPath("//x[position()=last(.)]");
+            org.w3c.dom.Element a = doc.createElementNS("", "a");
+            org.w3c.dom.Element b = doc.createElementNS("", "b");
+            doc.appendChild(a);
+            a.appendChild(b);
+            org.w3c.dom.Element x2 = doc.createElementNS("", "x");
+            org.w3c.dom.Element x3 = doc.createElementNS("", "x");
+            org.w3c.dom.Element x4 = doc.createElementNS("", "x");
+            a.appendChild(x4);
+            b.appendChild(x2);
+            b.appendChild(x3);
+            x2.appendChild(doc.createTextNode("2"));
+            x3.appendChild(doc.createTextNode("3"));
+            x4.appendChild(doc.createTextNode("4"));
+       
+            xpath.selectNodes(doc);
+            fail("last() function took arguments");
+        }
+        catch (FunctionCallException e) 
+        {
+            assertEquals("last() requires no arguments.", e.getMessage());
+        }
+    }    
+
+    
+    
+    
+}
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/LocalNameTest.java b/libjaxen-java/src/java/test/org/jaxen/test/LocalNameTest.java
new file mode 100644
index 0000000..7a5858e
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/LocalNameTest.java
@@ -0,0 +1,191 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2005 Elliotte Rusty Harold
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+
+package org.jaxen.test;
+
+import java.io.IOException;
+import java.util.List;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import junit.framework.TestCase;
+
+import org.jaxen.FunctionCallException;
+import org.jaxen.JaxenException;
+import org.jaxen.XPath;
+import org.jaxen.dom.DOMXPath;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Comment;
+import org.w3c.dom.Document;
+import org.w3c.dom.ProcessingInstruction;
+import org.w3c.dom.Text;
+import org.xml.sax.SAXException;
+
+/**
+ * @author Elliotte Rusty Harold
+ *
+ */
+public class LocalNameTest extends TestCase {
+
+    private Document doc;
+    
+    public void setUp() throws ParserConfigurationException, SAXException, IOException
+    {
+        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        factory.setNamespaceAware(true);
+        DocumentBuilder builder = factory.newDocumentBuilder();
+        doc = builder.parse( "xml/basic.xml" );
+    }
+
+
+    public LocalNameTest(String name) {
+        super(name);
+    }
+
+    public void testLocalNameOfNumber() throws JaxenException
+    {
+        try
+        {
+            XPath xpath = new DOMXPath( "local-name(3)" );
+            xpath.selectNodes( doc );
+            fail("local-name of non-node-set");
+        }
+        catch (FunctionCallException e) 
+        {
+           assertEquals("The argument to the local-name function must be a node-set", e.getMessage());
+        }
+    }    
+
+    public void testLocalNameWithTwoArguments() throws JaxenException
+    {
+        try
+        {
+            XPath xpath = new DOMXPath( "local-name(/*, //*)" );
+            xpath.selectNodes( doc );
+            fail("local-name with two arguments");
+        }
+        catch (FunctionCallException e) 
+        {
+           assertEquals("local-name() requires zero or one argument.", e.getMessage());
+        }
+    }    
+
+    public void testLocalNameAllowsNoArguments() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "local-name()" );
+        String result = (String) xpath.evaluate( doc.getDocumentElement() );
+        assertEquals("foo", result);
+    }    
+
+    public void testLocalNameOfCommentIsEmptyString() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "local-name(/comment())" );
+        Comment c = doc.createComment("test");
+        doc.appendChild(c);
+        String result = (String) xpath.evaluate(doc);
+        assertEquals("", result);
+    }    
+
+    public void testLocalNameOfEmptyNodeSetIsEmptyString() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "local-name(/aaa)" );
+        String result = (String) xpath.evaluate(doc);
+        assertEquals("", result);
+    }    
+
+    public void testLocalNameOfProcessingInstructionIsTarget() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "local-name(/processing-instruction())" );
+        ProcessingInstruction pi = doc.createProcessingInstruction("target", "value");
+        doc.appendChild(pi);
+        String result = (String) xpath.evaluate(doc);
+        assertEquals("target", result);
+    }    
+
+    public void testLocalNameOfAttribute() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "local-name(/*/@*)" );
+        Attr a = doc.createAttribute("name");
+        doc.getDocumentElement().setAttributeNode(a);
+        String result = (String) xpath.evaluate(doc);
+        assertEquals("name", result);
+    }    
+
+    public void testLocalNameOfTextIsEmptyString() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "local-name(/*/text())" );
+        Text c = doc.createTextNode("test");
+        doc.getDocumentElement().appendChild(c);
+        String result = (String) xpath.evaluate(doc);
+        assertEquals("", result);
+    }    
+
+    public void testLocalNameOfNamespaceIsPrefix() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "local-name(/*/namespace::node())" );
+        String result = (String) xpath.evaluate(doc);
+        assertEquals("xml", result);
+    }    
+
+    public void testLocalNameNoArguments()
+    {
+        try
+        {
+            XPath xpath = new DOMXPath( "local-name()" );
+            List results = xpath.selectNodes( doc );
+            assertEquals("", results.get(0));
+       }
+       catch (Exception e)
+        {
+            e.printStackTrace();
+            fail( e.getMessage() );
+        }
+    }    
+
+}
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/MockXPathReader.java b/libjaxen-java/src/java/test/org/jaxen/test/MockXPathReader.java
new file mode 100644
index 0000000..0f60cbe
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/MockXPathReader.java
@@ -0,0 +1,72 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Jaxen Project and was originally
+ * created by bob mcwhirter <bob at werken.com> and
+ * James Strachan <jstrachan at apache.org>.  For more information on the
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ *
+ * $Id$
+ */
+
+
+
+package org.jaxen.test;
+
+import org.jaxen.saxpath.XPathHandler;
+import org.jaxen.saxpath.XPathReader;
+
+
+public class MockXPathReader implements XPathReader
+{
+
+    public void parse(String xpath)
+    {
+    }
+
+    public void setXPathHandler(XPathHandler handler)
+    {
+    }
+
+    public XPathHandler getXPathHandler()
+    {
+        return null;
+    }
+}
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/ModTest.java b/libjaxen-java/src/java/test/org/jaxen/test/ModTest.java
new file mode 100644
index 0000000..6d472db
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/ModTest.java
@@ -0,0 +1,90 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+
+
+
+package org.jaxen.test;
+
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.jaxen.JaxenException;
+import org.jaxen.dom.DOMXPath;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import junit.framework.TestCase;
+
+/**
+ * <p>
+ *  Test for function context.
+ * </p>
+ * 
+ * @author Elliotte Rusty Harold
+ * @version 1.1b9
+ *
+ */
+public class ModTest extends TestCase
+{
+
+    public void testModofNonIntegers() 
+      throws JaxenException, ParserConfigurationException {
+        
+        DOMXPath xpath = new DOMXPath("5.5 mod 2.5");
+        
+        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        factory.setNamespaceAware(true);
+        Document doc = factory.newDocumentBuilder().newDocument();
+        Element root = doc.createElement("root");
+        doc.appendChild(root);
+        
+        Double result = (Double) xpath.evaluate(doc);
+        assertEquals(0.5, result.doubleValue(), 0.000001);
+        
+    }
+ 
+}
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/NameTest.java b/libjaxen-java/src/java/test/org/jaxen/test/NameTest.java
new file mode 100644
index 0000000..5aab39d
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/NameTest.java
@@ -0,0 +1,184 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2005 Elliotte Rusty Harold
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+
+package org.jaxen.test;
+
+import java.io.IOException;
+import java.util.List;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import junit.framework.TestCase;
+
+import org.jaxen.FunctionCallException;
+import org.jaxen.JaxenException;
+import org.jaxen.XPath;
+import org.jaxen.dom.DOMXPath;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Comment;
+import org.w3c.dom.Document;
+import org.w3c.dom.ProcessingInstruction;
+import org.w3c.dom.Text;
+import org.xml.sax.SAXException;
+
+/**
+ * @author Elliotte Rusty Harold
+ *
+ */
+public class NameTest extends TestCase {
+
+    private Document doc;
+    
+    public void setUp() throws ParserConfigurationException, SAXException, IOException
+    {
+        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        factory.setNamespaceAware(true);
+        DocumentBuilder builder = factory.newDocumentBuilder();
+        doc = builder.parse( "xml/basic.xml" );
+    }
+
+
+    public NameTest(String name) {
+        super(name);
+    }
+
+    public void testNameOfNumber() throws JaxenException
+    {
+        try
+        {
+            XPath xpath = new DOMXPath( "name(3)" );
+            xpath.selectNodes( doc );
+            fail("name of non-node-set");
+        }
+        catch (FunctionCallException e) 
+        {
+           assertEquals("The argument to the name function must be a node-set", e.getMessage());
+        }
+    }    
+
+    public void testNameWithTwoArguments() throws JaxenException
+    {
+        try
+        {
+            XPath xpath = new DOMXPath( "name(/*, //*)" );
+            xpath.selectNodes( doc );
+            fail("name with two arguments");
+        }
+        catch (FunctionCallException e) 
+        {
+           assertEquals("name() requires zero or one argument.", e.getMessage());
+        }
+    }    
+
+    public void testNameAllowsNoArguments() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "name()" );
+        String result = (String) xpath.evaluate( doc.getDocumentElement() );
+        assertEquals("foo", result);
+    }    
+
+    public void testNameOfCommentIsEmptyString() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "name(/comment())" );
+        Comment c = doc.createComment("test");
+        doc.appendChild(c);
+        String result = (String) xpath.evaluate(doc);
+        assertEquals("", result);
+    }    
+
+    public void testNameOfProcessingInstructionIsTarget() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "name(/processing-instruction())" );
+        ProcessingInstruction pi = doc.createProcessingInstruction("target", "value");
+        doc.appendChild(pi);
+        String result = (String) xpath.evaluate(doc);
+        assertEquals("target", result);
+    }    
+
+    public void testNameOfAttribute() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "name(/*/@*)" );
+        Attr a = doc.createAttribute("name");
+        doc.getDocumentElement().setAttributeNode(a);
+        String result = (String) xpath.evaluate(doc);
+        assertEquals("name", result);
+    }    
+
+    public void testNameOfTextIsEmptyString() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "name(/*/text())" );
+        Text c = doc.createTextNode("test");
+        doc.getDocumentElement().appendChild(c);
+        String result = (String) xpath.evaluate(doc);
+        assertEquals("", result);
+    }    
+
+    public void testNameOfNamespaceIsPrefix() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "name(/*/namespace::node())" );
+        String result = (String) xpath.evaluate(doc);
+        assertEquals("xml", result);
+    }    
+
+    public void testNameNoArguments()
+    {
+        try
+        {
+            XPath xpath = new DOMXPath( "name()" );
+            List results = xpath.selectNodes( doc );
+            assertEquals("", results.get(0));
+       }
+       catch (Exception e)
+        {
+            e.printStackTrace();
+            fail( e.getMessage() );
+        }
+    }    
+
+}
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/NamespaceTest.java b/libjaxen-java/src/java/test/org/jaxen/test/NamespaceTest.java
new file mode 100644
index 0000000..9f38f6e
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/NamespaceTest.java
@@ -0,0 +1,194 @@
+/* $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2005 Elliotte Rusty Harold.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+package org.jaxen.test;
+
+import java.util.List;
+
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.jaxen.JaxenException;
+import org.jaxen.SimpleNamespaceContext;
+import org.jaxen.UnresolvableException;
+import org.jaxen.XPath;
+import org.jaxen.dom.DOMXPath;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Element;
+
+import junit.framework.TestCase;
+
+public class NamespaceTest extends TestCase {
+
+    private org.w3c.dom.Document doc;
+
+    public NamespaceTest(String name) {
+        super(name);
+    }
+    
+    protected void setUp() throws ParserConfigurationException {
+        
+        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        factory.setNamespaceAware(true);
+        doc = factory.newDocumentBuilder().newDocument();
+        
+    }     
+    
+    public void testMultipleNamespaceAxis() throws JaxenException {
+        
+        Element root = doc.createElement("root");
+        doc.appendChild(root);
+        Element child = doc.createElementNS("http://www.example.org", "child");
+        child.setAttributeNS("http://www.w3.org/2000/xmlns/" , "xmlns:pre", "value");
+        root.appendChild(child);
+        
+        XPath xpath = new DOMXPath("namespace::node()");
+        List result = xpath.selectNodes(child);
+        assertEquals(3, result.size());
+   
+    }
+    
+    public void testNumberOfNamespaceNodes() throws JaxenException {
+        
+        Element root = doc.createElement("root");
+        doc.appendChild(root);
+        Element child = doc.createElementNS("http://www.example.org", "foo:child");
+        root.appendChild(child);
+        
+        XPath xpath = new DOMXPath("//namespace::node()");
+        List result = xpath.selectNodes(doc);
+        assertEquals(3, result.size());
+        // 1 for xml prefix on root; 1 for foo prefix on child; 1 for xml prefix on child
+   
+    }
+    
+    
+    public void testNamespaceAxis() throws JaxenException {
+        
+        Element root = doc.createElement("root");
+        doc.appendChild(root);
+        Element child = doc.createElementNS("http://www.example.org", "foo:child");
+        root.appendChild(child);
+        
+        XPath xpath = new DOMXPath("namespace::node()");
+        List result = xpath.selectNodes(child);
+        assertEquals(2, result.size());
+   
+    }
+    
+    
+    public void testUnprefixedNamespaceAxis() throws JaxenException {
+        
+        Element root = doc.createElement("root");
+        doc.appendChild(root);
+        Element child = doc.createElementNS("http://www.example.org", "child");
+        root.appendChild(child);
+        
+        XPath xpath = new DOMXPath("namespace::node()");
+        List result = xpath.selectNodes(child);
+        assertEquals(2, result.size());
+   
+    }   
+    
+    
+    public void testNamespaceNodesReadFromAttributes() throws JaxenException {
+        
+        Element root = doc.createElement("root");
+        doc.appendChild(root);
+        Attr a = doc.createAttributeNS("http://www.example.org/", "a");
+        a.setNodeValue("value");
+        root.setAttributeNode(a);
+        
+        XPath xpath = new DOMXPath("namespace::node()");
+        List result = xpath.selectNodes(root);
+        // one for the xml prefix; one from the attribute node
+        assertEquals(2, result.size());
+   
+    }   
+    
+    
+    public void testUnboundNamespaceUsedInXPathExpression() throws JaxenException {
+        
+        Element root = doc.createElementNS("http://www.example.org/", "root");
+        doc.appendChild(root);
+        XPath xpath = new DOMXPath("/pre:root");
+        try {
+            xpath.selectNodes(root);
+            fail("Used unresolvable prefix");
+        }
+        catch (UnresolvableException ex) {
+            assertNotNull(ex.getMessage());
+        }
+   
+    }   
+    
+    
+    public void testQueryDefaultNamespace() throws JaxenException {
+        
+        Element root = doc.createElementNS("http://www.example.org/", "root");
+        doc.appendChild(root);
+        XPath xpath = new DOMXPath("/pre:root");
+        xpath.addNamespace("pre", "http://www.example.org/");
+        List result = xpath.selectNodes(root);
+        assertEquals(1, result.size());
+   
+    }   
+    
+    
+    public void testQueryDefaultNamespaceWithContext() throws JaxenException {
+        
+        Element root = doc.createElementNS("http://www.example.org/", "root");
+        doc.appendChild(root);
+        XPath xpath = new DOMXPath("/pre:root");
+        SimpleNamespaceContext context = new SimpleNamespaceContext();
+        context.addNamespace("pre", "http://www.example.org/");
+        xpath.setNamespaceContext(context);
+        List result = xpath.selectNodes(root);
+        assertEquals(1, result.size());
+   
+    }   
+    
+    
+}
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/NamespaceURITest.java b/libjaxen-java/src/java/test/org/jaxen/test/NamespaceURITest.java
new file mode 100644
index 0000000..88abe37
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/NamespaceURITest.java
@@ -0,0 +1,186 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2005 Elliotte Rusty Harold
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+
+package org.jaxen.test;
+
+import java.io.IOException;
+import java.util.List;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import junit.framework.TestCase;
+
+import org.jaxen.FunctionCallException;
+import org.jaxen.JaxenException;
+import org.jaxen.XPath;
+import org.jaxen.dom.DOMXPath;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
+import org.w3c.dom.ProcessingInstruction;
+import org.w3c.dom.Text;
+import org.xml.sax.SAXException;
+
+/**
+ * @author Elliotte Rusty Harold
+ *
+ */
+public class NamespaceURITest extends TestCase {
+
+    private Document doc;
+    private DocumentBuilder builder;
+    
+    public void setUp() throws ParserConfigurationException, SAXException, IOException
+    {
+        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        factory.setNamespaceAware(true);
+        builder = factory.newDocumentBuilder();
+        doc = builder.parse( "xml/basic.xml" );
+    }
+
+
+    public NamespaceURITest(String name) {
+        super(name);
+    }
+
+    public void testNamespaceURIOfNumber() throws JaxenException
+    {
+        try
+        {
+            XPath xpath = new DOMXPath( "namespace-uri(3)" );
+            xpath.selectNodes( doc );
+            fail("namespace-uri of non-node-set");
+        }
+        catch (FunctionCallException e) 
+        {
+           assertEquals("The argument to the namespace-uri function must be a node-set", e.getMessage());
+        }
+    }    
+
+    public void testNamespaceURINoArguments() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "namespace-uri()" );
+        List results = xpath.selectNodes( doc );
+        assertEquals("", results.get(0));
+    }    
+    
+    public void testNamespaceURIOfEmptyNodeSetIsEmptyString() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "namespace-uri(/aaa)" );
+        String result = (String) xpath.evaluate(doc);
+        assertEquals("", result);
+    }    
+
+    public void testNamespaceURIOfProcessingInstructionIsEmptyString() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "namespace-uri(/processing-instruction())" );
+        ProcessingInstruction pi = doc.createProcessingInstruction("target", "value");
+        doc.appendChild(pi);
+        String result = (String) xpath.evaluate(doc);
+        assertEquals("", result);
+    }    
+
+    public void testNamespaceURIOfAttribute() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "namespace-uri(/*/@*)" );
+        Attr a = doc.createAttribute("name");
+        doc.getDocumentElement().setAttributeNode(a);
+        Object result = xpath.evaluate(doc);
+        assertEquals("", result);
+    }    
+
+    public void testNamespaceURIOfAttributeInNamespace() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "namespace-uri(/*/@*)" );
+        Attr a = doc.createAttributeNS("http://www.w3.org/", "pre:name");
+        doc.getDocumentElement().setAttributeNode(a);
+        Object result = xpath.evaluate(doc);
+        assertEquals("http://www.w3.org/", result);
+    }    
+
+    public void testNamespaceURIOfTextIsEmptyString() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "namespace-uri(/*/text())" );
+        Text c = doc.createTextNode("test");
+        doc.getDocumentElement().appendChild(c);
+        String result = (String) xpath.evaluate(doc);
+        assertEquals("", result);
+    }    
+
+    public void testNamespaceURIRequiresAtMostOneArgument() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "namespace-uri(/*, /*)" );
+        try {
+            xpath.evaluate(doc);
+            fail("Allowed namespace-uri function with no arguments");
+        }
+        catch (FunctionCallException ex) {
+            assertNotNull(ex.getMessage());
+        }
+    }    
+
+    public void testNamespaceURIOfNamespaceIsNull() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "namespace-uri(/*/namespace::node())" );
+        String result = (String) xpath.evaluate(doc);
+        assertEquals("", result);
+    }
+    
+    public void testNamespaceURIOfComment() 
+      throws JaxenException {
+        
+        XPath xpath = new DOMXPath("namespace-uri(/a/comment())");
+        Document document = builder.getDOMImplementation().createDocument(null, "a", null);
+        document.getDocumentElement().appendChild(document.createComment("data"));
+        
+        String result = (String) xpath.evaluate(document);
+        assertEquals("", result);
+        
+    }
+
+}
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/NormalizeSpaceTest.java b/libjaxen-java/src/java/test/org/jaxen/test/NormalizeSpaceTest.java
new file mode 100644
index 0000000..4ff72f5
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/NormalizeSpaceTest.java
@@ -0,0 +1,125 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2005 Elliotte Rusty Harold.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+
+package org.jaxen.test;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import junit.framework.TestCase;
+
+import org.jaxen.BaseXPath;
+import org.jaxen.FunctionCallException;
+import org.jaxen.JaxenException;
+import org.jaxen.XPath;
+import org.jaxen.dom.DOMXPath;
+import org.w3c.dom.Document;
+
+/**
+ * @author Elliotte Rusty Harold
+ *
+ */
+public class NormalizeSpaceTest extends TestCase {
+
+    private Document doc;
+    
+    public void setUp() throws ParserConfigurationException
+    {
+        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        factory.setNamespaceAware(true);
+        DocumentBuilder builder = factory.newDocumentBuilder();
+        doc = builder.newDocument();
+        doc.appendChild(doc.createElement("root"));
+    }
+
+
+    public NormalizeSpaceTest(String name) {
+        super(name);
+    }
+
+    public void testNormalizeSpaceUsesXMLSpaceRulesNotJavaRules() throws JaxenException
+    {
+        // em space counts as whitespace in Java but not XML
+        String data = "\u2003X\u2003";
+        XPath xpath = new DOMXPath( "normalize-space('" + data + "')" );
+        String result = (String) xpath.evaluate( doc );
+        assertEquals(data, result);
+    }    
+  
+    public void testNormalizeSpaceUsesXMLSpaceRulesNotJavaRules2() throws JaxenException
+    {
+        // em space counts as whitespace in Java but not XML
+        String data = "\u2003X\u2003";
+        XPath xpath = new DOMXPath( "normalize-space(' " + data + " ')" );
+        String result = (String) xpath.evaluate( doc );
+        assertEquals(data, result);
+    }    
+  
+    public void testNormalizeSpaceInContextNode() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "normalize-space()" );
+        String result = (String) xpath.evaluate( doc );
+        assertEquals("", result);
+    }    
+  
+    public void testNormalizeSpaceRequiresAtMostOneArguments() 
+      throws JaxenException {
+        
+        BaseXPath xpath = new DOMXPath("normalize-space('a', 'a')");
+        
+        try {
+            xpath.selectNodes(doc);
+            fail("Allowed normalize-space function with two arguments");
+        }
+        catch (FunctionCallException ex) {
+            assertNotNull(ex.getMessage());
+        }
+        
+    }    
+
+}
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/NotTest.java b/libjaxen-java/src/java/test/org/jaxen/test/NotTest.java
new file mode 100644
index 0000000..e2b404a
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/NotTest.java
@@ -0,0 +1,169 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2005 Elliotte Rusty Harold.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+
+package org.jaxen.test;
+
+import java.util.List;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import junit.framework.TestCase;
+
+import org.jaxen.BaseXPath;
+import org.jaxen.FunctionCallException;
+import org.jaxen.JaxenException;
+import org.jaxen.dom.DOMXPath;
+import org.w3c.dom.Document;
+
+/**
+ * @author Elliotte Rusty Harold
+ *
+ */
+public class NotTest extends TestCase {
+
+    private Document doc;
+    
+    public void setUp() throws ParserConfigurationException
+    {
+        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        factory.setNamespaceAware(true);
+        DocumentBuilder builder = factory.newDocumentBuilder();
+        doc = builder.newDocument();
+        doc.appendChild(doc.createElement("root"));
+    }
+
+
+    public NotTest(String name) {
+        super(name);
+    }
+
+    public void testZeroIsFalse() 
+      throws JaxenException {
+        
+        BaseXPath xpath = new DOMXPath("not(0)");
+        
+        List result = xpath.selectNodes(doc);
+        assertEquals(1, result.size());
+        assertEquals(Boolean.TRUE, result.get(0));
+        
+    }    
+
+    public void testOneIsTrue() 
+      throws JaxenException {
+        
+        BaseXPath xpath = new DOMXPath("not(1)");
+        
+        List result = xpath.selectNodes(doc);
+        assertEquals(1, result.size());
+        assertEquals(Boolean.FALSE, result.get(0));
+        
+    }    
+
+    public void testEmptyStringIsFalse() 
+      throws JaxenException {
+        
+        BaseXPath xpath = new DOMXPath("not('')");
+        
+        List result = xpath.selectNodes(doc);
+        assertEquals(1, result.size());
+        assertEquals(Boolean.TRUE, result.get(0));
+        
+    }    
+
+    public void testNaNIsFalse() 
+      throws JaxenException {
+        
+        BaseXPath xpath = new DOMXPath("not(0 div 0)");
+        Object result = xpath.evaluate(null);
+        assertEquals(Boolean.TRUE, result);
+        
+    }    
+
+    public void testNonEmptyStringIsTrue() 
+      throws JaxenException {
+        
+        BaseXPath xpath = new DOMXPath("not('false')");
+        
+        List result = xpath.selectNodes(doc);
+        assertEquals(1, result.size());
+        assertEquals(Boolean.FALSE, result.get(0));
+        
+    }    
+
+    public void testNotFunctionRequiresOneArgument() 
+      throws JaxenException {
+        
+        BaseXPath xpath = new DOMXPath("not()");
+        
+        try {
+            xpath.selectNodes(doc);
+            fail("Allowed not() function with no arguments");
+        }
+        catch (FunctionCallException ex) {
+            assertNotNull(ex.getMessage());
+        }
+        
+    }    
+
+    public void testNotFunctionRequiresExactlyOneArgument() 
+      throws JaxenException {
+        
+        BaseXPath xpath = new DOMXPath("not('', '')");
+        
+        try {
+            xpath.selectNodes(doc);
+            fail("Allowed not() function with two arguments");
+        }
+        catch (FunctionCallException ex) {
+            assertNotNull(ex.getMessage());
+        }
+        
+    }    
+
+}
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/NumberTest.java b/libjaxen-java/src/java/test/org/jaxen/test/NumberTest.java
new file mode 100644
index 0000000..12dff02
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/NumberTest.java
@@ -0,0 +1,155 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2005 Elliotte Rusty Harold.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+
+package org.jaxen.test;
+
+import java.util.List;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import junit.framework.TestCase;
+
+import org.jaxen.FunctionCallException;
+import org.jaxen.JaxenException;
+import org.jaxen.XPath;
+import org.jaxen.dom.DOMXPath;
+import org.jaxen.function.NumberFunction;
+import org.w3c.dom.Document;
+
+/**
+ * @author Elliotte Rusty Harold
+ *
+ */
+public class NumberTest extends TestCase {
+
+    private Document doc;
+    
+    public void setUp() throws ParserConfigurationException
+    {
+        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        factory.setNamespaceAware(true);
+        DocumentBuilder builder = factory.newDocumentBuilder();
+        doc = builder.newDocument();
+    }
+
+
+    public NumberTest(String name) {
+        super(name);
+    }
+
+    // test case for JAXEN-55
+    public void testNumberFunctionOperatesOnFirstNodeInDocumentOrder() 
+      throws JaxenException {
+        
+        XPath xpath = new DOMXPath("number(//x)");
+        org.w3c.dom.Element a = doc.createElementNS("", "a");
+        org.w3c.dom.Element b = doc.createElementNS("", "b");
+        doc.appendChild(a);
+        a.appendChild(b);
+        org.w3c.dom.Element x2 = doc.createElementNS("", "x");
+        org.w3c.dom.Element x3 = doc.createElementNS("", "x");
+        org.w3c.dom.Element x4 = doc.createElementNS("", "x");
+        a.appendChild(x4);
+        b.appendChild(x2);
+        b.appendChild(x3);
+        x2.appendChild(doc.createTextNode("2"));
+        x3.appendChild(doc.createTextNode("3"));
+        x4.appendChild(doc.createTextNode("4"));
+        
+        List result = xpath.selectNodes(doc);
+        assertEquals(1, result.size());
+        assertEquals(Double.valueOf("2.0"), result.get(0));
+        
+    }    
+
+    public void testNumberFunctionOperatesOnContextNode() 
+      throws JaxenException {
+        
+        XPath xpath = new DOMXPath("number()");
+        org.w3c.dom.Element a = doc.createElementNS("", "a");
+        doc.appendChild(a);
+        a.appendChild(doc.createTextNode("2"));
+        
+        Double result = (Double) xpath.evaluate(doc);
+        assertEquals(2, result.intValue());
+        
+    }    
+
+
+    public void testNumberFunctionRequiresAtMostOneArgument() 
+      throws JaxenException {
+        
+        XPath xpath = new DOMXPath("number('2.2', '1.2')");
+        
+        try {
+            xpath.selectNodes(doc);
+            fail("Allowed number function with two arguments");
+        }
+        catch (FunctionCallException ex) {
+            assertNotNull(ex.getMessage());
+        }
+        
+    }     
+    
+    
+    public void testNumberFunctionAppliedToNonNumericString() 
+      throws JaxenException {
+        
+        XPath xpath = new DOMXPath("number('Marx')");
+        
+        Double result = (Double) xpath.evaluate(doc);
+        assertEquals(new Double(Double.NaN), result);
+        
+    }     
+    
+    public void testIsNan() {
+        assertTrue(NumberFunction.isNaN(0.0 / 0.0));
+    }     
+    
+}
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/PatternHandlerTest.java b/libjaxen-java/src/java/test/org/jaxen/test/PatternHandlerTest.java
new file mode 100644
index 0000000..2dee268
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/PatternHandlerTest.java
@@ -0,0 +1,122 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+
+
+
+package org.jaxen.test;
+
+import junit.framework.TestCase;
+
+import org.jaxen.JaxenException;
+import org.jaxen.pattern.Pattern;
+import org.jaxen.pattern.PatternParser;
+import org.jaxen.saxpath.SAXPathException;
+import org.jaxen.saxpath.XPathSyntaxException;
+
+public class PatternHandlerTest extends TestCase
+{
+    
+    String[] paths = {
+        "foo",
+        "*",
+        "/",
+        "foo/bar",
+        "foo//bar",
+        "/*/foo",
+        "*[@name]",
+        "foo/bar[1]",
+        "foo[bar=\"contents\"]",
+        "foo[bar='contents']",
+        "foo|bar",
+        "foo/title | bar/title | xyz/title",
+        "/foo//*",
+        "foo/text()",
+        "foo/@*",
+    };
+
+    String[] bogusPaths = { };
+    
+    String[] ignore_bogusPaths = {        
+        // this path is bogus because of a trailing /
+        "/foo/bar/",
+        
+        // This path is bogus because '/' is not division, but
+        // rather just the step separator.
+        "12 + sum(count(//author),count(//author/attribute::*)) / 2",
+        "id()/2",
+        "+"
+    };
+    
+    public PatternHandlerTest(String name)
+    {
+        super( name );
+    }
+
+    public void testValidPaths() throws JaxenException, SAXPathException
+    {
+        for ( int i = 0; i < paths.length; i++ ) {
+            String path = paths[i];
+            PatternParser.parse( path );
+        }
+    }
+
+    public void testBogusPaths() throws JaxenException, SAXPathException
+    {
+        for ( int i = 0; i < bogusPaths.length; i++ ) {
+            String path = bogusPaths[i];
+            try
+            {                    
+                Pattern pattern = PatternParser.parse( path );
+                fail( "Parsed bogus path as: " + pattern );
+            }
+            catch (XPathSyntaxException e)
+            {                    
+            }
+        }
+
+    }
+}
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/PatternTests.java b/libjaxen-java/src/java/test/org/jaxen/test/PatternTests.java
new file mode 100644
index 0000000..3522da8
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/PatternTests.java
@@ -0,0 +1,73 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2005 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+
+
+package org.jaxen.test;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+/**
+ * <p>
+ *   Collect the org.jaxen.pattern tests.
+ * </p>
+ * 
+ * @author Elliotte Rusty Harold
+ * @version 1.1b9
+ *
+ */
+public class PatternTests {
+
+    public static Test suite() {
+        
+        TestSuite result = new TestSuite();
+        result.addTest(new TestSuite(PatternHandlerTest.class));
+        return result;
+        
+    }
+    
+}
\ No newline at end of file
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/Person.java b/libjaxen-java/src/java/test/org/jaxen/test/Person.java
new file mode 100644
index 0000000..b4c73e9
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/Person.java
@@ -0,0 +1,44 @@
+package org.jaxen.test;
+
+import java.util.Set;
+import java.util.HashSet;
+
+public class Person
+{
+    private String name;
+    private int age;
+
+    private Set brothers;
+
+    Person(String name, int age)
+    {
+        this.name = name;
+        this.age  = age;
+        this.brothers = new HashSet();
+    }
+
+    public String getName()
+    {
+        return this.name;
+    }
+
+    public int getAge()
+    {
+        return this.age;
+    }
+
+    void addBrother(Person brother)
+    {
+        this.brothers.add( brother );
+    }
+
+    public Set getBrothers()
+    {
+        return this.brothers;
+    }
+
+    public String toString()
+    {
+        return "[Person: " + this.name + "]";
+    }
+}
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/PositionTest.java b/libjaxen-java/src/java/test/org/jaxen/test/PositionTest.java
new file mode 100644
index 0000000..cc6e2cc
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/PositionTest.java
@@ -0,0 +1,98 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2005 Elliotte Rusty Harold.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+
+package org.jaxen.test;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import junit.framework.TestCase;
+
+import org.jaxen.FunctionCallException;
+import org.jaxen.JaxenException;
+import org.jaxen.XPath;
+import org.jaxen.dom.DOMXPath;
+import org.w3c.dom.Document;
+
+/**
+ * @author Elliotte Rusty Harold
+ *
+ */
+public class PositionTest extends TestCase {
+
+    private Document doc;
+    
+    public void setUp() throws ParserConfigurationException
+    {
+        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        factory.setNamespaceAware(true);
+        DocumentBuilder builder = factory.newDocumentBuilder();
+        doc = builder.newDocument();
+        doc.appendChild(doc.createElement("root"));
+    }
+
+
+    public PositionTest(String name) {
+        super(name);
+    }
+
+    public void testPositionOfNumber() throws JaxenException
+    {
+        try
+        {
+            XPath xpath = new DOMXPath( "position(3)" );
+            xpath.selectNodes( doc );
+            fail("position() function took arguments");
+        }
+        catch (FunctionCallException e) 
+        {
+            assertEquals("position() does not take any arguments.", e.getMessage());
+        }
+    }    
+
+}
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/PrecedingAxisIteratorTest.java b/libjaxen-java/src/java/test/org/jaxen/test/PrecedingAxisIteratorTest.java
new file mode 100644
index 0000000..0d052ec
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/PrecedingAxisIteratorTest.java
@@ -0,0 +1,109 @@
+/* $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2005 Elliotte Rusty Harold.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+package org.jaxen.test;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.jaxen.UnsupportedAxisException;
+import org.jaxen.util.PrecedingAxisIterator;
+import org.w3c.dom.Document;
+
+import junit.framework.TestCase;
+
+public class PrecedingAxisIteratorTest extends TestCase {
+
+    private Iterator iterator;
+
+    public PrecedingAxisIteratorTest(String name) {
+        super(name);
+    }
+    
+    protected void setUp() throws ParserConfigurationException, UnsupportedAxisException {
+        
+        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        factory.setNamespaceAware(true);
+        Document doc = factory.newDocumentBuilder().newDocument();
+        doc.appendChild(doc.createElement("root"));
+        
+        iterator = new PrecedingAxisIterator(doc, new org.jaxen.dom.DocumentNavigator());
+        
+    }
+    
+    
+    public void testNoInfiniteLoops() {
+     
+        try {
+            iterator.next();
+            fail("Iterated too far");   
+        }
+        catch (NoSuchElementException ex) {
+            pass();
+        }
+        
+    }
+    
+    
+    private void pass() {
+        // Just to make checkstyle and the like happy
+    }
+
+    public void testRemove() {
+        
+        try {
+            iterator.remove();
+            fail("Removed from descendant axis iterator");   
+        }
+        catch (UnsupportedOperationException ex) {
+            pass();
+        }
+        
+    }
+    
+}
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/PrecedingSiblingAxisIteratorTest.java b/libjaxen-java/src/java/test/org/jaxen/test/PrecedingSiblingAxisIteratorTest.java
new file mode 100644
index 0000000..ff00ea1
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/PrecedingSiblingAxisIteratorTest.java
@@ -0,0 +1,109 @@
+/* $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2005 Elliotte Rusty Harold.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+package org.jaxen.test;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.jaxen.UnsupportedAxisException;
+import org.jaxen.util.PrecedingSiblingAxisIterator;
+import org.w3c.dom.Document;
+
+import junit.framework.TestCase;
+
+public class PrecedingSiblingAxisIteratorTest extends TestCase {
+
+    private Iterator iterator;
+
+    public PrecedingSiblingAxisIteratorTest(String name) {
+        super(name);
+    }
+    
+    protected void setUp() throws ParserConfigurationException, UnsupportedAxisException {
+        
+        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        factory.setNamespaceAware(true);
+        Document doc = factory.newDocumentBuilder().newDocument();
+        doc.appendChild(doc.createElement("root"));
+        
+        iterator = new PrecedingSiblingAxisIterator(doc, new org.jaxen.dom.DocumentNavigator());
+        
+    }
+    
+    
+    public void testNoInfiniteLoops() {
+     
+        try {
+            iterator.next();
+            fail("Iterated too far");   
+        }
+        catch (NoSuchElementException ex) {
+            pass();
+        }
+        
+    }
+    
+    
+    private void pass() {
+        // Just to make checkstyle and the like happy
+    }
+
+    public void testRemove() {
+        
+        try {
+            iterator.remove();
+            fail("Removed from descendant axis iterator");   
+        }
+        catch (UnsupportedOperationException ex) {
+            pass();
+        }
+        
+    }
+    
+}
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/PriorityTest.java b/libjaxen-java/src/java/test/org/jaxen/test/PriorityTest.java
new file mode 100644
index 0000000..0003c51
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/PriorityTest.java
@@ -0,0 +1,147 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+
+
+
+package org.jaxen.test;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+import junit.textui.TestRunner;
+
+import org.jaxen.JaxenException;
+import org.jaxen.pattern.Pattern;
+import org.jaxen.pattern.PatternParser;
+import org.jaxen.saxpath.SAXPathException;
+import org.jaxen.saxpath.helpers.XPathReaderFactory;
+
+/** Tests the use of priority in the Pattern implementations.
+  *
+  * @author <a href="mailto:jstrachan at apache.org">James Strachan</a>
+  * @version $Revision$
+  */
+public class PriorityTest extends TestCase
+{
+    public PriorityTest(String name)
+    {
+        super( name );
+    }
+
+    public static void main(String[] args) 
+    {
+        TestRunner.run( suite() );
+    }
+    
+    public static Test suite() 
+    {
+        return new TestSuite( PriorityTest.class );
+    }
+    
+    public void setUp()
+    {
+        System.setProperty( XPathReaderFactory.DRIVER_PROPERTY,
+                            "" );
+    }
+
+    public void testDocumentNode() throws Exception
+    {
+        testPriority( "/", -0.5, Pattern.DOCUMENT_NODE );
+    }
+    
+    public void testNameNode() throws Exception
+    {
+        testPriority( "foo", 0, Pattern.ELEMENT_NODE );
+    }
+    
+    public void testQNameNode() throws Exception
+    {
+        testPriority( "foo:bar", 0, Pattern.ELEMENT_NODE );
+    }
+    
+    public void testFilter() throws Exception
+    {
+        testPriority( "foo[@id='123']", 0.5, Pattern.ELEMENT_NODE );
+    }
+    
+    public void testURI() throws Exception
+    {
+        testPriority( "foo:*", -0.25, Pattern.ELEMENT_NODE );
+    }
+
+    public void testNodeType() throws Exception
+    {
+        testPriority( "text()", -0.5, Pattern.TEXT_NODE );
+    }
+    
+    public void testAttribute() throws Exception
+    {
+        testPriority( "@*", -0.5, Pattern.ATTRIBUTE_NODE );
+    }
+    
+    public void testAnyNode() throws Exception
+    {
+        testPriority( "*", -0.5, Pattern.ELEMENT_NODE );
+    }
+    
+    protected void testPriority(String expr, double priority, short nodeType) 
+     throws JaxenException, SAXPathException  
+    {
+        
+        Pattern pattern = PatternParser.parse( expr );
+        double d = pattern.getPriority();
+        short nt = pattern.getMatchType();
+        
+        assertEquals( "expr: " + expr,
+                      new Double( priority ),
+                      new Double( d ) );
+
+        assertEquals( "nodeType: " + expr,
+                      nodeType, 
+                      nt );
+    }
+}
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/RoundTest.java b/libjaxen-java/src/java/test/org/jaxen/test/RoundTest.java
new file mode 100644
index 0000000..1465273
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/RoundTest.java
@@ -0,0 +1,140 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2005 Elliotte Rusty Harold.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+
+package org.jaxen.test;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import junit.framework.TestCase;
+
+import org.jaxen.FunctionCallException;
+import org.jaxen.JaxenException;
+import org.jaxen.XPath;
+import org.jaxen.dom.DOMXPath;
+import org.w3c.dom.Document;
+
+/**
+ * @author Elliotte Rusty Harold
+ *
+ */
+public class RoundTest extends TestCase {
+
+    private Document doc;
+    
+    public void setUp() throws ParserConfigurationException
+    {
+        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        factory.setNamespaceAware(true);
+        DocumentBuilder builder = factory.newDocumentBuilder();
+        doc = builder.newDocument();
+        org.w3c.dom.Element a = doc.createElementNS("", "a");
+        doc.appendChild(a);
+    }
+
+
+    public RoundTest(String name) {
+        super(name);
+    }
+
+    
+    public void testRound() throws JaxenException {
+        
+        XPath xpath = new DOMXPath("round(1.5)");
+        
+        Object result = xpath.evaluate(doc);
+        assertEquals(2, ((Double) result).doubleValue(), 0.0001);
+        
+    }    
+
+    public void testNegativeRound() throws JaxenException {
+        
+        XPath xpath = new DOMXPath("round(-1.5)");
+        
+        Object result = xpath.evaluate(doc);
+        assertEquals(-1, ((Double) result).doubleValue(), 0.0001);
+        
+    }    
+
+    public void testNaNRoundIsNaN() throws JaxenException {
+        XPath xpath = new DOMXPath("round(1.0 div 0.0 - 2.0 div 0.0)");
+        double result = ((Double) xpath.evaluate(doc)).doubleValue();
+        assertTrue(Double.isNaN(result));
+    }    
+
+    public void testRoundFunctionRequiresAtLeastOneArgument() 
+      throws JaxenException {
+        
+        XPath xpath = new DOMXPath("round()");
+        
+        try {
+            xpath.selectNodes(doc);
+            fail("Allowed round function with no arguments");
+        }
+        catch (FunctionCallException ex) {
+            assertNotNull(ex.getMessage());
+        }
+        
+    }    
+
+    public void testRoundFunctionRequiresAtMostOneArgument() 
+      throws JaxenException {
+        
+        XPath xpath = new DOMXPath("round(2.2, 1.2)");
+        
+        try {
+            xpath.selectNodes(doc);
+            fail("Allowed round function with two arguments");
+        }
+        catch (FunctionCallException ex) {
+            assertNotNull(ex.getMessage());
+        }
+        
+    }    
+
+}
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/SAXPathExceptionTest.java b/libjaxen-java/src/java/test/org/jaxen/test/SAXPathExceptionTest.java
new file mode 100644
index 0000000..822b50e
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/SAXPathExceptionTest.java
@@ -0,0 +1,85 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2005 Elliotte Rusty Harold.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+
+package org.jaxen.test;
+
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+import org.jaxen.saxpath.SAXPathException;
+
+import junit.framework.TestCase;
+
+
+/**
+ * @author Elliotte Rusty Harold
+ *
+ */
+public class SAXPathExceptionTest extends TestCase {
+
+    public SAXPathExceptionTest(String name) {
+        super(name);
+    }
+
+    public void testMessageIsNonNull() {
+        SAXPathException ex = new SAXPathException("Hello");
+        assertEquals("Hello", ex.getMessage());
+    }    
+  
+    public void testPrintStackTrace() {
+        StringIndexOutOfBoundsException cause = new StringIndexOutOfBoundsException("1234");
+        SAXPathException ex = new SAXPathException(cause);
+        StringWriter out = new StringWriter();
+        PrintWriter pw = new PrintWriter(out);
+        ex.printStackTrace(pw);
+        pw.close();
+        assertTrue(out.toString().indexOf("Caused by: java.lang.StringIndexOutOfBoundsException") > 0);
+        assertTrue(out.toString().indexOf("1234") > 0);
+    }
+    
+}
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/SAXPathTests.java b/libjaxen-java/src/java/test/org/jaxen/test/SAXPathTests.java
new file mode 100644
index 0000000..0059b49
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/SAXPathTests.java
@@ -0,0 +1,74 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2005 Elliotte Rusty Harold
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+
+
+package org.jaxen.test;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+/**
+ * <p>
+ *   Collect the org.jaxen.saxpath.base tests.
+ * </p>
+ * 
+ * @author Elliotte Rusty Harold
+ * @version 1.1b9
+ *
+ */
+public class SAXPathTests {
+    
+    public static Test suite() {
+        
+        TestSuite result = new TestSuite();
+        result.addTestSuite(SAXPathExceptionTest.class);
+        result.addTestSuite(AxisTest.class);
+        return result;
+        
+    }
+    
+}
\ No newline at end of file
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/SimpleNamespaceContextTest.java b/libjaxen-java/src/java/test/org/jaxen/test/SimpleNamespaceContextTest.java
new file mode 100644
index 0000000..8b49998
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/SimpleNamespaceContextTest.java
@@ -0,0 +1,161 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2005, 2006 Elliotte Rusty Harold
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+
+
+
+package org.jaxen.test;
+
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.jaxen.SimpleNamespaceContext;
+import org.jaxen.UnsupportedAxisException;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import junit.framework.TestCase;
+
+/**
+ * <p>
+ *  Test for namespace context.
+ * </p>
+ * 
+ * @author Elliotte Rusty Harold
+ * @version 1.1b10
+ *
+ */
+public class SimpleNamespaceContextTest extends TestCase
+{
+
+    /**
+     * Need to make sure that changing the map after it's used to create the 
+     * namespace context does not affect the context. i.e.
+     * data encapsulation is not violated.
+     */
+    public void testMapCopy() {
+        Map map = new HashMap();
+        SimpleNamespaceContext context = new SimpleNamespaceContext(map);
+        map.put("pre", "http://www.example.org/");
+        assertNull(context.translateNamespacePrefixToUri("pre"));
+    }
+ 
+    public void testCantUseNonStringsAsValues() {
+        Map map = new HashMap();
+        map.put("key", new Object());
+        try {
+            new SimpleNamespaceContext(map);
+            fail("added non String value to namespace context");
+        }
+        catch (Exception ex) {
+            assertNotNull(ex.getMessage());
+        }
+    }
+ 
+    public void testCantUseNonStringsAsKeys() {
+        Map map = new HashMap();
+        map.put(new Object(), "value");
+        try {
+            new SimpleNamespaceContext(map);
+            fail("added non String key to namespace context");
+        }
+        catch (Exception ex) {
+            assertNotNull(ex.getMessage());
+        }
+    }
+ 
+    public void testContextFromElement() throws ParserConfigurationException, UnsupportedAxisException { 
+        SimpleNamespaceContext context = new SimpleNamespaceContext();
+        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        factory.setNamespaceAware(true);
+        DocumentBuilder builder = factory.newDocumentBuilder();
+        Document doc = builder.newDocument();
+        Element root = doc.createElementNS("http://www.example.org/", "pre:root");
+        doc.appendChild(root);
+        context.addElementNamespaces(new org.jaxen.dom.DocumentNavigator(), root);
+        
+        assertEquals("http://www.example.org/", context.translateNamespacePrefixToUri("pre"));
+    }
+ 
+    public void testSerialization() throws IOException, ClassNotFoundException {
+        
+        // construct test object
+        SimpleNamespaceContext original = new SimpleNamespaceContext();
+        original.addNamespace("a", "http://www.a.com");
+        original.addNamespace("b", "http://www.b.com");
+        
+        // serialize
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        ObjectOutputStream oos = new ObjectOutputStream(out);
+        oos.writeObject(original);
+        oos.close();
+        
+        //deserialize
+        byte[] pickled = out.toByteArray();
+        InputStream in = new ByteArrayInputStream(pickled);
+        ObjectInputStream ois = new ObjectInputStream(in);
+        Object o = ois.readObject();
+        SimpleNamespaceContext copy = (SimpleNamespaceContext) o;
+        
+        // test the result
+        assertEquals("http://www.a.com", copy.translateNamespacePrefixToUri("a"));
+        assertEquals("http://www.b.com", copy.translateNamespacePrefixToUri("b"));
+        assertEquals("", "");
+        
+    }
+    
+}
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/SimpleVariableContextTest.java b/libjaxen-java/src/java/test/org/jaxen/test/SimpleVariableContextTest.java
new file mode 100644
index 0000000..c001517
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/SimpleVariableContextTest.java
@@ -0,0 +1,125 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2006 Elliotte Rusty Harold
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+
+
+
+package org.jaxen.test;
+
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+
+import org.jaxen.SimpleVariableContext;
+import org.jaxen.UnresolvableException;
+
+import junit.framework.TestCase;
+
+/**
+ * <p>
+ *  Test for namespace context.
+ * </p>
+ * 
+ * @author Elliotte Rusty Harold
+ * @version 1.1b10
+ *
+ */
+public class SimpleVariableContextTest extends TestCase
+{
+
+    public void testRoundTripSerialization() 
+      throws IOException, ClassNotFoundException, UnresolvableException {
+        
+        // construct test object
+        SimpleVariableContext original = new SimpleVariableContext();
+        original.setVariableValue("s", "String Value");
+        original.setVariableValue("x", new Double(3.1415292));
+        original.setVariableValue("b", Boolean.TRUE);
+        
+        // serialize
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        ObjectOutputStream oos = new ObjectOutputStream(out);
+        oos.writeObject(original);
+        oos.close();
+        
+        //deserialize
+        byte[] pickled = out.toByteArray();
+        InputStream in = new ByteArrayInputStream(pickled);
+        ObjectInputStream ois = new ObjectInputStream(in);
+        Object o = ois.readObject();
+        SimpleVariableContext copy = (SimpleVariableContext) o;
+        
+        // test the result
+        assertEquals("String Value", copy.getVariableValue("", "", "s"));
+        assertEquals(Double.valueOf(3.1415292), copy.getVariableValue("", "", "x"));
+        assertEquals(Boolean.TRUE, copy.getVariableValue("", "", "b"));
+        assertEquals("", "");
+        
+    }
+    
+    public void testSerializationFormatHasNotChanged() 
+      throws IOException, ClassNotFoundException, UnresolvableException {
+        
+        //deserialize
+        InputStream in = new FileInputStream("xml/simplevariablecontext.ser");
+        ObjectInputStream ois = new ObjectInputStream(in);
+        Object o = ois.readObject();
+        SimpleVariableContext context = (SimpleVariableContext) o;
+        
+        // test the result
+        assertEquals("String Value", context.getVariableValue("", "", "s"));
+        assertEquals(Double.valueOf(3.1415292), context.getVariableValue("", "", "x"));
+        assertEquals(Boolean.TRUE, context.getVariableValue("", "", "b"));
+        assertEquals("", "");
+        
+    }
+    
+}
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/SingleObjectIteratorTest.java b/libjaxen-java/src/java/test/org/jaxen/test/SingleObjectIteratorTest.java
new file mode 100644
index 0000000..1b9b4c4
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/SingleObjectIteratorTest.java
@@ -0,0 +1,83 @@
+/* $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2005 Elliotte Rusty Harold.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+package org.jaxen.test;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+import org.jaxen.util.SingleObjectIterator;
+
+import junit.framework.TestCase;
+
+public class SingleObjectIteratorTest extends TestCase {
+
+    private Iterator iterator = new SingleObjectIterator(new Object());
+    
+    public void testNoInfiniteLoops() {
+     
+        iterator.next();
+        try {
+            iterator.next();
+            fail("Iterated twice");   
+        }
+        catch (NoSuchElementException ex) {
+        }
+        
+    }
+    
+    
+    public void testRemove() {
+        
+        try {
+            iterator.remove();
+            fail("Removed from iterator");   
+        }
+        catch (UnsupportedOperationException ex) {
+        }
+        
+    }
+    
+}
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/SingletonListTest.java b/libjaxen-java/src/java/test/org/jaxen/test/SingletonListTest.java
new file mode 100644
index 0000000..c92566d
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/SingletonListTest.java
@@ -0,0 +1,69 @@
+/* $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2005 Elliotte Rusty Harold.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+package org.jaxen.test;
+
+import java.util.List;
+
+import org.jaxen.util.SingletonList;
+
+import junit.framework.TestCase;
+
+public class SingletonListTest extends TestCase {
+
+    public void testIndexOutOfBoundsException() {
+     
+        List list = new SingletonList(new Object());
+        try {
+            list.get(1);
+            fail("Got element 1");
+        }
+        catch (IndexOutOfBoundsException ex) {
+            assertNotNull(ex.getMessage());
+        }
+        
+    }
+    
+}
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/StartsWithTest.java b/libjaxen-java/src/java/test/org/jaxen/test/StartsWithTest.java
new file mode 100644
index 0000000..f62801b
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/StartsWithTest.java
@@ -0,0 +1,172 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2005 Elliotte Rusty Harold.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+
+package org.jaxen.test;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import junit.framework.TestCase;
+
+import org.jaxen.BaseXPath;
+import org.jaxen.FunctionCallException;
+import org.jaxen.JaxenException;
+import org.jaxen.XPath;
+import org.jaxen.dom.DOMXPath;
+import org.w3c.dom.Document;
+
+/**
+ * @author Elliotte Rusty Harold
+ *
+ */
+public class StartsWithTest extends TestCase {
+
+    private Document doc;
+    
+    public void setUp() throws ParserConfigurationException
+    {
+        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        factory.setNamespaceAware(true);
+        DocumentBuilder builder = factory.newDocumentBuilder();
+        doc = builder.newDocument();
+        doc.appendChild(doc.createElement("root"));
+    }
+
+
+    public StartsWithTest(String name) {
+        super(name);
+    }
+
+    public void testStartsWithNumber() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "starts-with(33, '3')" );
+        Boolean result = (Boolean) xpath.evaluate( doc );
+        assertEquals(Boolean.TRUE, result);
+    }    
+  
+    public void testStartsWithString() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "starts-with('test', 't')" );
+        Boolean result = (Boolean) xpath.evaluate( doc );
+        assertEquals(Boolean.TRUE, result);
+    }    
+  
+    public void testStartsWithString3() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "starts-with('superlative', 'superlative')" );
+        Boolean result = (Boolean) xpath.evaluate( doc );
+        assertEquals(Boolean.TRUE, result);
+    }    
+  
+    public void testStartsWithNumber2() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "starts-with(43, '3')" );
+        Boolean result = (Boolean) xpath.evaluate( doc );
+        assertEquals(Boolean.FALSE, result);
+    }    
+  
+    public void testStartsWithString2() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "starts-with('1234567890', '1234567a')" );
+        Boolean result = (Boolean) xpath.evaluate( doc );
+        assertEquals(Boolean.FALSE, result);
+    }    
+  
+  
+    public void testEmptyStringStartsWithNonEmptyString() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "starts-with('', 'a')" );
+        Boolean result = (Boolean) xpath.evaluate( doc );
+        assertEquals(Boolean.FALSE, result);
+    }
+  
+    public void testEmptyStringStartsWithEmptyString() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "starts-with('', '')" );
+        Boolean result = (Boolean) xpath.evaluate( doc );
+        assertEquals(Boolean.TRUE, result);
+    }
+  
+    public void testStartsWithEmptyString() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "starts-with('a', '')" );
+        Boolean result = (Boolean) xpath.evaluate( doc );
+        assertEquals(Boolean.TRUE, result);
+    }    
+  
+    public void testStartsWithFunctionRequiresAtLeastTwoArguments() 
+      throws JaxenException {
+        
+        BaseXPath xpath = new DOMXPath("starts-with('a')");
+        
+        try {
+            xpath.selectNodes(doc);
+            fail("Allowed starts-with function with one argument");
+        }
+        catch (FunctionCallException ex) {
+            assertNotNull(ex.getMessage());
+        }
+        
+    }    
+
+    public void testStartsWithFunctionRequiresAtMostTwoArguments() 
+      throws JaxenException {
+        
+        BaseXPath xpath = new DOMXPath("starts-with('a', 'a', 'a')");
+        
+        try {
+            xpath.selectNodes(doc);
+            fail("Allowed starts-with function with three arguments");
+        }
+        catch (FunctionCallException ex) {
+            assertNotNull(ex.getMessage());
+        }
+        
+    }    
+
+}
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/StringLengthTest.java b/libjaxen-java/src/java/test/org/jaxen/test/StringLengthTest.java
new file mode 100644
index 0000000..e440f4f
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/StringLengthTest.java
@@ -0,0 +1,153 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2005 Elliotte Rusty Harold.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+
+package org.jaxen.test;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import junit.framework.TestCase;
+
+import org.jaxen.BaseXPath;
+import org.jaxen.FunctionCallException;
+import org.jaxen.JaxenException;
+import org.jaxen.XPath;
+import org.jaxen.dom.DOMXPath;
+import org.w3c.dom.Document;
+
+/**
+ * @author Elliotte Rusty Harold
+ *
+ */
+public class StringLengthTest extends TestCase {
+
+    private Document doc;
+    
+    public void setUp() throws ParserConfigurationException
+    {
+        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        factory.setNamespaceAware(true);
+        DocumentBuilder builder = factory.newDocumentBuilder();
+        doc = builder.newDocument();
+        doc.appendChild(doc.createElement("root"));
+    }
+
+
+    public StringLengthTest(String name) {
+        super(name);
+    }
+
+    public void testStringLengthOfNumber() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "string-length(3)" );
+        Double result = (Double) xpath.evaluate( doc );
+        assertEquals(1, result.intValue());
+    }    
+  
+    public void testStringLengthOfEmptyString() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "string-length('')" );
+        Double result = (Double) xpath.evaluate( doc );
+        assertEquals(0, result.intValue());
+    }    
+  
+    public void testStringLengthOfString() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "string-length('0123456789')" );
+        Double result = (Double) xpath.evaluate( doc );
+        assertEquals(10, result.intValue());
+    }    
+  
+    public void testStringLengthFunctionOperatesOnContextNode() 
+      throws JaxenException {
+        
+        BaseXPath xpath = new DOMXPath("string-length()");
+        Double result = (Double) xpath.evaluate( doc );
+        assertEquals(0, result.intValue());
+        
+    }    
+
+    public void testStringLengthFunctionCountsUnicodeCharactersNotJavaChars() 
+      throws JaxenException {
+   
+        BaseXPath xpath = new DOMXPath("string-length('\uD834\uDD00')");
+        Double result = (Double) xpath.evaluate( doc );
+        assertEquals(1, result.intValue());
+        
+    }    
+
+    public void testStringLengthFunctionWithMalformedString() 
+      throws JaxenException {
+   
+        BaseXPath xpath = new DOMXPath("string-length('\uD834A\uDD00')");
+        try {
+            xpath.evaluate( doc );
+            fail("Allowed Malformed string");
+        }
+        catch (FunctionCallException ex) {
+            assertNotNull(ex.getMessage());
+        }
+        
+    }    
+
+    public void testStringLengthFunctionRequiresExactlyOneArgument() 
+      throws JaxenException {
+        
+        BaseXPath xpath = new DOMXPath("string-length('', '')");
+        
+        try {
+            xpath.selectNodes(doc);
+            fail("Allowed string-length function with two arguments");
+        }
+        catch (FunctionCallException ex) {
+            assertNotNull(ex.getMessage());
+        }
+        
+    }    
+
+}
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/StringTest.java b/libjaxen-java/src/java/test/org/jaxen/test/StringTest.java
new file mode 100644
index 0000000..99acc30
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/StringTest.java
@@ -0,0 +1,195 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2005 Elliotte Rusty Harold
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+
+package org.jaxen.test;
+
+import java.util.List;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import junit.framework.TestCase;
+
+import org.jaxen.FunctionCallException;
+import org.jaxen.JaxenException;
+import org.jaxen.XPath;
+import org.jaxen.dom.DOMXPath;
+import org.jaxen.dom.DocumentNavigator;
+import org.jaxen.function.StringFunction;
+import org.w3c.dom.Document;
+
+/**
+ * @author Elliotte Rusty Harold
+ *
+ */
+public class StringTest extends TestCase {
+
+    private Document doc;
+    
+    public void setUp() throws ParserConfigurationException
+    {
+        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        factory.setNamespaceAware(true);
+        DocumentBuilder builder = factory.newDocumentBuilder();
+        doc = builder.newDocument();
+    }
+
+
+    public StringTest(String name) {
+        super(name);
+    }
+
+    // test case for JAXEN-55
+    public void testStringFunctionOperatesOnFirstNodeInDocumentOrder() 
+      throws JaxenException {
+        
+        XPath xpath = new DOMXPath("string(//x)");
+        org.w3c.dom.Element a = doc.createElementNS("", "a");
+        org.w3c.dom.Element b = doc.createElementNS("", "b");
+        doc.appendChild(a);
+        a.appendChild(b);
+        org.w3c.dom.Element x2 = doc.createElementNS("", "x");
+        org.w3c.dom.Element x3 = doc.createElementNS("", "x");
+        org.w3c.dom.Element x4 = doc.createElementNS("", "x");
+        a.appendChild(x4);
+        b.appendChild(x2);
+        b.appendChild(x3);
+        x2.appendChild(doc.createTextNode("2"));
+        x3.appendChild(doc.createTextNode("3"));
+        x4.appendChild(doc.createTextNode("4"));
+        
+        List result = xpath.selectNodes(doc);
+        assertEquals(1, result.size());
+        assertEquals("2", result.get(0));
+        
+    }
+    
+    public void testStringValueOfComment() 
+      throws JaxenException {
+        
+        XPath xpath = new DOMXPath("string(/a/comment())");
+        org.w3c.dom.Element a = doc.createElementNS("", "a");
+        doc.appendChild(a);
+        a.appendChild(doc.createComment("data"));
+        
+        String result = (String) xpath.evaluate(doc);
+        assertEquals("data", result);
+        
+    }
+    
+    public void testStringValueOfNull() {
+        assertEquals("", StringFunction.evaluate(null, null));
+    }
+    
+    public void testStringValueOfNullWithNonNullNavigator() {
+        assertEquals("", StringFunction.evaluate(null, new DocumentNavigator()));
+    }
+    
+    public void testStringValueOfNamespaceNode() 
+      throws JaxenException {
+        
+        XPath xpath = new DOMXPath("string(/a/namespace::node())");
+        org.w3c.dom.Element a = doc.createElementNS("", "a");
+        doc.appendChild(a);
+        
+        String result = (String) xpath.evaluate(doc);
+        assertEquals("http://www.w3.org/XML/1998/namespace", result);
+        
+    }
+    
+    public void testSmallNumbersDontUseExponentialNotation() throws JaxenException {
+        XPath xpath = new DOMXPath("string(0.0000003)");
+        String result = (String) xpath.evaluate(null);
+        assertEquals("0.0000003", result);
+    }
+
+    public void testBigNumbersDontUseExponentialNotation() throws JaxenException {
+        XPath xpath = new DOMXPath("string(100000000.5)");
+        String result = (String) xpath.evaluate(null);
+        assertEquals("100000000.5", result);
+    }
+
+    public void testStringOfInfinity() throws JaxenException {
+        XPath xpath = new DOMXPath("string(1 div 0)");
+        String result = (String) xpath.evaluate(null);
+        assertEquals("Infinity", result);
+    }
+
+    public void testStringOfNegativeInfinity() throws JaxenException {
+        XPath xpath = new DOMXPath("string(-1 div 0)");
+        String result = (String) xpath.evaluate(null);
+        assertEquals("-Infinity", result);
+    }
+
+    public void testStringOfNegativeZero() throws JaxenException {
+        XPath xpath = new DOMXPath("string(-0)");
+        String result = (String) xpath.evaluate(null);
+        assertEquals("0", result);
+    }
+
+    public void testIntegersAreFormattedAsInts() throws JaxenException {
+        XPath xpath = new DOMXPath("string(12)");
+        String result = (String) xpath.evaluate(null);
+        assertEquals("12", result);
+    } 
+
+    public void testStringFunctionRequiresAtMostOneArgument() 
+      throws JaxenException {
+        
+        XPath xpath = new DOMXPath("string('a', 1)");
+        
+        try {
+            xpath.selectNodes(doc);
+            fail("Allowed string function with two arguments");
+        }
+        catch (FunctionCallException ex) {
+            assertNotNull(ex.getMessage());
+        }
+        
+    }
+}
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/SubstringAfterTest.java b/libjaxen-java/src/java/test/org/jaxen/test/SubstringAfterTest.java
new file mode 100644
index 0000000..7bff07c
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/SubstringAfterTest.java
@@ -0,0 +1,180 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2005 Elliotte Rusty Harold.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+
+package org.jaxen.test;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import junit.framework.TestCase;
+
+import org.jaxen.BaseXPath;
+import org.jaxen.FunctionCallException;
+import org.jaxen.JaxenException;
+import org.jaxen.XPath;
+import org.jaxen.dom.DOMXPath;
+import org.w3c.dom.Document;
+
+/**
+ * @author Elliotte Rusty Harold
+ *
+ */
+public class SubstringAfterTest extends TestCase {
+
+    private Document doc;
+    
+    public void setUp() throws ParserConfigurationException
+    {
+        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        factory.setNamespaceAware(true);
+        DocumentBuilder builder = factory.newDocumentBuilder();
+        doc = builder.newDocument();
+        doc.appendChild(doc.createElement("root"));
+    }
+
+
+    public SubstringAfterTest(String name) {
+        super(name);
+    }
+
+    public void testSubstringAfterNumber() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "substring-after(33, '3')" );
+        String result = (String) xpath.evaluate( doc );
+        assertEquals("3", result);
+    }    
+  
+    public void testSubstringAfterString() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "substring-after('test', 'es')" );
+        String result = (String) xpath.evaluate( doc );
+        assertEquals("t", result);
+    }    
+  
+    public void testSubstringAfterString4() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "substring-after('superlative', 'superlative')" );
+        String result = (String) xpath.evaluate( doc );
+        assertEquals("", result);
+    }    
+  
+    public void testSubstringAfterNumber2() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "substring-after(43, '0')" );
+        String result = (String) xpath.evaluate( doc );
+        assertEquals("", result);
+    }    
+  
+    public void testSubstringAfterString2() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "substring-after('1234567890', '1234567a')" );
+        String result = (String) xpath.evaluate( doc );
+        assertEquals("", result);
+    }    
+  
+  
+    public void testSubstringAfterString3() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "substring-after('1234567890', '456')" );
+        String result = (String) xpath.evaluate( doc );
+        assertEquals("7890", result);
+    }    
+  
+  
+    public void testEmptyStringSubstringAfterNonEmptyString() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "substring-after('', 'a')" );
+        String result = (String) xpath.evaluate( doc );
+        assertEquals("", result);
+    }
+  
+    public void testEmptyStringBeforeEmptyString() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "substring-after('', '')" );
+        String result = (String) xpath.evaluate( doc );
+        assertEquals("", result);
+    }
+  
+    public void testSubstringAfterEmptyString() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "substring-after('a', '')" );
+        String result = (String) xpath.evaluate( doc );
+        assertEquals("a", result);
+    }    
+  
+    public void testSubstringAfterFunctionRequiresAtLeastTwoArguments() 
+      throws JaxenException {
+        
+        BaseXPath xpath = new DOMXPath("substring-after('a')");
+        
+        try {
+            xpath.selectNodes(doc);
+            fail("Allowed substring-after function with one argument");
+        }
+        catch (FunctionCallException ex) {
+            assertNotNull(ex.getMessage());
+        }
+        
+    }    
+
+    public void testSubstringAfterFunctionRequiresAtMostTwoArguments() 
+      throws JaxenException {
+        
+        BaseXPath xpath = new DOMXPath("substring-after('a', 'a', 'a')");
+        
+        try {
+            xpath.selectNodes(doc);
+            fail("Allowed substring-after function with three arguments");
+        }
+        catch (FunctionCallException ex) {
+            assertNotNull(ex.getMessage());
+        }
+        
+    }    
+
+}
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/SubstringBeforeTest.java b/libjaxen-java/src/java/test/org/jaxen/test/SubstringBeforeTest.java
new file mode 100644
index 0000000..0368cbf
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/SubstringBeforeTest.java
@@ -0,0 +1,180 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2005 Elliotte Rusty Harold.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+
+package org.jaxen.test;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import junit.framework.TestCase;
+
+import org.jaxen.BaseXPath;
+import org.jaxen.FunctionCallException;
+import org.jaxen.JaxenException;
+import org.jaxen.XPath;
+import org.jaxen.dom.DOMXPath;
+import org.w3c.dom.Document;
+
+/**
+ * @author Elliotte Rusty Harold
+ *
+ */
+public class SubstringBeforeTest extends TestCase {
+
+    private Document doc;
+    
+    public void setUp() throws ParserConfigurationException
+    {
+        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        factory.setNamespaceAware(true);
+        DocumentBuilder builder = factory.newDocumentBuilder();
+        doc = builder.newDocument();
+        doc.appendChild(doc.createElement("root"));
+    }
+
+
+    public SubstringBeforeTest(String name) {
+        super(name);
+    }
+
+    public void testSubstringBeforeNumber() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "substring-before(33, '3')" );
+        String result = (String) xpath.evaluate( doc );
+        assertEquals("", result);
+    }    
+  
+    public void testSubstringBeforeString() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "substring-before('test', 'es')" );
+        String result = (String) xpath.evaluate( doc );
+        assertEquals("t", result);
+    }    
+  
+    public void testContainsString3() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "substring-before('superlative', 'superlative')" );
+        String result = (String) xpath.evaluate( doc );
+        assertEquals("", result);
+    }    
+  
+    public void testSubstringBeforeNumber2() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "substring-before(43, '0')" );
+        String result = (String) xpath.evaluate( doc );
+        assertEquals("", result);
+    }    
+  
+    public void testSubstringBeforeString2() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "substring-before('1234567890', '1234567a')" );
+        String result = (String) xpath.evaluate( doc );
+        assertEquals("", result);
+    }    
+  
+  
+    public void testSubstringBeforeString3() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "substring-before('1234567890', '456')" );
+        String result = (String) xpath.evaluate( doc );
+        assertEquals("123", result);
+    }    
+  
+  
+    public void testEmptyStringSubstringBeforeNonEmptyString() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "substring-before('', 'a')" );
+        String result = (String) xpath.evaluate( doc );
+        assertEquals("", result);
+    }
+  
+    public void testEmptyStringBeforeEmptyString() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "substring-before('', '')" );
+        String result = (String) xpath.evaluate( doc );
+        assertEquals("", result);
+    }
+  
+    public void testSubstringBeforeEmptyString() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "substring-before('a', '')" );
+        String result = (String) xpath.evaluate( doc );
+        assertEquals("", result);
+    }    
+  
+    public void testSubstringBeforeFunctionRequiresAtLeastTwoArguments() 
+      throws JaxenException {
+        
+        BaseXPath xpath = new DOMXPath("substring-before('a')");
+        
+        try {
+            xpath.selectNodes(doc);
+            fail("Allowed substring-before function with one argument");
+        }
+        catch (FunctionCallException ex) {
+            assertNotNull(ex.getMessage());
+        }
+        
+    }    
+
+    public void testSubstringBeforeFunctionRequiresAtMostTwoArguments() 
+      throws JaxenException {
+        
+        BaseXPath xpath = new DOMXPath("substring-before('a', 'a', 'a')");
+        
+        try {
+            xpath.selectNodes(doc);
+            fail("Allowed substring-before function with three arguments");
+        }
+        catch (FunctionCallException ex) {
+            assertNotNull(ex.getMessage());
+        }
+        
+    }    
+
+}
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/SubstringTest.java b/libjaxen-java/src/java/test/org/jaxen/test/SubstringTest.java
new file mode 100644
index 0000000..12e8dec
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/SubstringTest.java
@@ -0,0 +1,263 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2005 Elliotte Rusty Harold.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+
+package org.jaxen.test;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import junit.framework.TestCase;
+
+import org.jaxen.FunctionCallException;
+import org.jaxen.JaxenException;
+import org.jaxen.XPath;
+import org.jaxen.dom.DOMXPath;
+import org.w3c.dom.Document;
+
+/**
+ * @author Elliotte Rusty Harold
+ *
+ */
+public class SubstringTest extends TestCase {
+
+    private Document doc;
+    
+    public void setUp() throws ParserConfigurationException
+    {
+        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        factory.setNamespaceAware(true);
+        DocumentBuilder builder = factory.newDocumentBuilder();
+        doc = builder.newDocument();
+        doc.appendChild(doc.createElement("root"));
+    }
+
+
+    public SubstringTest(String name) {
+        super(name);
+    }
+
+    public void testSubstringOfNumber() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "substring(1234, 3)" );
+        String result = (String) xpath.evaluate( doc );
+        assertEquals("34", result);
+    }    
+  
+    public void testSubstringOfNumber2() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "substring(1234, 2, 3)" );
+        String result = (String) xpath.evaluate( doc );
+        assertEquals("234", result);
+    }    
+    
+    // Unusual tests from XPath spec
+    
+    public void testUnusualSubstring1() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "substring('12345', 1.5, 2.6)" );
+        String result = (String) xpath.evaluate( doc );
+        assertEquals("234", result);
+    }    
+
+
+    public void testUnusualSubstring2() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "substring('12345', 0, 3)" );
+        String result = (String) xpath.evaluate( doc );
+        assertEquals("12", result);
+    }    
+
+
+    public void testUnusualSubstring3() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "substring('12345', 0 div 0, 3)" );
+        String result = (String) xpath.evaluate( doc );
+        assertEquals("", result);
+    }    
+
+    public void testUnusualSubstring4() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "substring('12345', 1, 0 div 0)" );
+        String result = (String) xpath.evaluate( doc );
+        assertEquals("", result);
+    }    
+
+    public void testUnusualSubstring5() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "substring('12345', -42, 1 div 0)" );
+        String result = (String) xpath.evaluate( doc );
+        assertEquals("12345", result);
+    }    
+
+    public void testUnusualSubstring6() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "substring('12345', -1 div 0, 1 div 0)" );
+        String result = (String) xpath.evaluate( doc );
+        assertEquals("", result);
+    }    
+
+  
+    public void testSubstringOfNaN() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "substring(0 div 0, 2)" );
+        String result = (String) xpath.evaluate( doc );
+        assertEquals("aN", result);
+    }    
+ 
+  
+    public void testSubstringOfEmptyString() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "substring('', 2)" );
+        String result = (String) xpath.evaluate( doc );
+        assertEquals("", result);
+    }    
+ 
+  
+    public void testSubstringWithNegativeLength() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "substring('12345', 2, -3)" );
+        String result = (String) xpath.evaluate( doc );
+        assertEquals("", result);
+    }    
+ 
+  
+    public void testSubstringWithExcessiveLength() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "substring('12345', 2, 32)" );
+        String result = (String) xpath.evaluate( doc );
+        assertEquals("2345", result);
+    }    
+ 
+  
+    public void testSubstringWithNegativeLength2() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "substring('12345', 2, -1)" );
+        String result = (String) xpath.evaluate( doc );
+        assertEquals("", result);
+    }    
+ 
+  
+    public void testSubstringFunctionRequiresAtLeastTwoArguments() 
+      throws JaxenException {
+        
+        XPath xpath = new DOMXPath("substring('a')");
+        
+        try {
+            xpath.selectNodes(doc);
+            fail("Allowed substring function with one argument");
+        }
+        catch (FunctionCallException ex) {
+            assertNotNull(ex.getMessage());
+        }
+        
+    }    
+
+    public void testNegativeStartNoLength() 
+      throws JaxenException {
+        
+        XPath xpath = new DOMXPath("substring('Hello', -50)");
+        String result = (String) xpath.evaluate( doc );
+        assertEquals("Hello", result);
+        
+    }    
+
+    public void testNegativeStartWithLength() 
+      throws JaxenException {
+        
+        XPath xpath = new DOMXPath("substring('Hello', -50, 20)");
+        String result = (String) xpath.evaluate( doc );
+        assertEquals("", result);
+        
+    }    
+
+    public void testSubstringFunctionRequiresAtMostThreeArguments() 
+      throws JaxenException {
+        
+        XPath xpath = new DOMXPath("substring('a', 1, 1, 4)");
+        
+        try {
+            xpath.selectNodes(doc);
+            fail("Allowed substring function with four arguments");
+        }
+        catch (FunctionCallException ex) {
+            assertNotNull(ex.getMessage());
+        }
+        
+    }
+
+    public void testStringLengthCountsUnicodeCharactersNotJavaChars() 
+      throws JaxenException {
+   
+        XPath xpath = new DOMXPath("substring('A\uD834\uDD00', 1, 2)");
+        String result = (String) xpath.evaluate( doc );
+        assertEquals("A\uD834\uDD00", result);
+        
+    }
+    
+    
+    public void testStringLengthIndexesUnicodeCharactersNotJavaChars() 
+      throws JaxenException {
+   
+        XPath xpath = new DOMXPath("substring('A\uD834\uDD00', 3, 1)");
+        String result = (String) xpath.evaluate( doc );
+        assertEquals("", result);
+        
+    }
+    
+    
+    public void testStringLengthIndexesAndCountsUnicodeCharactersNotJavaChars() 
+      throws JaxenException {
+   
+        XPath xpath = new DOMXPath("substring('A\uD834\uDD00123', 3, 2)");
+        String result = (String) xpath.evaluate( doc );
+        assertEquals("12", result);
+        
+    }
+    
+    
+}
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/SumTest.java b/libjaxen-java/src/java/test/org/jaxen/test/SumTest.java
new file mode 100644
index 0000000..5a1d845
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/SumTest.java
@@ -0,0 +1,112 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+
+package org.jaxen.test;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import junit.framework.TestCase;
+
+import org.jaxen.FunctionCallException;
+import org.jaxen.JaxenException;
+import org.jaxen.XPath;
+import org.jaxen.dom.DOMXPath;
+import org.w3c.dom.Document;
+
+/**
+ * @author Elliotte Rusty Harold
+ *
+ */
+public class SumTest extends TestCase {
+
+    private Document doc;
+    
+    public void setUp() throws ParserConfigurationException
+    {
+        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        factory.setNamespaceAware(true);
+        DocumentBuilder builder = factory.newDocumentBuilder();
+        doc = builder.newDocument();
+        doc.appendChild(doc.createElement("root"));
+    }
+
+
+    public SumTest(String name) {
+        super(name);
+    }
+
+    public void testSumOfNumber() throws JaxenException
+    {
+        try
+        {
+            XPath xpath = new DOMXPath( "sum(3)" );
+            xpath.selectNodes( doc );
+            fail("sum of non-node-set");
+        }
+        catch (FunctionCallException e) 
+        {
+            assertEquals("The argument to the sum function must be a node-set", e.getMessage());
+        }
+    }    
+
+    public void testSumNoArguments() throws JaxenException
+    {
+        try
+        {
+            XPath xpath = new DOMXPath( "sum()" );
+            xpath.selectNodes( doc );
+            fail("sum of nothing");
+        }
+        catch (FunctionCallException e)
+        {
+            assertEquals("sum() requires one argument.", e.getMessage());
+        }
+    }    
+
+}
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/TranslateFunctionTest.java b/libjaxen-java/src/java/test/org/jaxen/test/TranslateFunctionTest.java
new file mode 100644
index 0000000..587245a
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/TranslateFunctionTest.java
@@ -0,0 +1,197 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2005 Elliotte Rusty Harold.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+
+package org.jaxen.test;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import junit.framework.TestCase;
+
+import org.jaxen.FunctionCallException;
+import org.jaxen.JaxenException;
+import org.jaxen.XPath;
+import org.jaxen.dom.DOMXPath;
+import org.w3c.dom.Document;
+
+/**
+ * @author Elliotte Rusty Harold
+ *
+ */
+public class TranslateFunctionTest extends TestCase {
+
+    private Document doc;
+    
+    protected void setUp() throws ParserConfigurationException
+    {
+        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        factory.setNamespaceAware(true);
+        DocumentBuilder builder = factory.newDocumentBuilder();
+        doc = builder.newDocument();
+        doc.appendChild(doc.createElement("root"));
+    }
+
+    public void testTranslate() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "translate('abc', 'b', 'd')" );
+        String result = (String) xpath.evaluate( doc );
+        assertEquals("adc", result);
+    }    
+  
+    public void testTranslateIgnoresExtraArguments() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "translate('abc', 'b', 'dghf')" );
+        String result = (String) xpath.evaluate( doc );
+        assertEquals("adc", result);
+    }    
+  
+    public void testTranslateFunctionRequiresAtLeastThreeArguments() 
+      throws JaxenException {
+        
+        XPath xpath = new DOMXPath("translate('a', 'b')");
+        
+        try {
+            xpath.selectNodes(doc);
+            fail("Allowed translate function with two arguments");
+        }
+        catch (FunctionCallException ex) {
+            assertNotNull(ex.getMessage());
+        }
+        
+    }    
+
+    public void testTranslateRequiresAtMostThreeArguments() 
+      throws JaxenException {
+        
+        XPath xpath = new DOMXPath("substring-after('a', 'a', 'a', 'a')");
+        
+        try {
+            xpath.selectNodes(doc);
+            fail("Allowed translate function with four arguments");
+        }
+        catch (FunctionCallException ex) {
+            assertNotNull(ex.getMessage());
+        }
+        
+    }   
+    
+    public void testTranslateStringThatContainsNonBMPChars() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "translate('ab\uD834\uDD00b', 'b', 'd')" );
+        String result = (String) xpath.evaluate( doc );
+        assertEquals("ad\uD834\uDD00d", result);
+    }
+    
+
+    public void testTranslateNonBMPChars() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "translate('ab\uD834\uDD00b', '\uD834\uDD00', 'd')" );
+        String result = (String) xpath.evaluate( doc );
+        assertEquals("abdb", result);
+    }   
+    
+
+    public void testTranslateNonBMPChars2() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "translate('ab\uD834\uDD00b', '\uD834\uDD00', 'da')" );
+        String result = (String) xpath.evaluate( doc );
+        assertEquals("abdb", result);
+    }   
+    
+
+    public void testTranslateWithNonBMPChars() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "translate('abc', 'c', '\uD834\uDD00')" );
+        String result = (String) xpath.evaluate( doc );
+        assertEquals("ab\uD834\uDD00", result);
+    }   
+    
+
+    public void testTranslateWithNonBMPChars2() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "translate('abc', 'c', '\uD834\uDD00b')" );
+        String result = (String) xpath.evaluate( doc );
+        assertEquals("ab\uD834\uDD00", result);
+    }   
+    
+
+    public void testTranslateWithMalformedSurrogatePair() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "translate('abc', 'c', '\uD834X\uDD00b')" );
+        try {
+            xpath.evaluate( doc );
+            fail("Allowed malformed surrogate pair");
+        }
+        catch (FunctionCallException ex) {
+            assertNotNull(ex.getMessage());
+        }
+    }   
+    
+
+    public void testTranslateWithMissingLowSurrogate() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "translate('abc', 'c', 'AB\uD834X')" );
+        try {
+            xpath.evaluate( doc );
+            fail("Allowed malformed surrogate pair");
+        }
+        catch (FunctionCallException ex) {
+            assertNotNull(ex.getMessage());
+        }
+    }   
+    
+
+    public void testTranslateWithExtraCharsInReplacementString() throws JaxenException
+    {
+        XPath xpath = new DOMXPath( "translate('abc', 'c', 'def')" );
+        String result = (String) xpath.evaluate( doc );
+        assertEquals("abd", result);
+    }   
+    
+
+}
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/TrueTest.java b/libjaxen-java/src/java/test/org/jaxen/test/TrueTest.java
new file mode 100644
index 0000000..7d496e2
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/TrueTest.java
@@ -0,0 +1,98 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2005 Elliotte Rusty Harold.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+
+package org.jaxen.test;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import junit.framework.TestCase;
+
+import org.jaxen.FunctionCallException;
+import org.jaxen.JaxenException;
+import org.jaxen.XPath;
+import org.jaxen.dom.DOMXPath;
+import org.w3c.dom.Document;
+
+/**
+ * @author Elliotte Rusty Harold
+ *
+ */
+public class TrueTest extends TestCase {
+
+    private Document doc;
+    
+    public void setUp() throws ParserConfigurationException
+    {
+        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        factory.setNamespaceAware(true);
+        DocumentBuilder builder = factory.newDocumentBuilder();
+        doc = builder.newDocument();
+        doc.appendChild(doc.createElement("root"));
+    }
+
+
+    public TrueTest(String name) {
+        super(name);
+    }
+
+    public void testTrueOfNumber() throws JaxenException
+    {
+        try
+        {
+            XPath xpath = new DOMXPath( "true(3)" );
+            xpath.selectNodes( doc );
+            fail("true() function took arguments");
+        }
+        catch (FunctionCallException e) 
+        {
+            assertEquals("true() requires no arguments.", e.getMessage());
+        }
+    }    
+
+}
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/UnresolvableExceptionTest.java b/libjaxen-java/src/java/test/org/jaxen/test/UnresolvableExceptionTest.java
new file mode 100644
index 0000000..a45da53
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/UnresolvableExceptionTest.java
@@ -0,0 +1,109 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2005 Elliotte Rusty Harold.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+
+package org.jaxen.test;
+
+
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.jaxen.JaxenException;
+import org.jaxen.UnresolvableException;
+import org.jaxen.XPath;
+import org.jaxen.dom.DOMXPath;
+
+import junit.framework.TestCase;
+
+
+/**
+ * @author Elliotte Rusty Harold
+ *
+ */
+public class UnresolvableExceptionTest extends TestCase {
+
+    public UnresolvableExceptionTest(String name) {
+        super(name);
+    }
+
+    private org.w3c.dom.Document doc;
+    
+    protected void setUp() throws ParserConfigurationException {
+        
+        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        factory.setNamespaceAware(true);
+        doc = factory.newDocumentBuilder().newDocument();
+        doc.appendChild(doc.createElement("foo"));
+    }    
+    
+    public void testUnresolvableVariable() throws JaxenException {
+        
+        try {
+            XPath xpath = new DOMXPath("//foo[bar = $var]");
+            xpath.evaluate(doc);
+            fail("Didn't throw Unresolvable Exception");
+        }
+        catch (UnresolvableException ex) {
+            assertNotNull(ex.getMessage());
+        }
+    }    
+ 
+  
+    public void testUnresolvableFunction() throws JaxenException {
+        
+        try {
+            XPath xpath = new DOMXPath("nonesuch()");
+            xpath.evaluate(doc);
+            fail("Didn't throw Unresolvable Exception");
+        }
+        catch (UnresolvableException ex) {
+            assertNotNull(ex.getMessage());
+        }
+    }    
+ 
+  
+
+}
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/UnsupportedAxisExceptionTest.java b/libjaxen-java/src/java/test/org/jaxen/test/UnsupportedAxisExceptionTest.java
new file mode 100644
index 0000000..06ac6d5
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/UnsupportedAxisExceptionTest.java
@@ -0,0 +1,74 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2005 Elliotte Rusty Harold.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+
+package org.jaxen.test;
+
+
+import org.jaxen.UnsupportedAxisException;
+
+import junit.framework.TestCase;
+
+
+/**
+ * @author Elliotte Rusty Harold
+ *
+ */
+public class UnsupportedAxisExceptionTest extends TestCase {
+
+    public UnsupportedAxisExceptionTest(String name) {
+        super(name);
+    }
+
+    public void testMessageIsNonNull() {
+        
+        UnsupportedAxisException ex = new UnsupportedAxisException("Hello");
+        assertEquals("Hello", ex.getMessage());
+        
+    }    
+  
+
+}
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/UtilTests.java b/libjaxen-java/src/java/test/org/jaxen/test/UtilTests.java
new file mode 100644
index 0000000..24ae80e
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/UtilTests.java
@@ -0,0 +1,80 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2005 Elliotte Rusty Harold
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+
+
+package org.jaxen.test;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+/**
+ * <p>
+ *   Collect the org.jaxen.util tests.
+ * </p>
+ * 
+ * @author Elliotte Rusty Harold
+ * @version 1.1b9
+ *
+ */
+public class UtilTests {
+    
+    public static Test suite() {
+        
+        TestSuite result = new TestSuite();
+        result.addTest(new TestSuite(SingletonListTest.class));
+        result.addTest(new TestSuite(SingleObjectIteratorTest.class));
+        result.addTest(new TestSuite(AncestorOrSelfAxisIteratorTest.class));
+        result.addTest(new TestSuite(DescendantAxisIteratorTest.class));
+        result.addTest(new TestSuite(FollowingAxisIteratorTest.class));
+        result.addTest(new TestSuite(FollowingSiblingAxisIteratorTest.class));
+        result.addTest(new TestSuite(PrecedingAxisIteratorTest.class));
+        result.addTest(new TestSuite(PrecedingSiblingAxisIteratorTest.class));
+        return result;
+        
+    }
+    
+}
\ No newline at end of file
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/VariableContextTest.java b/libjaxen-java/src/java/test/org/jaxen/test/VariableContextTest.java
new file mode 100644
index 0000000..66604bf
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/VariableContextTest.java
@@ -0,0 +1,115 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2005 Elliotte Rusty Harold
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+
+
+
+package org.jaxen.test;
+
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.jaxen.JaxenException;
+import org.jaxen.SimpleVariableContext;
+import org.jaxen.UnresolvableException;
+import org.jaxen.dom.DOMXPath;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import junit.framework.TestCase;
+
+/**
+ * <p>
+ *  Test for function context.
+ * </p>
+ * 
+ * @author Elliotte Rusty Harold
+ * @version 1.1b9
+ *
+ */
+public class VariableContextTest extends TestCase
+{
+
+    private Document doc;
+    
+    public void setUp() throws ParserConfigurationException {
+        
+        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        factory.setNamespaceAware(true);
+        doc = factory.newDocumentBuilder().newDocument();
+        Element root = doc.createElementNS("http://www.example.org/", "root");
+        doc.appendChild(root);
+        root.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns", "http://www.example.org/");
+              
+    }
+    
+ 
+    public void testUnresolvableVariable() throws JaxenException {
+        
+        DOMXPath xpath = new DOMXPath("$a/root");
+        
+        try {
+            xpath.evaluate(doc);
+            fail("Evaluated nonexistent variable");
+        }
+        catch (UnresolvableException ex) {
+            assertEquals("Variable a", ex.getMessage());
+        }
+        
+    }
+ 
+    public void testGetVariableContext() throws JaxenException {      
+        DOMXPath xpath = new DOMXPath("/root/child");
+        assertNotNull(xpath.getVariableContext());
+    }
+ 
+    public void testSetNamespacelessVariable() throws JaxenException { 
+        SimpleVariableContext context = new SimpleVariableContext();
+        context.setVariableValue("foo", "bar");
+        assertEquals("bar", context.getVariableValue("", "", "foo"));
+    }
+ 
+}
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/XOMNavigatorTest.java b/libjaxen-java/src/java/test/org/jaxen/test/XOMNavigatorTest.java
new file mode 100644
index 0000000..8d6ec4a
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/XOMNavigatorTest.java
@@ -0,0 +1,73 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2003 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+
+
+package org.jaxen.test;
+
+import org.jaxen.Navigator;
+import org.jaxen.xom.DocumentNavigator;
+import nu.xom.Builder;
+
+public class XOMNavigatorTest extends XPathTestBase
+{
+    private Builder builder = new Builder();
+
+    public XOMNavigatorTest(String name)
+    {
+        super( name );
+    }
+
+    public Navigator getNavigator()
+    {
+        return new DocumentNavigator();
+    }
+
+    public Object getDocument(String url) throws Exception
+    {
+        return this.builder.build( url );
+    }
+}
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/XOMPerformance.java b/libjaxen-java/src/java/test/org/jaxen/test/XOMPerformance.java
new file mode 100644
index 0000000..1e9335e
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/XOMPerformance.java
@@ -0,0 +1,67 @@
+/*
+ $Id$
+
+ Copyright 2003 The Werken Company. All Rights Reserved.
+ 
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+  * Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+
+  * Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+
+  * Neither the name of the Jaxen Project nor the names of its
+    contributors may be used to endorse or promote products derived 
+    from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ */
+package org.jaxen.test;
+
+import org.jaxen.xom.XOMXPath;
+
+import nu.xom.Document;
+import nu.xom.Element;
+import nu.xom.Builder;
+
+class XOMPerformance {
+    
+    public static void main(String[] args) {
+        
+        try {
+            Document doc = new Builder().build("http://www.ibiblio.org/xml/examples/shakespeare/much_ado.xml");
+            XOMXPath xpath = new XOMXPath("PLAY/ACT/SCENE/SPEECH/SPEAKER");
+            
+            long start = System.currentTimeMillis();
+            
+            int count = 0;
+            for (int i = 0; i < 1000; i++) {
+                Element speaker = (Element) xpath.selectSingleNode(doc);
+                count += (speaker == null ? 0 : 1);
+            }
+            
+            long end = System.currentTimeMillis();
+            System.out.println((end - start));
+            System.out.println(count);
+            
+        } catch (Exception ex) {
+            ex.printStackTrace();
+        }
+    }
+    
+}
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/XOMTests.java b/libjaxen-java/src/java/test/org/jaxen/test/XOMTests.java
new file mode 100644
index 0000000..7d53231
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/XOMTests.java
@@ -0,0 +1,74 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2005 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+
+
+package org.jaxen.test;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+/**
+ * <p>
+ *   Collect Jaxen's XOM tests.
+ * </p>
+ * 
+ * @author Elliotte Rusty Harold
+ * @version 1.1b9
+ *
+ */
+public class XOMTests {
+    
+    public static Test suite() {
+        
+        TestSuite result = new TestSuite();
+        result.addTest(new TestSuite(XOMNavigatorTest.class));
+        result.addTest(new TestSuite(XOMXPathTest.class));
+        return result;
+        
+    }
+    
+}
\ No newline at end of file
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/XOMXPathTest.java b/libjaxen-java/src/java/test/org/jaxen/test/XOMXPathTest.java
new file mode 100644
index 0000000..657d21a
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/XOMXPathTest.java
@@ -0,0 +1,106 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2003 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+
+
+package org.jaxen.test;
+
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.List;
+
+import junit.framework.TestCase;
+import nu.xom.Builder;
+import nu.xom.Document;
+import nu.xom.Element;
+import nu.xom.ParsingException;
+
+import org.jaxen.JaxenException;
+import org.jaxen.XPath;
+import org.jaxen.xom.XOMXPath;
+
+public class XOMXPathTest extends TestCase
+{
+
+    private static final String BASIC_XML = "xml/basic.xml";
+
+    public XOMXPathTest(String name)
+    {
+        super( name );
+    }
+
+    public void testConstruction() throws JaxenException
+    {
+        new XOMXPath( "/foo/bar/baz" );
+    }
+
+    public void testSelection() throws ParsingException, IOException, JaxenException
+    {
+        XPath xpath = new XOMXPath( "/foo/bar/baz" );
+
+        Builder builder = new Builder();
+
+        Document doc = builder.build( BASIC_XML );
+
+        List results = xpath.selectNodes( doc );
+
+        assertEquals( 3,
+                      results.size() );
+
+        Iterator iter = results.iterator();
+
+        assertEquals( "baz",
+                      ((Element)iter.next()).getLocalName() );
+
+        assertEquals( "baz",
+                      ((Element)iter.next()).getLocalName() );
+
+        assertEquals( "baz",
+                      ((Element)iter.next()).getLocalName() );
+
+        assertTrue( ! iter.hasNext() );
+    }
+}
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/XPathReaderFactoryTest.java b/libjaxen-java/src/java/test/org/jaxen/test/XPathReaderFactoryTest.java
new file mode 100644
index 0000000..23b095e
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/XPathReaderFactoryTest.java
@@ -0,0 +1,150 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Jaxen Project and was originally
+ * created by bob mcwhirter <bob at werken.com> and
+ * James Strachan <jstrachan at apache.org>.  For more information on the
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ *
+ * $Id$
+ */
+
+package org.jaxen.test;
+
+import junit.framework.TestCase;
+
+import org.jaxen.saxpath.SAXPathException;
+import org.jaxen.saxpath.XPathReader;
+import org.jaxen.saxpath.helpers.XPathReaderFactory;
+
+public class XPathReaderFactoryTest extends TestCase
+{
+    public XPathReaderFactoryTest(String name)
+    {
+        super( name );
+    }
+    
+    
+    protected void tearDown() {
+        System.setProperty( XPathReaderFactory.DRIVER_PROPERTY, "" );
+    }
+
+    public void testDefault() throws SAXPathException
+    {
+        System.setProperty( XPathReaderFactory.DRIVER_PROPERTY,
+                            "" );
+        XPathReader reader = XPathReaderFactory.createReader();
+        assertNotNull( reader );
+    }
+
+    public void testValidByProperty() throws SAXPathException
+    {
+        System.setProperty( XPathReaderFactory.DRIVER_PROPERTY,
+                            "org.jaxen.test.MockXPathReader"  );
+
+        XPathReader reader = XPathReaderFactory.createReader();
+        assertNotNull( reader );
+        assertSame( MockXPathReader.class, reader.getClass() );
+    }
+
+    public void testInvalidByProperty() 
+    {
+        System.setProperty( XPathReaderFactory.DRIVER_PROPERTY,
+                            "java.lang.String" );
+
+        try
+        {
+            XPathReaderFactory.createReader();
+            fail( "Should have thrown SAXPathException" );
+        }
+        catch (SAXPathException e) {
+            // expected and correct
+            assertNotNull(e.getMessage());
+        }
+    }
+
+    public void testNonExistantByProperty()
+    {
+        System.setProperty( XPathReaderFactory.DRIVER_PROPERTY,
+                            "i.am.a.class.that.does.not.Exist" );
+
+        try
+        {
+            XPathReaderFactory.createReader();
+            fail( "Should have thrown SAXPathException" );
+        }
+        catch (org.jaxen.saxpath.SAXPathException e)
+        {
+            // expected and correct
+        }
+    }
+
+    public void testValidExplicit() throws SAXPathException
+    {
+        XPathReader reader = XPathReaderFactory.createReader( "org.jaxen.test.MockXPathReader" );
+        assertNotNull( reader );
+        assertSame( MockXPathReader.class, reader.getClass() );
+    }
+
+    public void testInvalidExplicit()
+    {
+        try
+        {
+            XPathReaderFactory.createReader( "java.lang.String" );
+            fail( "Should have thrown SAXPathException" );
+        }
+        catch (org.jaxen.saxpath.SAXPathException e)
+        {
+            // expected and correct
+        }
+    }
+
+    public void testNonExistantExplicit()
+    {
+        try
+        {
+            XPathReaderFactory.createReader( "i.am.a.class.that.does.not.Exist" );
+            fail( "Should have thrown SAXPathException" );
+        }
+        catch (org.jaxen.saxpath.SAXPathException e)
+        {
+            // expected and correct
+        }
+    }
+}
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/XPathReaderTest.java b/libjaxen-java/src/java/test/org/jaxen/test/XPathReaderTest.java
new file mode 100644
index 0000000..7d604c9
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/XPathReaderTest.java
@@ -0,0 +1,472 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Jaxen Project and was originally
+ * created by bob mcwhirter <bob at werken.com> and
+ * James Strachan <jstrachan at apache.org>.  For more information on the
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ *
+ * $Id$
+ */
+
+
+package org.jaxen.test;
+
+import java.io.IOException;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import junit.framework.TestCase;
+
+import org.jaxen.JaxenException;
+import org.jaxen.XPath;
+import org.jaxen.dom.DOMXPath;
+import org.jaxen.saxpath.SAXPathException;
+import org.jaxen.saxpath.base.XPathReader;
+import org.jaxen.saxpath.XPathSyntaxException;
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+public class XPathReaderTest extends TestCase
+{
+    private ConformanceXPathHandler actual;
+    private Document doc;
+
+    private XPathReader reader;
+
+    private String[] paths = {
+        "/foo/bar[@a='1' and @b='2']",
+        "/foo/bar[@a='1' and @b!='2']",
+        "$varname[@a='1']",
+        "//attribute::*[.!='crunchy']",
+        "'//*[contains(string(text()),\"yada yada\")]'",
+    };
+
+    private String[][] bogusPaths = {
+        new String[]{"chyld::foo", "Expected valid axis name instead of [chyld]"},
+        new String[]{"foo/tacos()", "Expected node-type"},
+        new String[]{"foo/tacos()", "Expected node-type"},
+        new String[]{"*:foo", "Unexpected ':'"},
+        new String[]{"/foo/bar[baz", "Expected: ]"},
+        new String[]{"/cracker/cheese[(mold > 1) and (sense/taste", "Expected: )"},
+        new String[]{"//", "Location path cannot end with //"},
+        new String[]{"foo/$variable/foo", "Expected one of '.', '..', '@', '*', <QName>"}
+    };
+
+    public XPathReaderTest( String name )
+    {
+        super( name );
+    }
+
+    public void setUp() throws ParserConfigurationException, SAXException, IOException
+    {
+        this.reader = new XPathReader();
+
+        this.actual = new ConformanceXPathHandler();
+
+        this.reader.setXPathHandler( this.actual );
+        
+        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        factory.setNamespaceAware(true);
+        DocumentBuilder builder = factory.newDocumentBuilder();
+        doc = builder.parse( "xml/basic.xml" );
+
+    }
+
+    public void tearDown()
+    {
+        this.reader = null;
+    }
+
+    // --------------------------------------------------------------------------------
+    // --------------------------------------------------------------------------------
+
+
+    public void testPaths() throws SAXPathException
+    {
+
+        for( int i = 0; i < paths.length; ++i )
+        {
+            reader.parse( paths[i] );
+        }
+    }
+
+    public void testBogusPaths() throws SAXPathException
+    {
+
+        for( int i = 0; i < bogusPaths.length; ++i )
+        {
+            final String[] bogusPath = bogusPaths[i];
+
+            try
+            {
+                reader.parse( bogusPath[0] );
+                fail( "Should have thrown XPathSyntaxException for " + bogusPath[0]);
+            }
+            catch( XPathSyntaxException e )
+            {
+                assertEquals( bogusPath[1], e.getMessage() );
+            }
+        }
+    }
+
+    public void testChildrenOfNumber() throws SAXPathException
+    {
+        try
+        {
+            reader.parse( "1/child::test" );
+            fail( "Should have thrown XPathSyntaxException for 1/child::test");
+        }
+        catch( XPathSyntaxException e )
+        {
+            assertEquals( "Node-set expected", e.getMessage() );
+        }
+    }
+
+    public void testChildIsNumber() throws SAXPathException
+    {
+        try
+        {
+            reader.parse( "jane/3" );
+            fail( "Should have thrown XPathSyntaxException for jane/3");
+        }
+        catch( XPathSyntaxException e )
+        {
+            assertEquals( "Expected one of '.', '..', '@', '*', <QName>", e.getMessage() );
+        }
+        
+    }
+
+    public void testNumberOrNumber()
+    {
+
+        try
+        {
+            XPath xpath = new DOMXPath( "4 | 5" );
+            xpath.selectNodes( doc );
+            fail( "Should have thrown XPathSyntaxException for 4 | 5");
+        }
+        catch( JaxenException e )
+        {
+            assertEquals( "Unions are only allowed over node-sets", e.getMessage() );
+        }
+    }
+
+    public void testStringOrNumber()
+    {
+
+        try
+        {
+            XPath xpath = new DOMXPath( "\"test\" | 5" );
+            xpath.selectNodes( doc );
+            fail( "Should have thrown XPathSyntaxException for \"test\" | 5");
+        }
+        catch( JaxenException e )
+        {
+            assertEquals( "Unions are only allowed over node-sets", e.getMessage() );
+        }
+    }    
+    
+    public void testStringOrString() 
+    {
+
+        try
+        {
+            XPath xpath = new DOMXPath( "\"test\" | \"festival\"" );
+            xpath.selectNodes( doc );
+            fail( "Should have thrown XPathSyntaxException for \"test\" | 5");
+        }
+        catch( JaxenException e )
+        {
+            assertEquals( "Unions are only allowed over node-sets", e.getMessage() );
+        }
+        
+    }    
+    
+    public void testUnionofNodesAndNonNodes() 
+    {
+
+        try
+        {
+            XPath xpath = new DOMXPath( "count(//*) | //* " );
+            xpath.selectNodes( doc );
+            fail( "Should have thrown XPathSyntaxException for \"count(//*) | //* ");
+        }
+        catch( JaxenException e )
+        {
+            assertEquals( "Unions are only allowed over node-sets", e.getMessage() );
+        }
+    }    
+    
+    public void testValidAxis() throws SAXPathException
+    {
+        reader.parse( "child::foo" );
+    }
+
+    public void testInvalidAxis() throws SAXPathException
+    {
+
+        try
+        {
+            reader.parse( "chyld::foo" );
+            fail( "Should have thrown XPathSyntaxException" );
+        }
+        catch( XPathSyntaxException ex )
+        {
+            assertNotNull(ex.getMessage());
+        }
+
+    }
+
+/*    public void testSimpleNameStep() throws SAXPathException
+    {
+        this.text = "foo";
+        this.reader.setUpParse( this.text );
+        this.reader.step( );
+        this.expected.startNameStep( Axis.CHILD,
+                                  "",
+                                  "foo" );
+        this.expected.endNameStep();
+        assertEquals( this.expected,
+          this.actual );
+
+    } 
+
+    public void testNameStepWithAxisAndPrefix() throws SAXPathException
+    {
+        this.text = "parent::foo:bar";
+        this.reader.setUpParse( this.text );
+        this.reader.step( );
+        this.expected.startNameStep( Axis.PARENT,
+                                  "foo",
+                                  "bar" );
+        this.expected.endNameStep();
+        assertEquals( this.expected,
+          this.actual );
+
+    }
+
+    public void testNodeStepWithAxis() throws SAXPathException
+    {
+
+        this.text = "parent::node()";
+        this.reader.setUpParse( this.text );
+        this.reader.step();
+        this.expected.startAllNodeStep( Axis.PARENT );
+        this.expected.endAllNodeStep();
+        assertEquals( this.expected,
+          this.actual );
+
+    }
+
+    public void testProcessingInstructionStepWithName() throws SAXPathException
+    {
+        this.text = "parent::processing-instruction('cheese')";
+        this.reader.setUpParse( this.text );
+        this.reader.step( );
+        this.expected.startProcessingInstructionNodeStep( Axis.PARENT,
+                                                           "cheese" );
+        this.expected.endProcessingInstructionNodeStep();
+        assertEquals( this.expected,
+          this.actual );
+    }
+
+    public void testProcessingInstructionStepNoName() throws SAXPathException
+    {
+        this.text = "parent::processing-instruction()";
+        this.reader.setUpParse( this.text );
+        this.reader.step( );
+        this.expected.startProcessingInstructionNodeStep( Axis.PARENT,
+                                                       "" );
+        this.expected.endProcessingInstructionNodeStep();
+        assertEquals( this.expected,
+          this.actual );
+
+    }
+
+    public void testAllNodeStep() throws SAXPathException
+    {
+
+        this.text = "parent::node()";
+        this.reader.setUpParse( this.text );
+        this.reader.step( );
+        this.expected.startAllNodeStep( Axis.PARENT );
+        this.expected.endAllNodeStep();
+        assertEquals( this.expected,
+          this.actual );
+
+    }
+
+    public void testTextNodeStep() throws SAXPathException
+    {
+
+        this.text = "parent::text()";
+        this.reader.setUpParse( this.text );
+        this.reader.step( );
+        this.expected.startTextNodeStep( Axis.PARENT );
+        this.expected.endTextNodeStep();
+        assertEquals( this.expected,
+          this.actual );
+
+    }
+
+    public void testCommentNodeStep() throws SAXPathException
+    {
+
+        this.text = "parent::comment()";
+        this.reader.setUpParse( this.text );
+        this.reader.step( );
+        this.expected.startCommentNodeStep( Axis.PARENT );
+        this.expected.endCommentNodeStep();
+        assertEquals( this.expected,
+          this.actual );
+
+    }*/
+
+    public void testLocationPathStartsWithVariable() throws SAXPathException
+    {
+
+        reader.parse( "$variable/foo" );
+
+    }
+
+    public void testLocationPathStartsWithParentheses() throws SAXPathException
+    {
+
+        reader.parse( "(//x)/foo" );
+
+    }
+
+    /*public void testRelativeLocationPath() throws SAXPathException
+    {
+
+        this.text = "foo/bar/baz";
+        this.reader.setUpParse( this.text );
+        this.reader.locationPath( false );
+        this.expected.startRelativeLocationPath();
+        this.expected.startNameStep( Axis.CHILD,
+                                  "",
+                                  "foo" );
+        this.expected.endNameStep();
+        this.expected.startNameStep( Axis.CHILD,
+                                  "",
+                                  "bar" );
+        this.expected.endNameStep();
+        this.expected.startNameStep( Axis.CHILD,
+                                  "",
+                                  "baz" );
+        this.expected.endNameStep();
+        this.expected.endRelativeLocationPath();
+        assertEquals( this.expected,
+          this.actual );
+
+    }
+
+    public void testAbsoluteLocationPath() throws SAXPathException
+    {
+        
+        this.text = "/foo/bar/baz";
+        this.reader.setUpParse( this.text );
+        this.reader.locationPath( true );
+        this.expected.startAbsoluteLocationPath();
+        this.expected.startNameStep( Axis.CHILD,
+                                  "",
+                                  "foo" );
+        this.expected.endNameStep();
+        this.expected.startNameStep( Axis.CHILD,
+                                  "",
+                                  "bar" );
+        this.expected.endNameStep();
+        this.expected.startNameStep( Axis.CHILD,
+                                  "",
+                                  "baz" );
+        this.expected.endNameStep();
+        this.expected.endAbsoluteLocationPath();
+        assertEquals( this.expected,
+          this.actual );
+
+    }*/
+
+    public void testNoSpaceAfterDiv() throws JaxenException 
+    {
+        XPath xpath = new DOMXPath( "105 div10" );
+        Double result = (Double) xpath.evaluate(doc);
+        assertEquals(10.5, result.doubleValue(), 0.000001);
+    }
+
+
+    public void testNoSpaceAfterMod() throws JaxenException 
+    {
+        XPath xpath = new DOMXPath( "105 mod10" );
+        Double result = (Double) xpath.evaluate(doc);
+        assertEquals(5, result.intValue());
+    }
+
+
+    public void testNoSpaceAfterPlus() throws JaxenException 
+    {
+        XPath xpath = new DOMXPath( "105 +10" );
+        Double result = (Double) xpath.evaluate(doc);
+        assertEquals(115, result.intValue());
+    }
+    
+    public void testNoSpaceAfterAnd() throws JaxenException 
+    {
+        XPath xpath = new DOMXPath("true() andfalse()");
+        Boolean result = (Boolean) xpath.evaluate(doc);
+        assertFalse(result.booleanValue());
+    }
+    
+    public void testNoSpaceAfterOr() throws JaxenException 
+    {
+        XPath xpath = new DOMXPath("true() orfalse()");
+        Boolean result = (Boolean) xpath.evaluate(doc);
+        assertTrue(result.booleanValue());
+    }
+    
+    public void testAndImmediatelyFollowedByRelativeLocationPath() throws JaxenException  
+    {
+        XPath xpath = new DOMXPath("true() andfoo");
+        Boolean result = (Boolean) xpath.evaluate(doc);
+        assertTrue(result.booleanValue());
+    }
+    
+}
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/XPathSyntaxExceptionTest.java b/libjaxen-java/src/java/test/org/jaxen/test/XPathSyntaxExceptionTest.java
new file mode 100644
index 0000000..da9e418
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/XPathSyntaxExceptionTest.java
@@ -0,0 +1,106 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2005 Elliotte Rusty Harold.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many 
+ * individuals on behalf of the Jaxen Project and was originally 
+ * created by bob mcwhirter <bob at werken.com> and 
+ * James Strachan <jstrachan at apache.org>.  For more information on the 
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ * 
+ * $Id$
+ */
+
+package org.jaxen.test;
+
+
+import junit.framework.TestCase;
+
+import org.jaxen.JaxenException;
+import org.jaxen.XPathSyntaxException;
+import org.jaxen.dom.*;
+
+/**
+ * @author Elliotte Rusty Harold
+ *
+ */
+public class XPathSyntaxExceptionTest extends TestCase {
+
+    public XPathSyntaxExceptionTest(String name) {
+        super(name);
+    }
+
+    public void testGetXPath() throws JaxenException {
+        
+        try {
+            new DOMXPath("///triple slash");
+            fail("Bad parsing");
+        }
+        catch (XPathSyntaxException ex) {
+            assertEquals("///triple slash", ex.getXPath());
+        }
+        
+    }    
+  
+    public void testGetPositionMarker() throws JaxenException {
+        
+        try {
+            new DOMXPath("///triple slash");
+            fail("Bad parsing");
+        }
+        catch (XPathSyntaxException ex) {
+            assertTrue(ex.getPositionMarker().startsWith("  "));
+            assertTrue(ex.getPositionMarker().endsWith("^"));
+        }
+        
+    }    
+
+    public void testGetMultilineMessage() throws JaxenException {
+        
+        try {
+            new DOMXPath("///triple slash");
+            fail("Bad parsing");
+        }
+        catch (XPathSyntaxException ex) {
+            String message = ex.getMultilineMessage();
+            assertTrue(message.indexOf("\n///triple slash\n") > 1);
+            assertTrue(message.endsWith("^"));
+        }
+        
+    }    
+
+}
diff --git a/libjaxen-java/src/java/test/org/jaxen/test/XPathTestBase.java b/libjaxen-java/src/java/test/org/jaxen/test/XPathTestBase.java
new file mode 100644
index 0000000..0a27fda
--- /dev/null
+++ b/libjaxen-java/src/java/test/org/jaxen/test/XPathTestBase.java
@@ -0,0 +1,1722 @@
+/*
+ * $Header$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ * Copyright 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 
+ *   * Neither the name of the Jaxen Project nor the names of its
+ *     contributors may be used to endorse or promote products derived 
+ *     from this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Jaxen Project and was originally
+ * created by bob mcwhirter <bob at werken.com> and
+ * James Strachan <jstrachan at apache.org>.  For more information on the
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ *
+ * $Id$
+ */
+
+
+package org.jaxen.test;
+
+import junit.framework.TestCase;
+
+import org.jaxen.*;
+import org.jaxen.dom.DOMXPath;
+import org.jaxen.function.StringFunction;
+import org.jaxen.saxpath.helpers.XPathReaderFactory;
+import org.jaxen.pattern.Pattern;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+public abstract class XPathTestBase extends TestCase
+{
+    protected static String VAR_URI   = "http://jaxen.org/test-harness/var";
+    protected static String TESTS_XML = "xml/test/tests.xml";
+
+    protected static boolean verbose = false;
+    protected static boolean debug = false;
+    private ContextSupport contextSupport;
+
+    protected XPathTestBase(String name)
+    {
+        super(name);
+    }
+
+    protected void setUp() throws Exception
+    {
+        this.contextSupport = null;
+        System.setProperty(XPathReaderFactory.DRIVER_PROPERTY,
+                "");
+        log("-----------------------------");
+    }
+
+    public void log(String text)
+    {
+        log(verbose,
+                text);
+    }
+
+    private void log(boolean actualVerbose,
+                    String text)
+    {
+        if (actualVerbose) System.out.println(text);
+    }
+
+    private void assertCountXPath(int expectedSize, Object context, String xpathStr) throws JaxenException
+    {
+        assertCountXPath2(expectedSize, context, xpathStr);
+    }
+
+    private Object assertCountXPath2(int expectedSize, Object context, String xpathStr) throws JaxenException
+    {
+        log(debug,
+                "  Select :: " + xpathStr);
+        DOMXPath xpath = new DOMXPath(xpathStr);
+        List results = xpath.selectNodes(getContext(context));
+        log(debug,
+                "    Expected Size :: " + expectedSize);
+        log(debug,
+                "    Result Size   :: " + results.size());
+        if (expectedSize != results.size())
+        {
+            log(debug,
+                    "      ## FAILED");
+            log(debug,
+                    "      ## xpath: " + xpath + " = " + xpath.debug());
+            Iterator resultIter = results.iterator();
+            while (resultIter.hasNext())
+            {
+                log(debug,
+                        "      --> " + resultIter.next());
+            }
+        }
+        assertEquals(xpathStr,
+                expectedSize,
+                results.size());
+        if (expectedSize > 0)
+        {
+            return results.get(0);
+        }
+        return null;
+    }
+
+    private void assertInvalidXPath(Object context, String xpathStr)
+    {
+        try
+        {
+            log(debug,
+                    "  Select :: " + xpathStr);
+            DOMXPath xpath = new DOMXPath(xpathStr);
+            List results = xpath.selectNodes(getContext(context));
+            log(debug,
+                    "    Result Size   :: " + results.size());
+            fail("An exception was expected.");
+        }
+        catch (JaxenException e)
+        {
+            log(debug, "    Caught expected exception " + e.getMessage());
+        }
+    }
+
+    private void assertValueOfXPath(String expected, Object context, String xpathStr) throws JaxenException
+    {
+            DOMXPath xpath = new DOMXPath(xpathStr);
+            Object node = xpath.evaluate(getContext(context));
+            String result = StringFunction.evaluate(node,
+                    getNavigator());
+            log(debug,
+                    "  Select :: " + xpathStr);
+            log(debug,
+                    "    Expected :: " + expected);
+            log(debug,
+                    "    Result   :: " + result);
+            if (!expected.equals(result))
+            {
+                log(debug,
+                        "      ## FAILED");
+                log(debug,
+                        "      ## xpath: " + xpath + " = " + xpath.debug());
+            }
+            assertEquals(xpathStr,
+                    expected,
+                    result);
+        }
+
+    private Context getContext(Object contextNode)
+    {
+        Context context = new Context(getContextSupport());
+        List list = new ArrayList(1);
+        list.add(contextNode);
+        context.setNodeSet(list);
+        return context;
+    }
+
+    private ContextSupport getContextSupport()
+    {
+        if (this.contextSupport == null)
+        {
+            this.contextSupport = new ContextSupport(new SimpleNamespaceContext(),
+                    XPathFunctionContext.getInstance(),
+                    new SimpleVariableContext(),
+                    getNavigator());
+        }
+        return this.contextSupport;
+    }
+
+    protected abstract Navigator getNavigator();
+    protected abstract Object getDocument(String url) throws Exception;
+
+    public void testGetNodeType() throws FunctionCallException, UnsupportedAxisException
+    {
+        Navigator nav = getNavigator();
+        Object document = nav.getDocument("xml/testNamespaces.xml");
+        int count = 0;
+        Iterator descendantOrSelfAxisIterator = nav.getDescendantOrSelfAxisIterator(document);
+        while (descendantOrSelfAxisIterator.hasNext())
+        {
+            Object node = descendantOrSelfAxisIterator.next();
+            Iterator namespaceAxisIterator = nav.getNamespaceAxisIterator(node);
+            while (namespaceAxisIterator.hasNext())
+            {
+                count++;
+                assertEquals("Node type mismatch", Pattern.NAMESPACE_NODE, nav.getNodeType(namespaceAxisIterator.next()));
+            }
+        }
+        assertEquals(25, count);
+    }
+
+
+    /* test for jaxen-24
+    */
+    public void testJaxen24() throws JaxenException
+    {
+        Navigator nav = getNavigator();
+        String url = "xml/jaxen24.xml";
+        log("Document [" + url + "]");
+        Object document = nav.getDocument(url);
+        XPath contextpath = new BaseXPath("/body/div", nav);
+        log("Initial Context :: " + contextpath);
+        List list = contextpath.selectNodes(document);
+        Iterator iter = list.iterator();
+        while (iter.hasNext())
+        {
+            Object context = iter.next();
+            assertCountXPath(1, context, "preceding::*[1]");
+            assertValueOfXPath("span", context, "local-name(preceding::*[1])");
+        }
+    }
+
+    /* jaxen-58
+    */
+    public void testJaxen58() throws JaxenException
+    {
+        Navigator nav = getNavigator();
+        String url = "xml/jaxen24.xml";
+        log("Document [" + url + "]");
+        Object document = nav.getDocument(url);
+        XPath contextpath = new BaseXPath("/", nav);
+        log("Initial Context :: " + contextpath);
+        List list = contextpath.selectNodes(document);
+        Iterator iter = list.iterator();
+        while (iter.hasNext())
+        {
+            Object context = iter.next();
+            assertCountXPath(0, context, "//preceding::x");
+            assertCountXPath(0, context, "//following::x");
+            assertCountXPath(0, context, "/descendant::*/preceding::x");
+            assertCountXPath(0, context, "/descendant::node()/preceding::x");
+        }
+    }
+
+    /* test for jaxen-3
+    */
+    public void testJaxen3() throws JaxenException
+    {
+        Navigator nav = getNavigator();
+        String url = "xml/simple.xml";
+        log("Document [" + url + "]");
+        Object document = nav.getDocument(url);
+        XPath contextpath = new BaseXPath("/", nav);
+        log("Initial Context :: " + contextpath);
+        List list = contextpath.selectNodes(document);
+        Iterator iter = list.iterator();
+        while (iter.hasNext())
+        {
+            Object context = iter.next();
+            assertValueOfXPath("abd", context, "string()");
+        }
+    }
+
+    public void testStringFunction1() throws JaxenException
+    {
+        Navigator nav = getNavigator();
+        String url = "xml/simple.xml";
+        log("Document [" + url + "]");
+        Object document = nav.getDocument(url);
+        XPath contextpath = new BaseXPath("/root", nav);
+        log("Initial Context :: " + contextpath);
+        List list = contextpath.selectNodes(document);
+        Iterator iter = list.iterator();
+        while (iter.hasNext())
+        {
+            Object context = iter.next();
+            assertValueOfXPath("abd", context, "string()");
+        }
+    }
+
+    public void testStringFunction2() throws JaxenException
+    {
+        Navigator nav = getNavigator();
+        String url = "xml/simple.xml";
+        log("Document [" + url + "]");
+        Object document = nav.getDocument(url);
+        XPath contextpath = new BaseXPath("/root/a", nav);
+        log("Initial Context :: " + contextpath);
+        List list = contextpath.selectNodes(document);
+        Iterator iter = list.iterator();
+        while (iter.hasNext())
+        {
+            Object context = iter.next();
+            assertValueOfXPath("a", context, "string()");
+        }
+    }
+
+    public void testStringFunction3() throws JaxenException
+    {
+        Navigator nav = getNavigator();
+        String url = "xml/simple.xml";
+        log("Document [" + url + "]");
+        Object document = nav.getDocument(url);
+        XPath contextpath = new BaseXPath("/root/c", nav);
+        log("Initial Context :: " + contextpath);
+        List list = contextpath.selectNodes(document);
+        Iterator iter = list.iterator();
+        while (iter.hasNext())
+        {
+            Object context = iter.next();
+            assertValueOfXPath("d", context, "string()");
+        }
+    }
+
+    /* test for jaxen-3
+    */
+    public void testJaxen3dupe() throws JaxenException
+    {
+        Navigator nav = getNavigator();
+        String url = "xml/jaxen3.xml";
+        log("Document [" + url + "]");
+        Object document = nav.getDocument(url);
+        XPath contextpath = new BaseXPath("/", nav);
+        log("Initial Context :: " + contextpath);
+        List list = contextpath.selectNodes(document);
+        Iterator iter = list.iterator();
+        while (iter.hasNext())
+        {
+            Object context = iter.next();
+            assertCountXPath(1, context, "/Configuration/hostname/attrlist/hostname[. = 'CE-A'] ");
+        }
+    }
+
+    /* parser test cases all of which should fail
+    */
+    public void testForParserErrors() throws JaxenException
+    {
+        Navigator nav = getNavigator();
+        String url = "xml/numbers.xml";
+        log("Document [" + url + "]");
+        Object document = nav.getDocument(url);
+        XPath contextpath = new BaseXPath("/", nav);
+        log("Initial Context :: " + contextpath);
+        List list = contextpath.selectNodes(document);
+        Iterator iter = list.iterator();
+        while (iter.hasNext())
+        {
+            Object context = iter.next();
+            /* repeated xpaths, jaxen-35
+            */
+            assertInvalidXPath(context, "/numbers numbers");
+            /* invalid xpath, jaxen-34
+            */
+            assertInvalidXPath(context, "/a/b[c > d]efg");
+            /* invalid xpath, jaxen-27
+            */
+            assertInvalidXPath(context, "/inv/child::");
+            /* invalid xpath, jaxen-26
+            */
+            assertInvalidXPath(context, "/invoice/@test[abcd");
+            assertInvalidXPath(context, "/invoice/@test[abcd > x");
+            /* unterminated string
+            */
+            assertInvalidXPath(context, "string-length('a");
+            /* various edge cases where code threw no exception
+            */
+            assertInvalidXPath(context, "/descendant::()");
+            assertInvalidXPath(context, "(1 + 1");
+            // no ! operator
+            assertInvalidXPath(context, "!false()");
+        }
+    }
+
+    /* test cases for the use of underscores in names
+    */
+    public void testUnderscoresInNames() throws JaxenException
+    {
+        Navigator nav = getNavigator();
+        String url = "xml/underscore.xml";
+        log("Document [" + url + "]");
+        Object document = nav.getDocument(url);
+        XPath contextpath = new BaseXPath("/", nav);
+        log("Initial Context :: " + contextpath);
+        List list = contextpath.selectNodes(document);
+        Iterator iter = list.iterator();
+        while (iter.hasNext())
+        {
+            Object context = iter.next();
+            assertCountXPath(1, context, "/root/@a");
+            assertCountXPath(1, context, "/root/@_a");
+            assertCountXPath(1, context, "/root/b");
+            assertCountXPath(1, context, "/root/_b");
+            assertValueOfXPath("1", context, "/root/@a");
+            assertValueOfXPath("2", context, "/root/@_a");
+            assertValueOfXPath("1", context, "/root/b");
+            assertValueOfXPath("2", context, "/root/_b");
+        }
+    }
+
+    /* test cases for the use of = with node-sets
+    */
+    public void testNodesetEqualsString() throws JaxenException
+    {
+        Navigator nav = getNavigator();
+        String url = "xml/web.xml";
+        log("Document [" + url + "]");
+        Object document = nav.getDocument(url);
+        XPath contextpath = new BaseXPath("/", nav);
+        log("Initial Context :: " + contextpath);
+        List list = contextpath.selectNodes(document);
+        Iterator iter = list.iterator();
+        while (iter.hasNext())
+        {
+            Object context = iter.next();
+            assertValueOfXPath("true", context, "/web-app/servlet/servlet-name = 'file'");
+            assertValueOfXPath("true", context, "/web-app/servlet/servlet-name = 'snoop'");
+        }
+    }
+
+    public void testNodesetEqualsNumber() throws JaxenException
+    {
+        Navigator nav = getNavigator();
+        String url = "xml/numbers.xml";
+        log("Document [" + url + "]");
+        Object document = nav.getDocument(url);
+        XPath contextpath = new BaseXPath("/", nav);
+        log("Initial Context :: " + contextpath);
+        List list = contextpath.selectNodes(document);
+        Iterator iter = list.iterator();
+        while (iter.hasNext())
+        {
+            Object context = iter.next();
+            assertValueOfXPath("true", context, "/numbers/set/nr = '-3'");
+            assertValueOfXPath("true", context, "/numbers/set/nr = -3");
+            assertValueOfXPath("true", context, "/numbers/set/nr = 24");
+            assertValueOfXPath("true", context, "/numbers/set/nr/@value = '9999'");
+            assertValueOfXPath("true", context, "/numbers/set/nr/@value = 9999.0");
+            assertValueOfXPath("true", context, "/numbers/set/nr/@value = 66");
+        }
+    }
+
+    /* test basic math...
+    */
+    public void testIntegerArithmetic() throws JaxenException
+    {
+        Navigator nav = getNavigator();
+        String url = "xml/numbers.xml";
+        log("Document [" + url + "]");
+        Object document = nav.getDocument(url);
+        XPath contextpath = new BaseXPath("/", nav);
+        log("Initial Context :: " + contextpath);
+        List list = contextpath.selectNodes(document);
+        Iterator iter = list.iterator();
+        while (iter.hasNext())
+        {
+            Object context = iter.next();
+            assertValueOfXPath("true", context, "(8 * 2 + 1) = 17");
+            assertValueOfXPath("true", context, "(1 + 8 * 2) = 17");
+            assertValueOfXPath("true", context, "(7 - 3 + 1) = 5");
+            assertValueOfXPath("true", context, "(8 - 4 + 5 - 6) = 3");
+            /* left-assoc tests, comments show WRONG evaluation
+            */
+            /* 3 - 2 - 1 != 2
+            */
+            assertValueOfXPath("0", context, "3 - 2 - 1");
+            /* 8 div 4 div 2 != 4
+            */
+            assertValueOfXPath("1", context, "8 div 4 div 2");
+            /* 3 mod 5 mod 7 != 1
+            */
+            assertValueOfXPath("3", context, "3 mod 7 mod 5");
+            /* 1=(2=2) is true
+            */
+            assertValueOfXPath("false", context, "1 = 2 = 2");
+            /*  2!=(3!=1) => 2!=1 => true, (2!=3)!=1 => 1!=1 => false
+            */
+            assertValueOfXPath("false", context, "2 != 3 != 1");
+            /* 3 > (2 > 1) is true
+            */
+            assertValueOfXPath("false", context, "3 > 2 > 1");
+            /* 3 >= (2 >= 2) is true
+            */
+            assertValueOfXPath("false", context, "3 >= 2 >= 2");
+            /* 1 < (2 < 3) is false
+            */
+            assertValueOfXPath("true", context, "1 < 2 < 3");
+            /* 0 <= (2 <= 3) is true
+            */
+            assertValueOfXPath("true", context, "2 <= 2 <= 3");
+        }
+    }
+    
+    public void testFloatingPointArithmetic() throws JaxenException
+    {
+        Navigator nav = getNavigator();
+        String url = "xml/numbers.xml";
+        log("Document [" + url + "]");
+        Object document = nav.getDocument(url);
+        XPath contextpath = new BaseXPath("/", nav);
+        log("Initial Context :: " + contextpath);
+        List list = contextpath.selectNodes(document);
+        Iterator iter = list.iterator();
+        while (iter.hasNext())
+        {
+            Object context = iter.next();
+            assertValueOfXPath("true", context, "(8.5 * 2.0 + 1) = 18");
+            assertValueOfXPath("true", context, "(1.00 + 8.5 * 2) = 18.0");
+            assertValueOfXPath("true", context, "(7.1 - 7.1 + 1.5) = 1.5");
+            assertValueOfXPath("true", context, "(8.000 - 4.0 + 5 - 6.00) = 3");
+            assertValueOfXPath("0", context, "3.5 - 2.5 - 1.0");
+            assertValueOfXPath("1", context, "8.0 div 4.0 div 2.0");
+            assertValueOfXPath("3", context, "3.0 mod 7.0 mod 5.0");
+            assertValueOfXPath("false", context, "1.5 = 2.3 = 2.3");
+            assertValueOfXPath("false", context, "2.1 != 3.2 != 1.9");
+            assertValueOfXPath("false", context, "3.8 > 2.7 > 1.6");
+            assertValueOfXPath("false", context, "3.4 >= 2.5 >= 2.5");
+            assertValueOfXPath("true", context, "1.4 < 2.3 < 3.2");
+            assertValueOfXPath("true", context, "2.5 <= 2.5 <= 3.5");
+        }
+    }
+
+    /* test cases for preceding axis with different node types
+    */
+    public void testPrecedingSiblingAxis() throws JaxenException
+    {
+        Navigator nav = getNavigator();
+        String url = "xml/pi2.xml";
+        log("Document [" + url + "]");
+        Object document = nav.getDocument(url);
+        XPath contextpath = new BaseXPath("/a/c", nav);
+        log("Initial Context :: " + contextpath);
+        List list = contextpath.selectNodes(document);
+        Iterator iter = list.iterator();
+        while (iter.hasNext())
+        {
+            Object context = iter.next();
+            assertCountXPath(1, context, "//processing-instruction()");
+            assertCountXPath(1, context, "preceding-sibling::*");
+            assertCountXPath(5, context, "preceding-sibling::node()");
+            assertCountXPath(1, context, "preceding-sibling::*[1]");
+            assertCountXPath(1, context, "preceding-sibling::processing-instruction()");
+            assertValueOfXPath("order-by=\"x\"", context, "preceding-sibling::processing-instruction()");
+            assertValueOfXPath("foo", context, "preceding-sibling::*[1]");
+            assertValueOfXPath("order-by=\"x\"", context, "preceding-sibling::node()[2]");
+        }
+    }
+
+    public void testVariableLookup() throws JaxenException
+    {
+        Navigator nav = getNavigator();
+        String url = "xml/id.xml";
+        log("Document [" + url + "]");
+        Object document = nav.getDocument(url);
+        XPath contextpath = new BaseXPath("/", nav);
+        log("Initial Context :: " + contextpath);
+        List list = contextpath.selectNodes(document);
+        SimpleVariableContext varContext = new SimpleVariableContext();
+        varContext.setVariableValue(null, "foobar", "foobar");
+        varContext.setVariableValue(null, "foo", "foo");
+        getContextSupport().setVariableContext(varContext);
+        Iterator iter = list.iterator();
+        while (iter.hasNext())
+        {
+            Object context = iter.next();
+            assertValueOfXPath("foobar", context, "$foobar");
+            assertCountXPath(1, context, "/foo[@id=$foobar]");
+            assertCountXPath(0, context, "/foo[@id='$foobar']");
+            assertCountXPath(1, context, "/foo[concat($foo, 'bar')=@id]");
+            assertCountXPath(0, context, "CD_Library/artist[@name=$artist]");
+        }
+    }
+
+    public void testAttributeParent() throws JaxenException
+    {
+        Navigator nav = getNavigator();
+        String url = "xml/id.xml";
+        log("Document [" + url + "]");
+        Object document = nav.getDocument(url);
+        XPath contextpath = new BaseXPath("/", nav);
+        log("Initial Context :: " + contextpath);
+        List list = contextpath.selectNodes(document);
+        Iterator iter = list.iterator();
+        while (iter.hasNext())
+        {
+            Object context = iter.next();
+            /* attributes have a parent: their element
+            */
+            assertCountXPath(1, context, "/foo/@id/parent::foo");
+        }
+    }
+
+    /* attributes can also be used as context nodes
+    */
+    public void testAttributeAsContext() throws JaxenException
+    {
+        Navigator nav = getNavigator();
+        String url = "xml/id.xml";
+        log("Document [" + url + "]");
+        Object document = nav.getDocument(url);
+        XPath contextpath = new BaseXPath("/foo/@id", nav);
+        log("Initial Context :: " + contextpath);
+        List list = contextpath.selectNodes(document);
+        Iterator iter = list.iterator();
+        while (iter.hasNext())
+        {
+            Object context = iter.next();
+            assertCountXPath(1, context, "parent::foo");
+        }
+    }
+
+    public void testid53992() throws JaxenException
+    {
+        Navigator nav = getNavigator();
+        String url = "xml/pi.xml";
+        log("Document [" + url + "]");
+        Object document = nav.getDocument(url);
+        XPath contextpath = new BaseXPath("/", nav);
+        log("Initial Context :: " + contextpath);
+        List list = contextpath.selectNodes(document);
+        Iterator iter = list.iterator();
+        while (iter.hasNext())
+        {
+            Object context = iter.next();
+            assertCountXPath(3, context, "//processing-instruction()");
+            assertCountXPath(2, context, "//processing-instruction('cheese')");
+                Object result = assertCountXPath2(1, context, "//processing-instruction('toast')");
+                assertValueOfXPath("is tasty", result, "string()");
+            }
+            }
+
+    /* test evaluate() extension function
+    */
+    public void testid54032() throws JaxenException
+    {
+        Navigator nav = getNavigator();
+        String url = "xml/evaluate.xml";
+        log("Document [" + url + "]");
+        Object document = nav.getDocument(url);
+        XPath contextpath = new BaseXPath("/", nav);
+        log("Initial Context :: " + contextpath);
+        List list = contextpath.selectNodes(document);
+        Iterator iter = list.iterator();
+        while (iter.hasNext())
+        {
+            Object context = iter.next();
+            assertCountXPath(3, context, "evaluate('//jumps/*')");
+            assertCountXPath(1, context, "evaluate('//jumps/object/dog')");
+            assertCountXPath(0, context, "evaluate('//jumps/object')/evaluate");
+            assertCountXPath(1, context, "evaluate('//jumps/object')/dog");
+            assertCountXPath(1, context, "evaluate('//jumps/*')/dog");
+            assertCountXPath(1, context, "//metatest[ evaluate(@select) = . ]");
+        }
+    }
+
+    public void testid54082() throws JaxenException
+    {
+        Navigator nav = getNavigator();
+        String url = "xml/numbers.xml";
+        log("Document [" + url + "]");
+        Object document = nav.getDocument(url);
+        XPath contextpath = new BaseXPath("/numbers/set[1]", nav);
+        log("Initial Context :: " + contextpath);
+        List list = contextpath.selectNodes(document);
+        Iterator iter = list.iterator();
+        while (iter.hasNext())
+        {
+            Object context = iter.next();
+            assertCountXPath(1, context, "*[-3 = .]");
+            assertValueOfXPath("true", context, "54 < *");
+            assertValueOfXPath("true", context, "55 <= *");
+            assertValueOfXPath("false", context, "69 < *");
+            assertValueOfXPath("true", context, "-2 > *");
+            assertValueOfXPath("true", context, "-3 >= *");
+            assertValueOfXPath("false", context, "-4 >= *");
+        }
+    }
+
+    /* TODO
+    This context should work, but needs a fixed version of saxpath to parse the right-hand side
+    of the greater-than expression.
+    <context select="/numbers/set[2]">
+      <valueOf select="1 > nr/@value">false</valueOf>
+      <valueOf select="55 > nr/@value">false</valueOf>
+      <valueOf select="55 >= nr/@value">true</valueOf>
+      <valueOf select="1000000 > nr/@value">true</valueOf>
+    </context>
+    
+    */
+    /* test sibling axes 
+    */
+    public void testid54145() throws JaxenException
+    {
+        Navigator nav = getNavigator();
+        String url = "xml/axis.xml";
+        log("Document [" + url + "]");
+        Object document = nav.getDocument(url);
+        XPath contextpath = new BaseXPath("/root", nav);
+        log("Initial Context :: " + contextpath);
+        List list = contextpath.selectNodes(document);
+        Iterator iter = list.iterator();
+        while (iter.hasNext())
+        {
+            Object context = iter.next();
+            assertCountXPath(0, context, "preceding-sibling::*");
+        }
+    }
+
+    public void testid54156() throws JaxenException
+    {
+        Navigator nav = getNavigator();
+        String url = "xml/axis.xml";
+        log("Document [" + url + "]");
+        Object document = nav.getDocument(url);
+        XPath contextpath = new BaseXPath("/root/a/a.3", nav);
+        log("Initial Context :: " + contextpath);
+        List list = contextpath.selectNodes(document);
+        Iterator iter = list.iterator();
+        while (iter.hasNext())
+        {
+            Object context = iter.next();
+            assertCountXPath(2, context, "preceding::*");
+        }
+    }
+
+    public void testid54168() throws JaxenException
+    {
+        Navigator nav = getNavigator();
+        String url = "xml/axis.xml";
+        log("Document [" + url + "]");
+        Object document = nav.getDocument(url);
+        XPath contextpath = new BaseXPath("/root/a/a.3", nav);
+        log("Initial Context :: " + contextpath);
+        List list = contextpath.selectNodes(document);
+        Iterator iter = list.iterator();
+        while (iter.hasNext())
+        {
+            Object context = iter.next();
+            assertCountXPath(2, context, "preceding-sibling::*");
+        }
+    }
+
+    public void testid54180() throws JaxenException
+    {
+        Navigator nav = getNavigator();
+        String url = "xml/axis.xml";
+        log("Document [" + url + "]");
+        Object document = nav.getDocument(url);
+        XPath contextpath = new BaseXPath("/", nav);
+        log("Initial Context :: " + contextpath);
+        List list = contextpath.selectNodes(document);
+        Iterator iter = list.iterator();
+        while (iter.hasNext())
+        {
+            Object context = iter.next();
+            assertValueOfXPath("a.2", context, "name(/root/a/a.3/preceding-sibling::*[1])");
+            assertValueOfXPath("a.1", context, "name(/root/a/a.3/preceding-sibling::*[2])");
+        }
+    }
+
+    public void testid54197() throws JaxenException
+    {
+        Navigator nav = getNavigator();
+        String url = "xml/axis.xml";
+        log("Document [" + url + "]");
+        Object document = nav.getDocument(url);
+        XPath contextpath = new BaseXPath("/", nav);
+        log("Initial Context :: " + contextpath);
+        List list = contextpath.selectNodes(document);
+        Iterator iter = list.iterator();
+        while (iter.hasNext())
+        {
+            Object context = iter.next();
+            assertValueOfXPath("a.4", context, "name(/root/a/a.3/following-sibling::*[1])");
+            assertValueOfXPath("a.5", context, "name(/root/a/a.3/following-sibling::*[2])");
+        }
+    }
+
+    public void testid54219() throws JaxenException
+    {
+        Navigator nav = getNavigator();
+        String url = "xml/web.xml";
+        log("Document [" + url + "]");
+        Object document = nav.getDocument(url);
+        XPath contextpath = new BaseXPath("/", nav);
+        log("Initial Context :: " + contextpath);
+        List list = contextpath.selectNodes(document);
+        Iterator iter = list.iterator();
+        while (iter.hasNext())
+        {
+            Object context = iter.next();
+            assertValueOfXPath("snoop", context, "/web-app/servlet[1]/servlet-name");
+            assertValueOfXPath("snoop", context, "/web-app/servlet[1]/servlet-name/text()");
+            assertValueOfXPath("file", context, "/web-app/servlet[2]/servlet-name");
+            assertValueOfXPath("file", context, "/web-app/servlet[2]/servlet-name/text()");
+        }
+    }
+
+    public void testid54249() throws JaxenException
+    {
+        Navigator nav = getNavigator();
+        String url = "xml/web.xml";
+        log("Document [" + url + "]");
+        Object document = nav.getDocument(url);
+        XPath contextpath = new BaseXPath("/web-app/servlet[1]", nav);
+        log("Initial Context :: " + contextpath);
+        List list = contextpath.selectNodes(document);
+        Iterator iter = list.iterator();
+        while (iter.hasNext())
+        {
+            Object context = iter.next();
+            assertValueOfXPath("snoop", context, "servlet-name");
+            assertValueOfXPath("snoop", context, "servlet-name/text()");
+        }
+    }
+
+    public void testid54266() throws JaxenException
+    {
+        Navigator nav = getNavigator();
+        String url = "xml/web.xml";
+        log("Document [" + url + "]");
+        Object document = nav.getDocument(url);
+        XPath contextpath = new BaseXPath("/web-app/servlet[2]/servlet-name", nav);
+        log("Initial Context :: " + contextpath);
+        List list = contextpath.selectNodes(document);
+        Iterator iter = list.iterator();
+        while (iter.hasNext())
+        {
+            Object context = iter.next();
+            assertCountXPath(3, context, "preceding::*");
+        }
+    }
+
+    public void testid54278() throws JaxenException
+    {
+        Navigator nav = getNavigator();
+        String url = "xml/web.xml";
+        log("Document [" + url + "]");
+        Object document = nav.getDocument(url);
+        XPath contextpath = new BaseXPath("/web-app/servlet[2]/servlet-name", nav);
+        log("Initial Context :: " + contextpath);
+        List list = contextpath.selectNodes(document);
+        Iterator iter = list.iterator();
+        while (iter.hasNext())
+        {
+            Object context = iter.next();
+            assertCountXPath(13, context, "following::*");
+        }
+    }
+
+    /* test name
+    */
+    public void testid54298() throws JaxenException
+    {
+        Navigator nav = getNavigator();
+        String url = "xml/web.xml";
+        log("Document [" + url + "]");
+        Object document = nav.getDocument(url);
+        XPath contextpath = new BaseXPath("/", nav);
+        log("Initial Context :: " + contextpath);
+        List list = contextpath.selectNodes(document);
+        Iterator iter = list.iterator();
+        while (iter.hasNext())
+        {
+            Object context = iter.next();
+                Object result = assertCountXPath2(1, context, "*");
+                assertValueOfXPath("web-app", result, "name()");
+            /* NOTE that the child::node() tests only work if the
+              XML document does not comments or PIs
+
+            */
+            result = assertCountXPath2(1, context, "./*");
+                assertValueOfXPath("web-app", result, "name()");
+            result = assertCountXPath2(1, context, "child::*");
+                assertValueOfXPath("web-app", result, "name()");
+            result = assertCountXPath2(1, context, "/*");
+                assertValueOfXPath("web-app", result, "name()");
+            result = assertCountXPath2(1, context, "/child::node()");
+                assertValueOfXPath("web-app", result, "name(.)");
+            result = assertCountXPath2(1, context, "child::node()");
+                assertValueOfXPath("web-app", result, "name(.)");
+            /* empty names
+            */
+            assertValueOfXPath("", context, "name()");
+            assertValueOfXPath("", context, "name(.)");
+            assertValueOfXPath("", context, "name(parent::*)");
+            assertValueOfXPath("", context, "name(/)");
+            assertValueOfXPath("", context, "name(/.)");
+            assertValueOfXPath("", context, "name(/self::node())");
+            /* name of root elemet
+            */
+            assertValueOfXPath("web-app", context, "name(node())");
+            assertValueOfXPath("web-app", context, "name(/node())");
+            assertValueOfXPath("web-app", context, "name(/*)");
+            assertValueOfXPath("web-app", context, "name(/child::*)");
+            assertValueOfXPath("web-app", context, "name(/child::node())");
+            assertValueOfXPath("web-app", context, "name(/child::node())");
+            assertValueOfXPath("web-app", context, "name(child::node())");
+            assertValueOfXPath("web-app", context, "name(./*)");
+            assertValueOfXPath("web-app", context, "name(*)");
+        }
+    }
+
+    public void testid54467() throws JaxenException
+    {
+        Navigator nav = getNavigator();
+        String url = "xml/web.xml";
+        log("Document [" + url + "]");
+        Object document = nav.getDocument(url);
+        XPath contextpath = new BaseXPath("/*", nav);
+        log("Initial Context :: " + contextpath);
+        List list = contextpath.selectNodes(document);
+        Iterator iter = list.iterator();
+        while (iter.hasNext())
+        {
+            Object context = iter.next();
+            /* empty names
+            */
+            assertValueOfXPath("", context, "name(..)");
+            assertValueOfXPath("", context, "name(parent::node())");
+            assertValueOfXPath("", context, "name(parent::*)");
+            /* name of root elemet
+            */
+            assertValueOfXPath("web-app", context, "name()");
+            assertValueOfXPath("web-app", context, "name(.)");
+            assertValueOfXPath("web-app", context, "name(../*)");
+            assertValueOfXPath("web-app", context, "name(../child::node())");
+        }
+    }
+
+    /* test predicates
+    */
+    public void testid54522() throws JaxenException
+    {
+        Navigator nav = getNavigator();
+        String url = "xml/nitf.xml";
+        log("Document [" + url + "]");
+        Object document = nav.getDocument(url);
+        XPath contextpath = new BaseXPath("/nitf/head/docdata", nav);
+        log("Initial Context :: " + contextpath);
+        List list = contextpath.selectNodes(document);
+        Iterator iter = list.iterator();
+        while (iter.hasNext())
+        {
+            Object context = iter.next();
+            assertCountXPath(1, context, "doc-id[@regsrc='AP' and @id-string='D76UIMO80']");
+        }
+    }
+
+    public void testid54534() throws JaxenException
+    {
+        Navigator nav = getNavigator();
+        String url = "xml/nitf.xml";
+        log("Document [" + url + "]");
+        Object document = nav.getDocument(url);
+        XPath contextpath = new BaseXPath("/nitf/head", nav);
+        log("Initial Context :: " + contextpath);
+        List list = contextpath.selectNodes(document);
+        Iterator iter = list.iterator();
+        while (iter.hasNext())
+        {
+            Object context = iter.next();
+            assertCountXPath(1, context, "meta[@name='ap-cycle']");
+            assertCountXPath(1, context, "meta[@content='AP']");
+            assertCountXPath(8, context, "meta[@name and @content]");
+            assertCountXPath(1, context, "meta[@name='ap-cycle' and @content='AP']");
+            assertCountXPath(7, context, "meta[@name != 'ap-cycle']");
+        }
+    }
+
+    public void testid54570() throws JaxenException
+    {
+        Navigator nav = getNavigator();
+        String url = "xml/nitf.xml";
+        log("Document [" + url + "]");
+        Object document = nav.getDocument(url);
+        XPath contextpath = new BaseXPath("/", nav);
+        log("Initial Context :: " + contextpath);
+        List list = contextpath.selectNodes(document);
+        Iterator iter = list.iterator();
+        while (iter.hasNext())
+        {
+            Object context = iter.next();
+            assertCountXPath(1, context, "/nitf/head/meta[@name='ap-cycle']");
+            assertCountXPath(1, context, "/nitf/head/meta[@content='AP']");
+            assertCountXPath(8, context, "/nitf/head/meta[@name and @content]");
+            assertCountXPath(1, context, "/nitf/head/meta[@name='ap-cycle' and @content='AP']");
+            assertCountXPath(7, context, "/nitf/head/meta[@name != 'ap-cycle']");
+        }
+    }
+
+    public void testid54614() throws JaxenException
+    {
+        Navigator nav = getNavigator();
+        String url = "xml/moreover.xml";
+        log("Document [" + url + "]");
+        Object document = nav.getDocument(url);
+        XPath contextpath = new BaseXPath("/", nav);
+        log("Initial Context :: " + contextpath);
+        List list = contextpath.selectNodes(document);
+        Iterator iter = list.iterator();
+        while (iter.hasNext())
+        {
+            Object context = iter.next();
+            assertCountXPath(1, context, "/child::node()");
+            assertCountXPath(1, context, "/*");
+            assertCountXPath(20, context, "/*/article");
+            assertCountXPath(221, context, "//*");
+            assertCountXPath(20, context, "//*[local-name()='article']");
+            assertCountXPath(20, context, "//article");
+            assertCountXPath(20, context, "/*/*[@code]");
+            assertCountXPath(1, context, "/moreovernews/article[@code='13563275']");
+                DOMXPath xpath = new DOMXPath("/moreovernews/article[@code='13563275']");
+                List results = xpath.selectNodes(getContext(context));
+                Object result = results.get(0);
+                assertValueOfXPath("http://c.moreover.com/click/here.pl?x13563273", result, "url");
+            xpath = new DOMXPath("/*/article[@code='13563275']");
+            results = xpath.selectNodes(getContext(context));
+            result = results.get(0);
+                assertValueOfXPath("http://c.moreover.com/click/here.pl?x13563273", result, "url");
+            xpath = new DOMXPath("//article[@code='13563275']");
+            results = xpath.selectNodes(getContext(context));
+            result = results.get(0);
+                assertValueOfXPath("http://c.moreover.com/click/here.pl?x13563273", result, "url");
+            xpath = new DOMXPath("//*[@code='13563275']");
+            results = xpath.selectNodes(getContext(context));
+            result = results.get(0);
+                assertValueOfXPath("http://c.moreover.com/click/here.pl?x13563273", result, "url");
+            xpath = new DOMXPath("/child::node()/child::node()[@code='13563275']");
+            results = xpath.selectNodes(getContext(context));
+            result = results.get(0);
+                assertValueOfXPath("http://c.moreover.com/click/here.pl?x13563273", result, "url");
+            xpath = new DOMXPath("/*/*[@code='13563275']");
+            results = xpath.selectNodes(getContext(context));
+            result = results.get(0);
+                assertValueOfXPath("http://c.moreover.com/click/here.pl?x13563273", result, "url");
+            }
+            }
+
+    /* test other node types
+    */
+    public void testNodeTypes() throws JaxenException
+    {
+        Navigator nav = getNavigator();
+        String url = "xml/contents.xml";
+        log("Document [" + url + "]");
+        Object document = nav.getDocument(url);
+        XPath contextpath = new BaseXPath("/", nav);
+        log("Initial Context :: " + contextpath);
+        List list = contextpath.selectNodes(document);
+        Iterator iter = list.iterator();
+        while (iter.hasNext())
+        {
+            Object context = iter.next();
+            assertCountXPath(3, context, "processing-instruction()");
+            assertCountXPath(3, context, "/processing-instruction()");
+            assertCountXPath(1, context, "/comment()");
+            assertCountXPath(1, context, "comment()");
+            assertCountXPath(2, context, "/child::node()/comment()");
+            assertCountXPath(2, context, "/*/comment()");
+            assertCountXPath(3, context, "//comment()");
+        }
+    }
+
+    /* test positioning
+    */
+    public void testPositioning() throws JaxenException
+    {
+        Navigator nav = getNavigator();
+        String url = "xml/fibo.xml";
+        log("Document [" + url + "]");
+        Object document = nav.getDocument(url);
+        XPath contextpath = new BaseXPath("/", nav);
+        log("Initial Context :: " + contextpath);
+        List list = contextpath.selectNodes(document);
+        Iterator iter = list.iterator();
+        while (iter.hasNext())
+        {
+            Object context = iter.next();
+            assertCountXPath(9, context, "/*/fibonacci[position() < 10]");
+            assertValueOfXPath("196417", context, "sum(//fibonacci)");
+            assertValueOfXPath("325", context, "sum(//fibonacci/@index)");
+            assertValueOfXPath("1", context, "/*/fibonacci[2]");
+            assertValueOfXPath("75025", context, "/*/fibonacci[ count(/*/fibonacci) ]");
+            assertValueOfXPath("46368", context, "/*/fibonacci[ count(/*/fibonacci) - 1 ]");
+        }
+    }
+
+    /* test number functions
+    */
+    /* test Axes 
+    */
+    public void testid54853() throws JaxenException
+    {
+        Navigator nav = getNavigator();
+        String url = "xml/web.xml";
+        log("Document [" + url + "]");
+        Object document = nav.getDocument(url);
+        XPath contextpath = new BaseXPath("/", nav);
+        log("Initial Context :: " + contextpath);
+        List list = contextpath.selectNodes(document);
+        Iterator iter = list.iterator();
+        while (iter.hasNext())
+        {
+            Object context = iter.next();
+            assertCountXPath(19, context, "descendant-or-self::*");
+            assertCountXPath(19, context, "descendant::*");
+            assertCountXPath(19, context, "/descendant::*");
+            assertCountXPath(19, context, "/descendant-or-self::*");
+            assertCountXPath(2, context, "/descendant::servlet");
+            assertCountXPath(2, context, "/descendant-or-self::servlet");
+            assertCountXPath(2, context, "descendant-or-self::servlet");
+            assertCountXPath(2, context, "descendant::servlet");
+            assertCountXPath(2, context, "/*/servlet");
+            assertValueOfXPath("2", context, "count(/*/servlet)");
+            assertCountXPath(2, context, "//servlet");
+            assertValueOfXPath("2", context, "count(//servlet)");
+        }
+    }
+
+    public void testid54932() throws JaxenException
+    {
+        Navigator nav = getNavigator();
+        String url = "xml/web.xml";
+        log("Document [" + url + "]");
+        Object document = nav.getDocument(url);
+        XPath contextpath = new BaseXPath("/web-app", nav);
+        log("Initial Context :: " + contextpath);
+        List list = contextpath.selectNodes(document);
+        Iterator iter = list.iterator();
+        while (iter.hasNext())
+        {
+            Object context = iter.next();
+            assertCountXPath(2, context, "/descendant::servlet");
+            assertCountXPath(2, context, "/descendant-or-self::servlet");
+            assertCountXPath(2, context, "descendant-or-self::servlet");
+            assertCountXPath(2, context, "descendant::servlet");
+        }
+    }
+
+    public void testCountFunction() throws JaxenException
+    {
+        Navigator nav = getNavigator();
+        String url = "xml/much_ado.xml";
+        log("Document [" + url + "]");
+        Object document = nav.getDocument(url);
+        XPath contextpath = new BaseXPath("/", nav);
+        log("Initial Context :: " + contextpath);
+        List list = contextpath.selectNodes(document);
+        Iterator iter = list.iterator();
+        while (iter.hasNext())
+        {
+            Object context = iter.next();
+            assertCountXPath(5, context, "/descendant::ACT");
+            assertCountXPath(5, context, "descendant::ACT");
+            assertValueOfXPath("Much Ado about Nothing", context, "/PLAY/TITLE");
+            assertValueOfXPath("4", context, "2+2");
+            assertValueOfXPath("21", context, "5 * 4 + 1");
+            assertValueOfXPath("5", context, "count(descendant::ACT)");
+            assertValueOfXPath("35", context, "10 + count(descendant::ACT) * 5");
+            assertValueOfXPath("75", context, "(10 + count(descendant::ACT)) * 5");
+        }
+    }
+
+    public void testCountFunctionMore() throws JaxenException
+    {
+        Navigator nav = getNavigator();
+        String url = "xml/much_ado.xml";
+        log("Document [" + url + "]");
+        Object document = nav.getDocument(url);
+        XPath contextpath = new BaseXPath("/PLAY/ACT[2]/SCENE[1]", nav);
+        log("Initial Context :: " + contextpath);
+        List list = contextpath.selectNodes(document);
+        Iterator iter = list.iterator();
+        while (iter.hasNext())
+        {
+            Object context = iter.next();
+            assertCountXPath(5, context, "/descendant::ACT");
+            assertCountXPath(5, context, "../../descendant::ACT");
+            assertCountXPath(141, context, "/PLAY/ACT[2]/SCENE[1]/descendant::SPEAKER");
+            assertCountXPath(141, context, "descendant::SPEAKER");
+            assertValueOfXPath("646", context, "count(descendant::*)+1");
+            assertValueOfXPath("142", context, "count(descendant::SPEAKER)+1");
+            assertValueOfXPath("2", context, "count(ancestor::*)");
+            assertValueOfXPath("1", context, "count(ancestor::PLAY)");
+            assertValueOfXPath("3", context, "count(ancestor-or-self::*)");
+            assertValueOfXPath("1", context, "count(ancestor-or-self::PLAY)");
+            assertValueOfXPath("6", context, "5+count(ancestor::*)-1");
+        }
+    }
+
+    public void testCorrectPredicateApplication() throws JaxenException
+    {
+        Navigator nav = getNavigator();
+        String url = "xml/much_ado.xml";
+        log("Document [" + url + "]");
+        Object document = nav.getDocument(url);
+        XPath contextpath = new BaseXPath("/", nav);
+        log("Initial Context :: " + contextpath);
+        List list = contextpath.selectNodes(document);
+        Iterator iter = list.iterator();
+        while (iter.hasNext())
+        {
+            Object context = iter.next();
+            /* Test correct predicate application
+            */
+            assertValueOfXPath("5", context, "count(/PLAY/ACT/SCENE[1])");
+        }
+    }
+
+    /* test axis node ordering
+    */
+    public void testAxisNodeOrdering() throws JaxenException
+    {
+        Navigator nav = getNavigator();
+        String url = "xml/web.xml";
+        log("Document [" + url + "]");
+        Object document = nav.getDocument(url);
+        XPath contextpath = new BaseXPath("/", nav);
+        log("Initial Context :: " + contextpath);
+        List list = contextpath.selectNodes(document);
+        Iterator iter = list.iterator();
+        while (iter.hasNext())
+        {
+            Object context = iter.next();
+            /* Reported as Jira issue JAXEN-24
+            */
+            assertCountXPath(1, context, "//servlet-mapping/preceding::*[1][name()='description']");
+            assertCountXPath(1, context, "/web-app/servlet//description/following::*[1][name()='servlet-mapping']");
+            assertCountXPath(1, context, "/web-app/servlet//description/following::*[2][name()='servlet-name']");
+        }
+    }
+
+    /* test document function
+    */
+    public void testDocumentFunction1() throws JaxenException
+    {
+        Navigator nav = getNavigator();
+        String url = "xml/text.xml";
+        log("Document [" + url + "]");
+        Object document = nav.getDocument(url);
+        XPath contextpath = new BaseXPath("/", nav);
+        log("Initial Context :: " + contextpath);
+        List list = contextpath.selectNodes(document);
+        Iterator iter = list.iterator();
+        while (iter.hasNext())
+        {
+            Object context = iter.next();
+                Object result = assertCountXPath2(1, context, "document('xml/web.xml')");
+                assertValueOfXPath("snoop", result, "/web-app/servlet[1]/servlet-name");
+                assertValueOfXPath("snoop", result, "/web-app/servlet[1]/servlet-name/text()");
+            assertValueOfXPath("snoop", context, "document('xml/web.xml')/web-app/servlet[1]/servlet-name");
+        }
+    }
+
+    /* Test to check if the context changes when an extension function is used.
+    First test is an example, second is the actual test.
+    
+    */
+    public void testDocumentFunctionContextExample() throws JaxenException
+    {
+        Navigator nav = getNavigator();
+        String url = "xml/text.xml";
+        log("Document [" + url + "]");
+        Object document = nav.getDocument(url);
+        XPath contextpath = new BaseXPath("/foo/bar/cheese[1]", nav);
+        log("Initial Context :: " + contextpath);
+        List list = contextpath.selectNodes(document);
+        Iterator iter = list.iterator();
+        while (iter.hasNext())
+        {
+            Object context = iter.next();
+            assertValueOfXPath("3foo3", context, "concat(./@id,'foo', at id)");
+            assertValueOfXPath("3snoop3", context, "concat(./@id,document('xml/web.xml')/web-app/servlet[1]/servlet-name,./@id)");
+        }
+    }
+
+    public void testDocumentFunctionActual() throws JaxenException
+    {
+        Navigator nav = getNavigator();
+        String url = "xml/message.xml";
+        log("Document [" + url + "]");
+        Object document = nav.getDocument(url);
+        XPath contextpath = new BaseXPath("/", nav);
+        log("Initial Context :: " + contextpath);
+        List list = contextpath.selectNodes(document);
+        Iterator iter = list.iterator();
+        while (iter.hasNext())
+        {
+            Object context = iter.next();
+            assertValueOfXPath("Pruefgebiete", context, "/message/body/data/items/item[name/text()='parentinfo']/value");
+            assertValueOfXPath("Pruefgebiete", context, "document('xml/message.xml')/message/body/data/items/item[name/text()='parentinfo']/value");
+        }
+    }
+
+    /* test behaviour of AbsoluteLocationPath
+    */
+    public void testAbsoluteLocationPaths() throws JaxenException
+    {
+        Navigator nav = getNavigator();
+        String url = "xml/simple.xml";
+        log("Document [" + url + "]");
+        Object document = nav.getDocument(url);
+        XPath contextpath = new BaseXPath("/root/a", nav);
+        log("Initial Context :: " + contextpath);
+        List list = contextpath.selectNodes(document);
+        Iterator iter = list.iterator();
+        while (iter.hasNext())
+        {
+            Object context = iter.next();
+            assertValueOfXPath("ab", context, "concat( ., /root/b )");
+            assertValueOfXPath("ba", context, "concat( ../b, . )");
+            assertValueOfXPath("ba", context, "concat( /root/b, . )");
+            assertValueOfXPath("db", context, "concat( /root/c/d, ../b )");
+        }
+    }
+
+    /* test the translate() function
+    */
+    public void testTranslateFunction() throws JaxenException
+    {
+        Navigator nav = getNavigator();
+        String url = "xml/simple.xml";
+        log("Document [" + url + "]");
+        Object document = nav.getDocument(url);
+        XPath contextpath = new BaseXPath("/", nav);
+        log("Initial Context :: " + contextpath);
+        List list = contextpath.selectNodes(document);
+        Iterator iter = list.iterator();
+        while (iter.hasNext())
+        {
+            Object context = iter.next();
+            assertValueOfXPath("", context, "translate( '', '', '' )");
+            assertValueOfXPath("abcd", context, "translate( 'abcd', '', '' )");
+            assertValueOfXPath("abcd", context, "translate( 'abcd', 'abcd', 'abcd' )");
+            assertValueOfXPath("abcd", context, "translate( 'abcd', 'dcba', 'dcba' )");
+            assertValueOfXPath("dcba", context, "translate( 'abcd', 'abcd', 'dcba' )");
+            assertValueOfXPath("ab", context, "translate( 'abcd', 'abcd', 'ab' )");
+            assertValueOfXPath("cd", context, "translate( 'abcd', 'cdab', 'cd' )");
+            assertValueOfXPath("xy", context, "translate( 'abcd', 'acbd', 'xy' )");
+            assertValueOfXPath("abcd", context, "translate( 'abcd', 'abcdb', 'abcdb' )");
+            assertValueOfXPath("abcd", context, "translate( 'abcd', 'abcd', 'abcdb' )");
+        }
+    }
+
+    public void testSubstringFunction() throws JaxenException
+    {
+        Navigator nav = getNavigator();
+        String url = "xml/simple.xml";
+        log("Document [" + url + "]");
+        Object document = nav.getDocument(url);
+        XPath contextpath = new BaseXPath("/", nav);
+        log("Initial Context :: " + contextpath);
+        List list = contextpath.selectNodes(document);
+        Iterator iter = list.iterator();
+        while (iter.hasNext())
+        {
+            Object context = iter.next();
+            assertValueOfXPath("234", context, "substring('12345', 1.5, 2.6)");
+            assertValueOfXPath("12", context, "substring('12345', 0, 3)");
+            assertValueOfXPath("", context, "substring('12345', 0 div 0, 3)");
+            assertValueOfXPath("", context, "substring('12345', 1, 0 div 0)");
+            assertValueOfXPath("12345", context, "substring('12345', -42, 1 div 0)");
+            assertValueOfXPath("", context, "substring('12345', -1 div 0, 1 div 0)");
+            assertValueOfXPath("345", context, "substring('12345', 3)");
+            assertValueOfXPath("12345", context, "substring('12345',1,15)");
+        }
+    }
+
+    /* Some tests for the normalize-space() function
+    */
+    public void testNormalizeSpaceFunction() throws JaxenException
+    {
+        Navigator nav = getNavigator();
+        String url = "xml/simple.xml";
+        log("Document [" + url + "]");
+        Object document = nav.getDocument(url);
+        XPath contextpath = new BaseXPath("/", nav);
+        log("Initial Context :: " + contextpath);
+        List list = contextpath.selectNodes(document);
+        Iterator iter = list.iterator();
+        while (iter.hasNext())
+        {
+            Object context = iter.next();
+            assertValueOfXPath("abc", context, "normalize-space('    abc    ')");
+            assertValueOfXPath("a b c", context, "normalize-space(' a  b  c  ')");
+            assertValueOfXPath("a b c", context, "normalize-space(' a \n b \n  c')");
+            /* Next test case addresses issue JAXEN-22
+            */
+            assertValueOfXPath("", context, "normalize-space(' ')");
+            /* Next test case addresses issue JAXEN-29
+            */
+            assertValueOfXPath("", context, "normalize-space('')");
+        }
+    }
+
+    /* test cases for String extension functions
+    */
+    public void testStringExtensionFunctions() throws JaxenException
+    {
+        Navigator nav = getNavigator();
+        String url = "xml/web.xml";
+        log("Document [" + url + "]");
+        Object document = nav.getDocument(url);
+        XPath contextpath = new BaseXPath("/web-app/servlet[1]", nav);
+        log("Initial Context :: " + contextpath);
+        List list = contextpath.selectNodes(document);
+        Iterator iter = list.iterator();
+        while (iter.hasNext())
+        {
+            Object context = iter.next();
+            assertValueOfXPath("SNOOPSERVLET", context, "upper-case( servlet-class )");
+            assertValueOfXPath("snoopservlet", context, "lower-case( servlet-class )");
+            assertValueOfXPath("SNOOPSERVLET", context, "upper-case( servlet-class, 'fr' )");
+            assertValueOfXPath("SNOOPSERVLET", context, "upper-case( servlet-class, 'fr-CA' )");
+            assertValueOfXPath("SNOOPSERVLET", context, "upper-case( servlet-class, 'es-ES-Traditional_WIN' )");
+            assertValueOfXPath("true", context, "ends-with( servlet-class, 'Servlet' )");
+            assertValueOfXPath("false", context, "ends-with( servlet-class, 'S' )");
+        }
+    }
+
+    /* test cases for the lang() function
+    */
+    public void testLangFunction() throws JaxenException
+    {
+        Navigator nav = getNavigator();
+        String url = "xml/lang.xml";
+        log("Document [" + url + "]");
+        Object document = nav.getDocument(url);
+        XPath contextpath = new BaseXPath("/", nav);
+        log("Initial Context :: " + contextpath);
+        List list = contextpath.selectNodes(document);
+        Iterator iter = list.iterator();
+        while (iter.hasNext())
+        {
+            Object context = iter.next();
+            assertCountXPath(0, context, "/e1/e2[lang('hr')]");
+            assertCountXPath(1, context, "/e1/e2/e3[lang('en')]");
+            assertCountXPath(1, context, "/e1/e2/e3[lang('en-US')]");
+            assertCountXPath(0, context, "/e1/e2/e3[lang('en-GB')]");
+            assertCountXPath(2, context, "/e1/e2/e3[lang('hu')]");
+            assertCountXPath(0, context, "/e1/e2/e3[lang('hu-HU')]");
+            assertCountXPath(1, context, "/e1/e2/e3[lang('es')]");
+            assertCountXPath(0, context, "/e1/e2/e3[lang('es-BR')]");
+        }
+    }
+
+    /* test namespace
+    */
+    public void testNamespacesAgain() throws JaxenException
+    {
+        Navigator nav = getNavigator();
+        String url = "xml/namespaces.xml";
+        log("Document [" + url + "]");
+        Object document = nav.getDocument(url);
+        XPath contextpath = new BaseXPath("/", nav);
+        log("Initial Context :: " + contextpath);
+        List list = contextpath.selectNodes(document);
+        SimpleNamespaceContext nsContext = new SimpleNamespaceContext();
+        nsContext.addNamespace("alias", "http://fooNamespace/");
+        nsContext.addNamespace("bar", "http://barNamespace/");
+        nsContext.addNamespace("voo", "http://fooNamespace/");
+        nsContext.addNamespace("foo", "http://fooNamespace/");
+        getContextSupport().setNamespaceContext(nsContext);
+        Iterator iter = list.iterator();
+        while (iter.hasNext())
+        {
+            Object context = iter.next();
+            assertCountXPath(1, context, "/*");
+            assertCountXPath(1, context, "/foo:a");
+            assertCountXPath(1, context, "/foo:a/b");
+            assertCountXPath(1, context, "/voo:a/b/c");
+            assertCountXPath(1, context, "/voo:a/bar:f");
+            assertCountXPath(1, context, "/*[namespace-uri()='http://fooNamespace/' and local-name()='a']");
+            assertCountXPath(1, context, "/*[local-name()='a' and namespace-uri()='http://fooNamespace/']/*[local-name()='x' and namespace-uri()='http://fooNamespace/']");
+            assertCountXPath(1, context, "/*[local-name()='a' and namespace-uri()='http://fooNamespace/']/*[local-name()='x' and namespace-uri()='http://fooNamespace/']/*[local-name()='y' and namespace-uri()='http://fooNamespace/']");
+        }
+    }
+
+    /* the prefix here and in the document have no relation; it's their
+    namespace-uri binding that counts 
+    */
+    public void testPrefixDoesntMatter() throws JaxenException
+    {
+        Navigator nav = getNavigator();
+        String url = "xml/namespaces.xml";
+        log("Document [" + url + "]");
+        Object document = nav.getDocument(url);
+        XPath contextpath = new BaseXPath("/", nav);
+        log("Initial Context :: " + contextpath);
+        List list = contextpath.selectNodes(document);
+        SimpleNamespaceContext nsContext = new SimpleNamespaceContext();
+        nsContext.addNamespace("foo", "http://somethingElse/");
+        getContextSupport().setNamespaceContext(nsContext);
+        Iterator iter = list.iterator();
+        while (iter.hasNext())
+        {
+            Object context = iter.next();
+            assertCountXPath(0, context, "/foo:a/b/c");
+        }
+    }
+
+    /* Jaxen-67, affects Jelly and Maven */
+    public void testCDATASectionsAreIncludedInTextNodes() throws JaxenException
+    {
+        Navigator nav = getNavigator();
+        String url = "xml/cdata.xml";
+        log("Document [" + url + "]");
+        Object document = nav.getDocument(url);
+        XPath contextPath = new BaseXPath("/p/text()", nav);
+        log("Initial Context :: " + contextPath);
+        List list = contextPath.selectNodes(document);
+        // Depending on the object model, there can be anywhere from 
+        // 1 to 3 nodes returned here.
+        StringBuffer buffer = new StringBuffer(10);
+        Iterator iterator = list.iterator();
+        while (iterator.hasNext()) {
+            buffer.append(StringFunction.evaluate(iterator.next(), nav));
+        }
+        assertEquals("awhateverb", buffer.toString());
+    }
+
+    public void testNamespaces() throws JaxenException
+    {
+        Navigator nav = getNavigator();
+        String url = "xml/namespaces.xml";
+        log("Document [" + url + "]");
+        Object document = nav.getDocument(url);
+        XPath contextpath = new BaseXPath("/", nav);
+        log("Initial Context :: " + contextpath);
+        List list = contextpath.selectNodes(document);
+        SimpleNamespaceContext nsContext = new SimpleNamespaceContext();
+        nsContext.addNamespace("alias", "http://fooNamespace/");
+        nsContext.addNamespace("bar", "http://barNamespace/");
+        nsContext.addNamespace("foo", "http://fooNamespace/");
+        getContextSupport().setNamespaceContext(nsContext);
+        Iterator iter = list.iterator();
+        while (iter.hasNext())
+        {
+            Object context = iter.next();
+            assertValueOfXPath("Hello", context, "/foo:a/b/c");
+            assertValueOfXPath("Hey", context, "/foo:a/foo:d/foo:e");
+            assertValueOfXPath("Hey3", context, "/foo:a/alias:x/alias:y");
+            assertValueOfXPath("Hey3", context, "/foo:a/foo:x/foo:y");
+            assertValueOfXPath("Hey3", context, "/*[local-name()='a' and namespace-uri()='http://fooNamespace/']/*[local-name()='x' and namespace-uri()='http://fooNamespace/']/*[local-name()='y' and namespace-uri()='http://fooNamespace/']");
+        }
+    }
+
+    public void testNoNamespace() throws JaxenException
+    {
+        Navigator nav = getNavigator();
+        String url = "xml/defaultNamespace.xml";
+        log("Document [" + url + "]");
+        Object document = nav.getDocument(url);
+        XPath contextpath = new BaseXPath("/", nav);
+        log("Initial Context :: " + contextpath);
+        List list = contextpath.selectNodes(document);
+        Iterator iter = list.iterator();
+        while (iter.hasNext())
+        {
+            Object context = iter.next();
+            /* NOTE: /a/b/c selects elements in no namespace only!
+            */
+            assertCountXPath(0, context, "/a/b/c");
+            /*
+                The following test uses an unbound prefix 'x' and should throw an exception.
+                Addresses issue JAXEN-18.
+                Turns out this isn't really tested as the test didn't fail when the exception wasn't thrown.
+              <test select="/x:a/x:b/x:c" count="0" exception="true"/>
+
+            */
+        }
+    }
+
+    public void testNamespaceResolution() throws JaxenException
+    {
+        Navigator nav = getNavigator();
+        String url = "xml/defaultNamespace.xml";
+        log("Document [" + url + "]");
+        Object document = nav.getDocument(url);
+        XPath contextpath = new BaseXPath("/", nav);
+        log("Initial Context :: " + contextpath);
+        List list = contextpath.selectNodes(document);
+        SimpleNamespaceContext nsContext = new SimpleNamespaceContext();
+        nsContext.addNamespace("dummy", "http://dummyNamespace/");
+        getContextSupport().setNamespaceContext(nsContext);
+        Iterator iter = list.iterator();
+        while (iter.hasNext())
+        {
+            Object context = iter.next();
+            assertCountXPath(1, context, "/dummy:a/dummy:b/dummy:c");
+        }
+    }
+
+    public void testTextNodes() throws JaxenException
+    {
+        Navigator nav = getNavigator();
+        String url = "xml/text.xml";
+        log("Document [" + url + "]");
+        Object document = nav.getDocument(url);
+        XPath contextpath = new BaseXPath("/", nav);
+        log("Initial Context :: " + contextpath);
+        List list = contextpath.selectNodes(document);
+        Iterator iter = list.iterator();
+        while (iter.hasNext())
+        {
+            Object context = iter.next();
+            assertCountXPath(3, context, "/foo/bar/text()");
+            assertValueOfXPath("baz", context, "normalize-space(/foo/bar/text())");
+        }
+    }
+
+    public void testNamespaceNodeCounts1() throws JaxenException
+    {
+        Navigator nav = getNavigator();
+        String url = "xml/testNamespaces.xml";
+        log("Document [" + url + "]");
+        Object document = nav.getDocument(url);
+        XPath contextpath = new BaseXPath("/", nav);
+        log("Initial Context :: " + contextpath);
+        List list = contextpath.selectNodes(document);
+        Iterator iter = list.iterator();
+        while (iter.hasNext())
+        {
+            Object context = iter.next();
+            /* the root is not an element, so no namespaces
+            */
+            assertCountXPath(0, context, "namespace::*");
+            assertCountXPath(0, context, "/namespace::*");
+            /* must count the default xml: prefix as well
+            */
+            assertCountXPath(3, context, "/Template/Application1/namespace::*");
+            assertCountXPath(3, context, "/Template/Application2/namespace::*");
+            /* every element has separate copies
+            */
+            assertCountXPath(25, context, "//namespace::*");
+        }
+    }
+
+    public void testNamespaceNodeCounts() throws JaxenException
+    {
+        Navigator nav = getNavigator();
+        String url = "xml/testNamespaces.xml";
+        log("Document [" + url + "]");
+        Object document = nav.getDocument(url);
+        XPath contextpath = new BaseXPath("/Template/Application1", nav);
+        log("Initial Context :: " + contextpath);
+        List list = contextpath.selectNodes(document);
+        Iterator iter = list.iterator();
+        while (iter.hasNext())
+        {
+            Object context = iter.next();
+            /* must count the default xml: prefix as well
+            */
+            assertCountXPath(3, context, "namespace::*");
+            assertCountXPath(0, context, "/namespace::*");
+            assertCountXPath(3, context, "/Template/Application1/namespace::*");
+            assertCountXPath(3, context, "/Template/Application2/namespace::*");
+            assertCountXPath(25, context, "//namespace::*");
+            assertCountXPath(8, context, "//namespace::xplt");
+            /* the name test literally matches the prefix as given in the
+              document, and does not use the uri
+            */
+            assertCountXPath(0, context, "//namespace::somethingelse");
+        }
+    }
+
+    public void testNamespaceNodesHaveParent() throws JaxenException
+    {
+        Navigator nav = getNavigator();
+        String url = "xml/testNamespaces.xml";
+        log("Document [" + url + "]");
+        Object document = nav.getDocument(url);
+        XPath contextpath = new BaseXPath("/", nav);
+        log("Initial Context :: " + contextpath);
+        List list = contextpath.selectNodes(document);
+        Iterator iter = list.iterator();
+        while (iter.hasNext())
+        {
+            Object context = iter.next();
+            /* namespace nodes have their element as their parent
+            */
+            assertCountXPath(1, context, "/Template/namespace::xml/parent::Template");
+        }
+    }
+
+    /* namespace nodes can also be used as context nodes
+    */
+    public void testNamespaceNodeAsContext() throws JaxenException
+    {
+        Navigator nav = getNavigator();
+        String url = "xml/testNamespaces.xml";
+        log("Document [" + url + "]");
+        Object document = nav.getDocument(url);
+        XPath contextpath = new BaseXPath("/Template/namespace::xml", nav);
+        log("Initial Context :: " + contextpath);
+        List list = contextpath.selectNodes(document);
+        Iterator iter = list.iterator();
+        while (iter.hasNext())
+        {
+            Object context = iter.next();
+            assertCountXPath(1, context, "parent::Template");
+        }
+    }
+}
\ No newline at end of file
diff --git a/libjaxen-java/src/javadoc/j2se/package-list b/libjaxen-java/src/javadoc/j2se/package-list
new file mode 100644
index 0000000..7f582f0
--- /dev/null
+++ b/libjaxen-java/src/javadoc/j2se/package-list
@@ -0,0 +1,76 @@
+java.applet
+java.awt
+java.awt.color
+java.awt.datatransfer
+java.awt.dnd
+java.awt.event
+java.awt.font
+java.awt.geom
+java.awt.im
+java.awt.im.spi
+java.awt.image
+java.awt.image.renderable
+java.awt.print
+java.beans
+java.beans.beancontext
+java.io
+java.lang
+java.lang.ref
+java.lang.reflect
+java.math
+java.net
+java.rmi
+java.rmi.activation
+java.rmi.dgc
+java.rmi.registry
+java.rmi.server
+java.security
+java.security.acl
+java.security.cert
+java.security.interfaces
+java.security.spec
+java.sql
+java.text
+java.util
+java.util.jar
+java.util.zip
+javax.accessibility
+javax.naming
+javax.naming.directory
+javax.naming.event
+javax.naming.ldap
+javax.naming.spi
+javax.rmi
+javax.rmi.CORBA
+javax.sound.midi
+javax.sound.midi.spi
+javax.sound.sampled
+javax.sound.sampled.spi
+javax.swing
+javax.swing.border
+javax.swing.colorchooser
+javax.swing.event
+javax.swing.filechooser
+javax.swing.plaf
+javax.swing.plaf.basic
+javax.swing.plaf.metal
+javax.swing.plaf.multi
+javax.swing.table
+javax.swing.text
+javax.swing.text.html
+javax.swing.text.html.parser
+javax.swing.text.rtf
+javax.swing.tree
+javax.swing.undo
+javax.transaction
+org.omg.CORBA
+org.omg.CORBA_2_3
+org.omg.CORBA_2_3.portable
+org.omg.CORBA.DynAnyPackage
+org.omg.CORBA.ORBPackage
+org.omg.CORBA.portable
+org.omg.CORBA.TypeCodePackage
+org.omg.CosNaming
+org.omg.CosNaming.NamingContextPackage
+org.omg.SendingContext
+org.omg.stub.java.rmi
diff --git a/libjaxen-java/src/javadoc/jaxp/package-list b/libjaxen-java/src/javadoc/jaxp/package-list
new file mode 100644
index 0000000..2922c08
--- /dev/null
+++ b/libjaxen-java/src/javadoc/jaxp/package-list
@@ -0,0 +1,9 @@
+javax.xml.parsers
+javax.xml.transform
+javax.xml.transform.dom
+javax.xml.transform.sax
+javax.xml.transform.stream
+org.w3c.dom
+org.xml.sax
+org.xml.sax.ext
+org.xml.sax.helpers
diff --git a/libjaxen-java/src/latex/intro-slides.tex b/libjaxen-java/src/latex/intro-slides.tex
new file mode 100644
index 0000000..dd80723
--- /dev/null
+++ b/libjaxen-java/src/latex/intro-slides.tex
@@ -0,0 +1,2676 @@
+\documentclass[20pt,landscape,headrule,footrule]{foils}
+
+\usepackage{alltt}
+\usepackage{color}
+\usepackage{pstricks}
+\usepackage{graphicx}
+\usepackage{verbatim}
+
+\setlength{\fboxsep}{0pt}
+\setlength{\foilheadskip}{-30pt}
+
+\begin{document}
+
+\definecolor{highlight}{rgb}{0.6,0.0,0.0}
+\definecolor{grey}{rgb}{0.3,0.3,0.3}
+\definecolor{higreen}{rgb}{0.0,0.6,0.0}
+\definecolor{hipurple}{rgb}{0.6,0.0,0.6}
+
+\renewcommand{\emph}[1]{\textcolor{highlight}{#1}}
+\newcommand{\bemph}[1]{\textbf{\emph{#1}}}
+\newcommand{\hired}[1]{\textcolor{red}{#1}}
+\newcommand{\hipurple}[1]{\textcolor{hipurple}{#1}}
+\newcommand{\hiblue}[1]{\textcolor{blue}{#1}}
+\newcommand{\higreen}[1]{\textcolor{higreen}{#1}}
+\newcommand{\hifade}[1]{\textcolor{grey}{#1}}
+\newcommand{\slide}[1]{\foilhead{\bemph{#1}}}
+\newcommand{\subslide}[1]{\foilhead{\bemph{\small{(#1)}}}}
+\newcommand{\breakslide}[1]{\foilhead{}\vspace{1in}\begin{center}\Huge{\textcolor{highlight}{ #1}}\end{center}}
+\newcommand{\egxpath}[1]{\begin{center}\texttt{#1}\end{center}}
+\newcommand{\egcode}[1]{\begin{center}\texttt{#1}\end{center}}
+\newcommand{\at}[0]{\texttt{\@@}}
+\newcommand{\tag}[1]{\texttt{<#1>}}
+
+\newenvironment{codelisting}%
+        {\begin{minipage}{\textwidth}\tiny\begin{alltt}}%
+        {\end{alltt}\end{minipage}}
+
+\newcommand{\diagram}[1]{
+  \begin{minipage}{\textwidth}
+    \begin{center}
+      \includegraphics[scale=0.5]{#1}
+    \end{center}
+  \end{minipage}
+}
+
+\title{\emph{Introduction to XPath\\
+       in Java using Jaxen}\\
+       \small{SD West 2003}}
+
+\author{Bob McWhirter\\
+        \tiny{\emph{The Werken Company}}\\
+        \tiny{\texttt{bob at werken.com}}}
+
+\MyLogo{\emph{http://jaxen.org/}}
+
+\leftheader{\emph{Jaxen}}
+
+\maketitle
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\slide{Quickest Intro}
+
+\begin{itemize}
+  \item Open-Source.
+  \item Business-friendly license (ASF/BSD).
+  \item Works with most XML object-models.
+\end{itemize}
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\slide{Open-Source}
+
+Being open-source, \emph{jaxen} has numerous developers working
+on various aspects of the project, from supporting
+additional object-models to seeking out optimization
+opportunities.
+
+Jaxen has existed for about two years, and has over a dozen
+committers, with 2-to-3 active at any point in time.  Some
+committers are simply users of \emph{jaxen}, others have created
+custom model adapters, while still others are implementors
+of other open-source XML object-models.
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\slide{Business-friendly License}
+
+Since \emph{jaxen} uses a license similar to the one used by
+the Apache Software Foundation, there are few restrictions
+on its usage.  It may be used in other open-source projects
+or in closed-source commercial products.  The only requirement
+is that the code maintains its copyrights.  
+
+\begin{center}
+\bemph{That's it!}
+\end{center}
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\slide{Works with Most XML Object-Models}
+
+\begin{itemize}
+  \item \bemph{dom4j}
+    James Strachan's dom4j includes direct support\\ 
+    for XPath by using the Jaxen library.
+  \item \bemph{JDOM}
+    Jason Hunter's JDOM includes optional support\\ 
+    for XPath by using the Jaxen library.
+  \item \bemph{W3C DOM}
+    Jaxen supports DOM documents.
+  \item \bemph{EXML}
+    The Mind Electric's EXML 6.0 includes direct \\
+    support for XPath by using the Jaxen library.
+\end{itemize}
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\slide{History}
+
+The first XPath engine Bob created was \emph{werken.xpath}, and it
+worked only with JDOM.  It was based upon an \emph{ANTLR} parser-generator grammar
+and contained numerous bugs.  \emph{James Strachan} started the
+\emph{dom4j} project.  Initially, we worked with porting
+werken.xpath to dom4j, but maintaining separate codebases proved 
+difficult.
+
+And thus, the concept for jaxen was born\dots
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\subslide{History - The Beginnings}
+
+Due to issues with the ANTLR-based grammar, \emph{SAXPath}, a
+hand-rolled expression lexer and parser was written.   SAXPath parses
+and reports XPath expressions in a manner similar to how SAX works
+for XML content.
+
+Bob McWhirter and James Strachan designed the \emph{Navigator}
+object-model adapter and implemented the core engine.  James 
+wrote the binding to dom4j while Bob wrote the bindings for
+JDOM and EXML.  James Strachan and David Megginson created the
+W3C DOM binding.
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\subslide{History - Contributors}
+
+Many others contributed patches, optimizations and improvements:
+
+\begin{tabular}{ll}
+\begin{minipage}{4in}
+\small
+\begin{itemize}
+  \item \emph{Erwin Boldwidt}
+  \item \emph{Eddie McGreal}
+  \item \emph{Jan Dvorak}
+  \item \emph{Mark A. Belonga}
+  \item \emph{Michael Brennan}
+  \item \emph{Stephen Colebourne}
+%% \end{itemize}
+%% \end{minipage}
+%% &
+%% \begin{minipage}{4in}
+%% \small
+%% \begin{itemize}
+  \item \emph{Paul R. Brown}
+  \item \emph{Alex Chaffee}
+  \item \emph{Steen Lehmann}
+  \item \emph{Attila Szegedi}
+  \item \emph{Christian Nentwich}
+  \item \emph{Pete Kazmier}
+  \item \emph{Jeffrey Brekke}
+\end{itemize}
+\end{minipage}
+\end{tabular}
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\slide{Jaxen and the XML-InfoSet}
+
+\emph{jaxen}'s flexibility comes from the fact that it works purely
+in terms of the \emph{XML InfoSet} instead of any concrete XML
+representation.  This flexibility actually allows jaxen to work with
+non-XML models.  The only requirement is that a \emph{Navigator}
+adapter be written to satisfy the subset of the InfoSet required
+by jaxen.  
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\slide{XML-InfoSet}
+
+The \emph{XML-InfoSet} defines the semantics of XML instead
+of the textual serialization as the original \emph{XML 1.0} spec
+does.  The InfoSet recognizes that the true structure is a tree
+with various types of nodes which the spec refers to as ``information
+items''.
+
+\begin{minipage}{\textwidth}
+\small
+\begin{itemize}
+  \item \emph{Document Information Item}
+  \item \emph{Element Information Items}
+  \item \emph{Attribute Information Items}
+  \item \emph{Processing Instruction Information Items}
+  \item \emph{Character Information Items}
+  \item \emph{Comment Information Items}
+  \item \emph{Namespace Information Items}
+\end{itemize}
+\end{minipage}
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\subslide{InfoSet - Document Info Item}
+
+The \emph{Document} information item is typically modeled in
+XML object-model frameworks by an explicit class such as  
+\emph{org.dom4j.Document} or \emph{org.jdom.Document}.
+
+The document information item most importantly contains children,
+including the root element and any comments or processing-instructions
+outside of the root element.
+
+\diagram{infoset-doc}
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\subslide{InfoSet - Element Info Items}
+
+Each tag in an XML document is an element and is represented by the
+Info-Set as an \emph{Element} information item.  Once again,
+most XML object-model frameworks represent each element with an
+instance of an element class, such as \emph{org.dom4j.Element}
+or \emph{org.jdom.Element}.
+
+An element information item contains several types of children,
+including attributes, comments, namespace declarations, text context 
+and other elements.  It also contains information regarding its own
+name and namespace.
+
+\begin{codelisting}
+\hifade{<\hiblue{article} id="mcw03"
+         \hiblue{xmlns="http://jaxen.org/example-ns/"}>}
+\end{codelisting}
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\subslide{InfoSet - Element Info Items - Diagram}
+
+\diagram{infoset-elem}
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\subslide{InfoSet - Attribute Info Items}
+
+Each attribute that does not begin with \emph{xmlns} is represented
+by an \emph{Attribute} information item.  Most object-models represent them
+with an explicit attribute class such as \emph{org.dom4j.Attribute}
+or \emph{org.jdom.Attribute}.  It contains information regarding
+its own name and namespace.
+
+\begin{codelisting}
+\hifade{<article \hiblue{id="mcw03"} 
+         xmlns="http://jaxen.org/example-ns/">}
+\end{codelisting}
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\subslide{InfoSet - Processing-Instruction Info Items}
+
+Processing-instructions, while not widely used, embody their target
+and the text associated with them.  Different object-models represent
+PIs differently, so no generalized statement may be made.
+
+\begin{codelisting}
+\hifade{<?\hiblue{mycompany:insert-random-bugs true}?>}
+\end{codelisting}
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\subslide{InfoSet - Character Info Items}
+
+The InfoSet defines a \emph{Character} information item for each individual
+text character.  The \emph{Navigator} of jaxen works with
+consecutive spans of uninterrupted characters.
+
+\begin{codelisting}
+\hifade{<text>
+    \hiblue{jaxen is a fun and exciting way to drive your coworkers insane..}
+</text>}
+\end{codelisting}
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\subslide{InfoSet - Comment Info Items}
+
+\emph{Comment} information items appear as children of either
+\emph{Document} or \emph{Element} items and contain the textual
+content of the comments themselves.
+
+\begin{codelisting}
+\hifade{
+\hiblue{<!--
+  || Comment on the Document information item
+  -->}
+<journal xmlns=\"http://jaxen.org/example-ns/\">
+    \hiblue{<!-- 
+      || Comment on the Element information item for <journal>
+      -->}
+</journal>
+}
+\end{codelisting}
+
+\emph{NOTE:} Due to how the specifications are written, there is no
+guarantee that XML parsed from a file will ever contain comment
+items.  Parsers are allowed to discard the comments and so they
+may not be included in your model of choice.
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\subslide{InfoSet - Namespace Info Items}
+
+The \emph{Namespace} information items contained by \emph{Element}
+items represent all XML namespace bindings in effect at the scope of
+the element.
+
+\begin{codelisting}
+\hifade{<journal \hiblue{xmlns="http://jaxen.org/example-ns-1/"}>
+    <art:article \hiblue{xmlns:art="http://jaxen.org/example-ns-2"}>
+}
+\end{codelisting}
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\slide{What is XPath?}
+
+XPath is a node-addressing expression language for the XML InfoSet.
+
+XPath expressions are used to traverse the graph provided by the
+InfoSet in order to locate any node contained therein.  
+
+\begin{itemize}
+  \item \emph{Full expression language.}
+  \item \emph{Multiple `directions' of traversal.}
+  \item \emph{Predicate evaluation for filtering.}
+  \item \emph{Extremely extensible.}
+\end{itemize}
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\slide{Compared to XQuery}
+
+XPath and XQuery vaguely overlap in functionality.  XPath 2.0 overlaps
+even more so with XQuery.
+
+In general, XQuery is more rigorously defined, more type-safe, much
+larger, and not finished.
+
+XPath is strictly an addressing language, not a full query language,
+but most people find that it satisfies the 80/20 rule where it
+provides 80\% of the solution for 20\% of the effort.
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\breakslide{Simple Expressions}
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\slide{Math!}
+
+Since XPath is a full expression language, arbitrary arithmetic
+constitutes valid expressions.
+
+\egxpath{42 + 84.2}
+
+\egxpath{10 div 3}
+
+\egxpath{(1 + 3) * 42}
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\slide{Location Paths}
+
+\emph{Location paths} are the core of the XPath expression
+language with regards to XML documents.  A location path is comprised
+of a series of \emph{steps}.
+
+Each step is evaluated, in order, against the results of the previous
+step.  The result of each step is a possibly empty set of some nodes
+from the document.
+
+\egxpath{/journal/article/author}
+
+What that means\dots
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\subslide{Location Paths - Processing Logic}
+
+An XPath is evaluated in relation to some initial context which typically is a
+\emph{Document} node from an object-model.
+
+Examples of common initial context classes:
+
+\begin{minipage}{\textwidth}
+\small
+\begin{itemize}
+  \item \emph{org.dom4j.Document}
+  \item \emph{org.jdom.Document}
+  \item \emph{org.w3c.dom.Document}
+\end{itemize}
+\end{minipage}
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\subslide{Location Paths - Processing Logic - Example Document}
+Given a document with the structure:
+
+\begin{codelisting}
+<journal>
+    <article id="article.1">
+        <title>...</title>
+        <author>
+          <first>Bob</first>
+          <last>McWhirter</last>
+        </author>
+        <text>
+        </text>
+    </article>
+    <article id="article.2">
+        <title>...</title>
+        <author>
+          <first>James</first>
+          <last>Strachan</last>
+        </author>
+        <text>
+        </text>
+    </article>
+</journal>
+\end{codelisting}
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\subslide{Location Paths - Processing Logic - Example XPath}
+Given an XPath expression: 
+
+\egxpath{/journal/article/author/last}
+
+Let's walk through how it is evaluated to select all \tag{last}
+elements which are children of \tag{author} elements which in
+turn are children of \tag{article} elements that have a parent 
+\tag{journal} element that is the root element of a document.
+
+\dots{}whew\dots
+
+The initial slash character (``\texttt{/}'') indicates that regardless
+of the initial context, the path is an \emph{absolute location path}
+and thus starts at the very top of the document.
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\subslide{Location Paths - Processing Logic - Journal }
+
+\egxpath{/\hiblue{journal}/article/author/last}
+
+\begin{codelisting}
+\hifade{\hiblue{<journal>}
+    <article id="article.1">
+        <title>...</title>
+        <author>
+          <first>Bob</first>
+          <last>McWhirter</last>
+        </author>
+        <text>
+        </text>
+    </article>
+    <article id="article.2">
+        <title>...</title>
+        <author>
+          <first>James</first>
+          <last>Strachan</last>
+        </author>
+        <text>
+        </text>
+    </article>
+\hiblue{</journal>}}
+\end{codelisting}
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\subslide{Location Paths - Processing Logic - Article }
+
+\egxpath{/journal/\hiblue{article}/author/last}
+
+\begin{codelisting}
+\hifade{<journal>
+    \hiblue{<article id="article.1">}
+        <title>...</title>
+        <author>
+          <first>Bob</first>
+          <last>McWhirter</last>
+        </author>
+        <text>
+        </text>
+    \hiblue{</article>}
+    \hiblue{<article id="article.2">}
+        <title>...</title>
+        <author>
+          <first>James</first>
+          <last>Strachan</last>
+        </author>
+        <text>
+        </text>
+    \hiblue{</article>}
+</journal>}
+\end{codelisting}
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\subslide{Location Paths - Processing Logic - Author }
+
+\egxpath{/journal/article/\hiblue{author}/last}
+
+\begin{codelisting}
+\hifade{<journal>
+    <article id="article.1">
+        <title>...</title>
+        \hiblue{<author>}
+          <first>Bob</first>
+          <last>McWhirter</last>
+        \hiblue{</author>}
+        <text>
+        </text>
+    </article>
+    <article id="article.2">
+        <title>...</title>
+        \hiblue{<author>}
+          <first>James</first>
+          <last>Strachan</last>
+        \hiblue{</author>}
+        <text>
+        </text>
+    </article>
+</journal>}
+\end{codelisting}
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\subslide{Location Paths - Processing Logic - Last }
+
+\egxpath{/journal/article/author/\hiblue{last}}
+
+\begin{codelisting}
+\hifade{<journal>
+    <article id="article.1">
+        <title>...</title>
+        <author>
+          <first>Bob</first>
+          \hiblue{<last>McWhirter</last>}
+        </author>
+        <text>
+        </text>
+    </article>
+    <article id="article.2">
+        <title>...</title>
+        <author>
+          <first>James</first>
+          \hiblue{<last>Strachan</last>}
+        /author>
+        <text>
+        </text>
+    </article>
+</journal>}
+\end{codelisting}
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\subslide{Location Paths - Processing Logic - Results }
+
+The result of evaluating the XPath against the document is a
+\emph{node-set} that contains nodes directly from the original
+object-model.  The results are \emph{not copies}.
+
+In this case, the results are two \emph{element} nodes, being
+instances of classes such as:
+
+\begin{minipage}{\textwidth}
+\small
+\begin{itemize}
+  \item \emph{org.dom4j.Element}
+  \item \emph{org.jdom.Element}
+  \item \emph{org.w3c.dom.Element}
+\end{itemize}
+\end{minipage}
+
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\subslide{Location Paths - Attributes}
+
+The previous example demonstrated some of the simplest location
+path expressions possible.  Not only can a location path select 
+elements, they can also select attributes amongst other items.
+
+A step that begins with the ``\at'' character selects an attribute
+with the given name instead of an element.
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\subslide{Location Paths - Attributes}
+\egxpath{/journal/article/\hiblue{@id}}
+
+This path would select the \texttt{id} attribute node from 
+each of the \tag{article} tags.  Once again, it selects instances
+of the actual corresponding classes for attributes in the
+target object-model, such as:
+
+\begin{itemize}
+  \item \bemph{org.dom4j.Attribute}
+  \item \bemph{org.jdom.Attribute}
+  \item \bemph{org.w3c.dom.Attr}
+\end{itemize}
+
+The path does \emph{not} select the values of the attributes.
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\subslide{Location Paths - Attributes - Example}
+
+\egxpath{/journal/article/\hiblue{@id}}
+
+\begin{codelisting}
+<journal>
+    <article \hiblue{id="article.1"}>
+        <title>...</title>
+        <author>
+          <first>Bob</first>
+          <last>McWhirter</last>
+        </author>
+        <text>
+        </text>
+    </article>
+    <article \hiblue{id="article.2"}>
+        <title>...</title>
+        <author>
+          <first>James</first>
+          <last>Strachan</last>
+        </author>
+        <text>
+        </text>
+    </article>
+</journal>
+\end{codelisting}
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\subslide{Location Paths - Predicates}
+
+Sometimes it is desirable to narrow the results of a particular
+step of a location path.  This narrowing is the job of a
+\emph{predicate}.  Multiple predicates can be chained together
+to further and further constrain the result node set.
+
+\egxpath{/journal/article\hiblue{[@id='article.2']}}
+
+After a step has been evaluated, if a predicate follows, then the
+predicate is evaluated in relation to each member of the node set.
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\subslide{Location Paths - Predicates - Base}
+
+\egxpath{\hiblue{/journal/article}[@id='article.2']}
+
+\begin{codelisting}
+<journal>
+    \hiblue{<article id="article.1">}
+        <title>...</title>
+        <author>
+          <first>Bob</first>
+          <last>McWhirter</last>
+        </author>
+        <text>
+        </text>
+    \hiblue{</article>}
+    \hiblue{<article id="article.2">}
+        <title>...</title>
+        <author>
+          <first>James</first>
+          <last>Strachan</last>
+        </author>
+        <text>
+        </text>
+    \hiblue{</article>}
+</journal>
+\end{codelisting}
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\subslide{Location Paths - Predicates - 1st article}
+
+\egxpath{/journal/article[\hiblue{@id='article.2'}]}
+
+\begin{codelisting}
+<journal>
+    \hiblue{<article \hired{id="article.1"}>}
+        <title>...</title>
+        <author>
+          <first>Bob</first>
+          <last>McWhirter</last>
+        </author>
+        <text>
+        </text>
+    \hiblue{</article>}
+    <article id="article.2">
+        <title>...</title>
+        <author>
+          <first>James</first>
+          <last>Strachan</last>
+        </author>
+        <text>
+        </text>
+    </article>
+</journal>
+\end{codelisting}
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\subslide{Location Paths - Predicates - 2nd article}
+
+\egxpath{/journal/article[\hiblue{@id='article.2'}]}
+
+\begin{codelisting}
+<journal>
+    <article id="article.1">
+        <title>...</title>
+        <author>
+          <first>Bob</first>
+          <last>McWhirter</last>
+        </author>
+        <text>
+        </text>
+    </article>
+    \hiblue{<article \higreen{id="article.2"}>}
+        <title>...</title>
+        <author>
+          <first>James</first>
+          <last>Strachan</last>
+        </author>
+        <text>
+        </text>
+    \hiblue{</article>}
+</journal>
+\end{codelisting}
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\subslide{Location Paths - Predicates - Proximity}
+
+The previous predicate was based upon some \emph{content} as opposed
+to \emph{position} within the document.  XPath defines the concept
+of a \emph{proximity predicate} that allows selection of specific
+elements by their location using roughly array notation.  
+
+\egxpath{/journal/article[2]}
+
+Selects the second \tag{article} under the \tag{journal} tag.  Since
+proximity predicates rely only on the positions of nodes, they are
+\emph{fragile} and do not survive large-scale editing of the
+document.
+
+\emph{NOTE:} Unlike Java, XPath indices begin at \texttt{1} instead
+of \texttt{0}.
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\subslide{Location Paths - Predicates - Proximity}
+
+\egxpath{/journal/article[2]}
+
+\begin{codelisting}
+<journal>
+    <article id="article.1">
+        <title>...</title>
+        <author>
+          <first>Bob</first>
+          <last>McWhirter</last>
+        </author>
+        <text>
+        </text>
+    </article>
+    \hiblue{<article id="article.2">}
+        <title>...</title>
+        <author>
+          <first>James</first>
+          <last>Strachan</last>
+        </author>
+        <text>
+        </text>
+    \hiblue{</article>}
+</journal>
+\end{codelisting}
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\subslide{Location Paths - Predicates - Multiple}
+
+Predicates can be chained together to recursively refine the
+selection.
+
+\egxpath{/journal/article\hiblue{[author/last='Strachan'][1]}}
+
+This path would only select the first \tag{article} that was
+written by an author with the last name \texttt{Strachan}.
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\subslide{Location Paths - Predicates - Nested}
+
+Predicates contain any arbitrary XPath expression which can
+include other location paths and predicates.
+
+\egxpath{/journal/article\hiblue{[author[1]/last='Strachan']}}
+
+This path would select all \tag{article} elements whose first
+\tag{author} has the \tag{last} name of \texttt{Strachan}.
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\subslide{Location Paths - Predicates - Nested - Example}
+
+\egxpath{/journal/article\hiblue{[author[1]/last='Strachan']}}
+
+\begin{codelisting}
+\tiny
+<journal>
+    \hiblue{<article>}
+        <title>...</title>
+        <author>
+          <first>James</first>
+          <last>Strachan</last>
+        </author>
+        <author>
+          <first>Bob</first>
+          <last>McWhirter</last>
+        </author>
+        <text>
+        </text>
+    \hiblue{</article>}
+</journal>
+\end{codelisting}
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\breakslide{Jaxen API}
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\slide{Model Bindings}
+
+Several object-models, such as \emph{dom4j} and \emph{EXML} include
+bindings to the jaxen xpath engine through their own APIs, typically
+in the form of \emph{selectNodes(String xpathExpr)} or
+\emph{selectSingleNode(String xpathExpr)} methods on
+their \emph{Document} and \emph{Element} classes.
+
+Here, we'll address using jaxen directly in conjunction with an
+object-model.  Please consult your chosen model's API documentation
+for any native bindings it may have.
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\slide{The XPath Classes}
+
+The main interface for working with jaxen XPaths is
+\emph{org.jaxen.XPath}.
+
+\begin{codelisting}
+package org.jaxen;
+
+public interface XPath
+\{
+    Object evaluate(Object context)
+        throws JaxenException;
+
+    \dots
+\}
+\end{codelisting}
+
+Each supported object-model has a matching concrete implementation:
+
+\begin{minipage}{\textwidth}
+\small
+\begin{itemize}
+  \item \bemph{org.jaxen.dom4j.Dom4jXPath}
+  \item \bemph{org.jaxen.jdom.JDOMXPath}
+  \item \bemph{org.jaxen.dom.DOMXPath}
+\end{itemize}
+\end{minipage}
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\subslide{The XPath Classes - Constructing}
+
+Once the appropriate class has been selected and imported into your
+code, a new instance of the \emph{XPath} class may be created
+using the constructor that takes a string XPath expression.
+
+\begin{codelisting}
+try
+\{
+    \hiblue{XPath xpath = new Dom4jXPath( "/journal/article/[author/last='Strachan']" );}
+\}
+catch (JaxenException e)
+\{
+    e.printStackTrace();
+\}
+\end{codelisting}
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\subslide{The XPath Classes - Evaluation}
+
+Once an \emph{XPath} has been instantiated successfully, it may be
+evaluated against multiple different contexts.  The \emph{XPath}
+implementations are thread-safe and so may be cached and shared 
+by multiple threads.
+
+\begin{codelisting}
+try
+\{
+    \hiblue{XPath xpath = new Dom4jXPath( "/journal/article/[author/last='Strachan']" );}
+
+    Document doc = retrieveDocument();
+
+    \hiblue{List results = (List) xpath.evaluate( doc );}
+\}
+catch (JaxenException e)
+\{
+    e.printStackTrace();
+\}
+\end{codelisting}
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\subslide{The XPath Classes - Evaluation - Results}
+
+As noted before, while the XPath is primarily intended for
+manipulating XML, it is a full expression language capable of
+evaluating non-XML-based expressions. The return value of
+\emph{evaluate(...)} is a \emph{java.lang.Object}.
+
+Calling code must cast the result to the appropriate class.
+When working with location paths, the result will always
+be a \emph{java.util.List} which represents the possibly
+empty node set of selected nodes.
+
+The members of the List will be instances of classes from the
+underlying object-model.
+In other cases, it may return \emph{java.lang.Number},
+\emph{java.lang.Boolean}, or \emph{java.lang.String}.
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\subslide{The XPath Classes - Evaluation - Helpers}
+
+The \emph{XPath} interface allows for additional helper methods
+that handle much of the desired conversion and casting.
+
+\begin{codelisting}
+package org.jaxen;
+
+public interface XPath
+\{
+    String \hiblue{stringValueOf}(Object context)
+        throws JaxenException;
+
+    boolean \hiblue{booleanValueOf}(Object context)
+        throws JaxenException;
+
+    boolean \hiblue{numberValueOf}(Object context)
+        throws JaxenException;
+
+    List \hiblue{selectNodes}(Object context)
+        throws JaxenException;
+
+    Object \hiblue{selectSingleNode}(Object context)
+        throws JaxenException;
+\}
+\end{codelisting}
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\subslide{The XPath Classes - Evaluation - stringValueOf}
+
+The \emph{stringValueOf(...)} method performs a normal
+\emph{evaluate(...)} and then follows XPath's rules for 
+coercion of the result to a string.
+
+In terms of XPath, this means that the first node is converted to
+its string value and all others are discarded.
+
+\egxpath{/journal/article/author/last}
+
+While this path would select both of the \tag{author} tags,
+only the first would be converted to its string value, which for
+elements, is the complete text content. 
+
+This would result in the string \texttt{McWhirter}.
+
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\subslide{The XPath Classes - Evaluation - booleanValueOf}
+
+The \emph{booleanValueOf(...)} method performs a normal
+\emph{evaluate(...)} and then follows XPath's rules for
+coercion of the result to a boolean.
+
+An empty result set is interpreted as \texttt{false} while a
+non-empty result set is interpreted as \texttt{true}.
+
+This XPath would return \texttt{true}:
+
+\egxpath{/journal/article/author[last='McWhirter']}
+
+This XPath would return \texttt{false}:
+
+\egxpath{/journal/article/author[last='MacWithier']}
+
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\subslide{The XPath Classes - Evaluation - numberValueOf}
+
+The \emph{numberValueOf(...)} method performs a normal
+\emph{evaluate(...)} and then follows XPath's rules for 
+coercion of the result to a number.
+
+In terms of XPath, this means that the first node is converted to
+its number value and all others are discarded.
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\subslide{The XPath Classes - Evaluation - selectNodes}
+
+The \emph{selectNodes(...)} method makes sense only for
+XPaths that perform node selection and not arithmetic.  It simplifies
+calling code by performing the cast to a \emph{List} on the results
+of \emph{evaluate(...)}.
+
+This XPath would return all \tag{author} elements in a list.
+
+\egxpath{/journal/article/author}
+
+\begin{codelisting}
+try
+\{
+    \hiblue{List authors = xpath.selectNodes( "/journal/article/author" );}
+\}
+catch (JaxenException e)
+\{
+    e.printStackTrace();
+\}
+\end{codelisting}
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\subslide{The XPath Classes - Evaluation - selectSingleNode}
+
+The \emph{selectSingleNode(...)} method operates similar to
+\emph{selectNodes(...)} but only returns the first member
+of the selected list as an \emph{Object}.  Depending on the
+expression, calling code must cast to a class appropriate to
+the object-model being used.
+
+This XPath would return only the first \tag{author} element.
+
+\egxpath{/journal/article/author}
+
+\begin{codelisting}
+try
+\{
+    \hiblue{Element firstAuthor = (Element) xpath.selectSingleNode( "/journal/article/author" );}
+\}
+catch (JaxenException e)
+\{
+    e.printStackTrace();
+\}
+\end{codelisting}
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\breakslide{Advanced XPath\\ \& \\ Jaxen}
+
+\begin{center}
+Namespaces - Variables - Functions
+\end{center}
+
+\slide{Namespaces}
+
+In many modern XML documents, XML Namespaces are used to help
+differentiate tags.  Multiple tags may have the same name but
+exist in different namespaces.  These are considered unique.
+
+\begin{codelisting}
+<\hiblue{soap:Envelope}
+  \hiblue{xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"}
+  soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
+   <soap:Body>
+       <\hiblue{mail:Envelope} 
+         \hiblue{xmlns:mail="http://jaxen.org/example-ns/mail/"}>
+         <mail:to>bob at werken.com</mail:to> 
+       <\hiblue{/mail:Envelope}>
+   </soap:Body>
+<\hiblue{/soap:Envelope}>
+\end{codelisting}
+
+Here, two different \tag{Envelope} tags exist.  
+
+One exists in the
+\bemph{http://schemas.xmlsoap.org/soap/envelope} namespace
+while
+the other is in the \bemph{http://jaxen.org/example-ns/mail/}
+namespace.
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\subslide{Namespaces - URIs}
+
+The namespace of an element is a \emph{URI} that does not necessarily
+have to be resolvable or point to any particular type of resource.  It
+acts purely as a distinguishing identifier.
+
+It would be unwieldy to affix the namespace URI to each element, so
+XML defines a way to declare a \emph{prefix mapping} for each
+namespace.
+
+This is accomplished by adding a pseudo-attribute to an element.
+
+\begin{codelisting}
+<wj:journal \hiblue{xmlns:wj="http://werken.com/werken-journal/"}>
+  <wj:article>
+    ...
+  </wj:article>
+</wj:journal>
+\end{codelisting}
+
+Any pseudo-attribute that begins with \emph{xmlns} is considered
+to be a namespace prefix mapping within the scope of the element
+upon which it is defined.
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\subslide{Namespaces - Prefix Mapping}
+
+The normal form of a namespace prefix mapping declaration is:
+
+\egcode{\hiblue{xmlns:\$\{PREFIX\}="\$\{URI\}"}}
+
+\egcode{\hifade{<tagname \hiblue{xmlns:myprefix="my-namespace"}>}}
+
+The declaration is available for the tag upon which it is declared
+and any nested child tag.  A prefix mapping is not required to be
+used by the tag upon which it is defined, and multiple mappings may
+be declared upon a single tag.
+
+\egcode{\hifade{<\hiblue{a:}tagname \hiblue{xmlns:a="uri-a" xmlns:b="uri-b"}>}}
+
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\subslide{Namespaces - Default Mapping}
+
+A \emph{default namespace mapping} can be used to define which
+namespace tags are a part of, unless otherwise specified.  The format
+of the default mapping is identical to the prefix mapping, with the
+exception that a prefix is not used.
+
+\egcode{\hiblue{xmlns="\$\{URI\}"}}
+
+\egcode{\hifade{<tagname \hiblue{xmlns="my-namespace"}>}}
+
+In this case, \tag{tagname} has no prefix but a default namespace
+mapping is defined, so \tag{tagname} is a member of
+\texttt{\hiblue{my-namespace}}.
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\subslide{Namespaces - Prefixes Do Not Matter}
+
+The actual prefixes used within a document \bemph{do not matter}.
+Only the mapped namespace URI is important.  These three documents
+are semantically identical:
+
+Using the default namespace mapping functionality:
+
+\begin{codelisting}
+<journal xmlns="http://werken.com/werken-journal/">
+</journal>
+\end{codelisting}
+
+Using the prefix namespace mapping functionality:
+
+\begin{codelisting}
+<yak:journal yak:xmlns="http://werken.com/werken-journal/">
+</yak:journal>
+\end{codelisting}
+
+Using the prefix namespace mapping functionality with a different
+prefix:
+
+\begin{codelisting}
+<frobnovich:journal xmlns:frobnovich="http://werken.com/werken-journal/">
+</frobnovich:journal>
+\end{codelisting}
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\subslide{Namespaces - Prefixes - XPath}
+
+Since prefixes do not matter, how do you construct an XPath that
+works with namespaces?
+
+\begin{center}
+\bemph{Using prefixes!}
+\end{center}
+
+Just as each element in a document has a set of prefix-to-namespace
+mappings, an XPath expression may also contain a set of
+prefix-to-namespace mappings.
+
+The only caveat is that XPath has absolutely no concept of a default
+namespace mapping.  
+
+\egxpath{\hiblue{j:}journal/\hiblue{j:}article/\hiblue{j:}author/\hiblue{j:}last}
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\subslide{Namespaces - Prefixes - XPath - Mappings}
+
+The XPath specification does not address how prefix namespace mappings
+are created.  It only specifies that an XPath is evaluated within the
+scope of a \emph{namespace context} which defines the mappings.
+
+In \emph{XSLT}, the namespace context is composed of all namespace
+mappings in effect within the template \emph{(not the target document)}
+at the point the xpath is used.
+
+\begin{codelisting}
+\hifade{<xsl:template match="\hiblue{wj:author}" 
+              \hiblue{xmlns:wj="http://werken.com/werken-journal/"}>
+    \dots
+</xsl:template>}
+\end{codelisting}
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\subslide{Namespaces - Prefixes - XPath - Mappings}
+
+The template will match \tag{author} tags in the
+\emph{http://werken.com/werken-journal/} namespace, 
+regardless of the actual prefix (or default mapping) used within the
+target document.
+
+\begin{codelisting}
+\hifade{<journal \hiblue{xmlns="http://werken.com/werken-journal/"}>
+    <\hiblue{author}>
+        \dots
+    <\hiblue{/author}>
+</journal>}
+\end{codelisting}
+
+\begin{codelisting}
+\hifade{<yak:journal \hiblue{xmlns:yak="http://werken.com/werken-journal/"}>
+    <\hiblue{yak:author}>
+        \dots
+    <\hiblue{/yak:author}>
+</yak:journal>}
+\end{codelisting}
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\subslide{Namespaces - Jaxen}
+
+Since jaxen is purely an XPath engine, and not an XSLT engine,
+it follows the specification in mandating nothing about how
+namespace prefix mappings are generated, but simply a \emph{namespace
+context} is available.
+
+This is accomplished through the \bemph{org.jaxen.NamespaceContext}
+interface.  It contains but a single method declaration for
+translating a prefix to a namespace URI.
+
+\begin{codelisting}
+package org.jaxen;
+
+public interface NamespaceContext
+\{
+    \hiblue{String translateNamespacePrefixToUri(String prefix);}
+\}
+\end{codelisting}
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\subslide{Namespaces - Jaxen - SimpleNamespaceContext}
+
+Since mapping a prefix to a namespace URI is a perfect job for a
+look-up table, jaxen provides the
+\bemph{org.jaxen.SimpleNamespaceContext}, which is an implementation
+simply backed by a hash-map.
+
+\begin{codelisting}
+package org.jaxen;
+
+public class SimpleNamespaceContext
+    implements NamespaceContext
+\{
+    public SimpleNamespaceContext() \{ \dots \}
+
+    public SimpleNamespaceContext(Map namespaces) \{ \dots \}
+
+    public void addNamespace(String prefix, 
+                             String namespaceUri) \{ \dots \}
+
+    public String translateNamespacePrefixToUri(String prefix) \{ \dots \}
+\}
+\end{codelisting}
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\subslide{Namespaces - Jaxen - Using NamespaceContext}
+
+Each \emph{XPath} has a \emph{NamespaceContext} associated with
+it.  The association is made using the \emph{setNamespaceContext(...)}
+method.
+
+\begin{codelisting}
+package org.jaxen;
+
+public interface XPath
+\{
+    \dots
+    \hiblue{void setNamespaceContext(NamespaceContext namespaceContext);}
+    \dots
+\}
+\end{codelisting}
+
+Any prefix that is resolvable through the \emph{NamespaceContext} may
+be used within the XPath expression itself.  
+If code using the
+\emph{XPath} does not explicitly set a \emph{NamespaceContext} then
+a default context that contains no mappings is used.
+
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\subslide{Namespaces - Jaxen - Example}
+
+\begin{codelisting}
+try
+\{
+    XPath xpath = new Dom4jXPath( \hiblue{"/j:journal/j:article/j:author"} );
+
+    SimpleNamespaceContext nsContext = new SimpleNamespaceContext();
+
+    \hiblue{nsContext.addNamespace( "j"
+                            "http://werken.com/werken-journal/" );
+
+    xpath.setNamespaceContext( nsContext );}
+
+    Document journalDoc = getJournalEdition( 42 );
+
+    List authors = xpath.selectNodes( journalDoc );
+\}
+catch (JaxenException e)
+\{
+    e.printStackTrace();
+\}
+
+\end{codelisting}
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\slide{Variables}
+
+The XPath specification allows for \emph{variables} in expressions
+to allow parameterization at evaluation time.
+
+Similar to the namespace-context, each XPath expression also has a 
+variable-context that maps variable names to values.
+
+\egxpath{/journal/article/author[last=\hiblue{\$lastName}]}
+
+Or with namespace support:
+
+\egxpath{/journal/article/author[last=\hiblue{\$myNsPrefix:lastName}]}
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\subslide{Variables - Jaxen - VariableContext}
+
+Parallel to the \emph{NamespaceContext}, jaxen provides an
+interface \emph{VariableContext} and a useful simple implementation.
+
+\begin{codelisting}
+package org.jaxen;
+
+public interface VariableContext
+\{
+    Object getVariableValue(String namespaceUri,
+                            String prefix,
+                            String localName)
+        throws UnresolvableException;
+\}
+\end{codelisting}
+
+The three parameters to the \emph{getVariableValue(...)}
+method are:
+
+\begin{minipage}{\textwidth}
+\small
+\begin{enumerate}
+  \item \bemph{namespaceUri} The namespace URI associated with the\\
+    prefix as determined by the current \emph{NamespaceContext}.
+  \item \bemph{prefix} The actual prefix used in the XPath expression.
+  \item \bemph{localName} The portion of the variable name that is\\ 
+    not the namespace prefix.
+\end{enumerate}
+\end{minipage}
+
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\subslide{Variables - Jaxen - SimpleVariableContext}
+
+A simple implementation of \emph{VariableContext} is provided by 
+the sensibly-named \emph{SimpleVariableContext}, which is backed
+by a hash-map.
+
+\begin{codelisting}
+package org.jaxen;
+
+public class SimpleVariableContext
+    implements VariableContext
+\{
+    public SimpleVariableContext() \{ \dots \}
+
+    public void setVariableValue(String namespaceUri,
+                                 String localName,
+                                 Object value) \{ \dots \}
+
+    public void setVariableValue(String localName,
+                                 Object value) \{ \dots \}
+
+    public Object getVariableValue(String namespaceUri,
+                                   String prefix,
+                                   String localName)
+        throws UnresolvableException \{ \dots \}
+\}
+\end{codelisting}
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\subslide{Variables - Jaxen - Using VariableContext}
+
+Each \emph{XPath} has a \emph{VariableContext} associated with
+it.  The association is made using the \emph{setVariableContext(...)}
+method.
+
+\begin{codelisting}
+package org.jaxen;
+
+public interface XPath
+\{
+    \dots
+    \hiblue{void setVariableContext(VariableContext variableContext);}
+    \dots
+\}
+\end{codelisting}
+
+If code using the \emph{XPath} does not explicitly set a 
+\emph{VariableContex} then
+a default context that contains no variables is used.
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\subslide{Variables - Jaxen - Example}
+
+\begin{codelisting}
+try
+\{
+    XPath xpath = new Dom4jXPath( "/journal/article[author/last=\hiblue{\$lastName}]" );
+
+    \hiblue{SimpleVariableContext varContext = new SimpleVariableContext();
+
+    varContext.setVariable( "lastName"
+                            "Strachan" );
+
+    xpath.setVariableContext( varContext );}
+
+    Document journalDoc = getJournalEdition( 42 );
+
+    List strachanArticles = xpath.selectNodes( journalDoc );
+\}
+catch (JaxenException e)
+\{
+    e.printStackTrace();
+\}
+\end{codelisting}
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\slide{Functions}
+
+The XPath language supports functions in expressions and provides for
+a core library of functions dealing with strings, numbers, booleans
+and node sets.
+
+Determine the number of articles written by Mr. Strachan:
+
+\egxpath{\hiblue{count(}/journal/article[author/last="Strachan"]\hiblue{)}}
+
+Find the Irish:
+
+\egxpath{/journal/article[\hiblue{starts-with(}author/last,"Mc"\hiblue{)}]}
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\subslide{Functions - Core Library}
+
+The core XPath function library is divided into four groups:
+
+\begin{enumerate}
+  \item \bemph{Node set functions}\\
+    Functions for working with node-sets.
+    Either the implicit current node set or one passed as a parameter.
+  \item \bemph{String functions}\\
+    Functions for working with strings.  Includes type coercions.
+  \item \bemph{Boolean functions}\\
+    Functions for working with booleans.  Includes type coercions.
+  \item \bemph{Number functions}\\
+    Functions for working with numbers.  Includes type coercions.
+\end{enumerate}
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\subslide{Functions - Core Library - Node Set Functions}
+\begin{minipage}{\textwidth}
+\small
+\begin{itemize}
+  \item \bemph{last()}
+    Returns the index of the last item of the current result
+    set.  
+      \egxpath{/journal/article[\hiblue{last()}]}
+  \item \bemph{position()}
+    Returns the index of the current item in the current result set.
+      \egxpath{/journal/article[\hiblue{position()}<3]}
+  \item \bemph{count(\textsl{node-set})}
+    Returns the number of items in the parameter result set.
+      \egxpath{\hiblue{count(/journal/article)}}
+  \item \bemph{id(\textsl{object})}
+    Returns the elements with the ID specified.
+      \egxpath{\hiblue{id("article.1")}/author/last}
+\end{itemize}
+\end{minipage}
+
+\subslide{Functions - Core Library - Node Set Functions}
+\begin{minipage}{\textwidth}
+\small
+\begin{itemize}
+  \item \bemph{local-name(\textsl{node-set?})}
+    Returns the non-namespace portion of the node name of either
+    a node set passed as a parameter or the current node in the
+    current node set.
+      \egxpath{\hiblue{local-name(/wj:journal)}}
+      \egxpath{/journal/*[\hiblue{local-name()}="article"]}
+  \item \bemph{namespace-uri(\textsl{node-set?})}
+    Returns the namespace URI of the node name of either 
+    a node set passed as a parameter or the current node in the
+    current node set.
+      \egxpath{\hiblue{namespace-uri(/wj:journal)}}
+      \egxpath{/journal/*:*[\hiblue{namespace-uri()}="http://werken.com/werken-journal/"]}
+  \item \bemph{name(\textsl{node-set?})}
+    Returns the complete textual node name of either a node set
+    passed as a parameter or the current node in the current
+    node set.
+      \egxpath{\hiblue{name(/journal)}}
+      \egxpath{/*[\hiblue{name()}="soap:Envelope"]}
+\end{itemize}
+\end{minipage}
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\subslide{Functions - Core Library - String Functions}
+\begin{minipage}{\textwidth}
+\small
+\begin{itemize}
+  \item \bemph{string(\textsl{object?})} 
+    Converts an object (possibly the current context node) to its
+    string value.
+      \egxpath{/journal/article/author[string()='Strachan']}
+  \item \bemph{concat(\textsl{string, string, string*})}
+    Concatenate two or more strings together.  
+      \egxpath{concat(author/salutation, ' ', author/last)}
+  \item \bemph{starts-with(\textsl{string, string})}
+    Determine if the first argument starts with the second argument
+string.
+      \egxpath{/journal/article[starts-with(title, 'Advanced')]}
+  \item \bemph{contains(\textsl{string, string})}
+    Determine if the first argument contains the second argument
+string.
+      \egxpath{/journal/article[contains(title, 'XPath')]}
+\end{itemize}
+\end{minipage}
+
+\subslide{Functions - Core Library - String Functions}
+\begin{minipage}{\textwidth}
+\small
+\begin{itemize}
+  \item \bemph{substring-before(\textsl{string, string})}
+    Retrieve the substring of the first argument that occurs before
+    the first occurrence of the second argument string.
+      \egxpath{substring-before(/journal/article[1]/date, '/')}
+  \item \bemph{substring-after(\textsl{string, string})}
+    Retrieve the substring of the first argument that occurs after
+    the first occurrence of the second argument string.
+      \egxpath{substring-after(/journal/article[1]/date, '/')}
+  \item \bemph{substring(\textsl{string, number, number?})}
+    Retrieve the substring of the first argument starting at the index
+    of the second number argument, for the length of the optional
+    third argument.
+      \egxpath{substring('McStrachan', 3)}
+  \item \bemph{string-length(\textsl{string?})}
+    Determine the length of a string, or the current context node
+    coerced to a string.
+      \egxpath{/journal/article[string-length(author/last) > 9]}
+\end{itemize}
+\end{minipage}
+
+\subslide{Functions - Core Library - String Functions}
+\begin{minipage}{\textwidth}
+\small
+\begin{itemize}
+  \item \bemph{normalize-space(\textsl{string?})}
+    Retrieve the string argument or context node with all space
+    normalized, trimming whitespace from the ends and compressing
+    consecutive whitespace elements to a single space.
+      \egxpath{normalize-space(/journal/article[1]/content)}
+  \item \bemph{translate(\textsl{string, string, string})}
+    Retrieve the first string argument augmented so that characters
+    that occur in the second string argument are replaced by the
+    character from the third argument in the same position.
+      \egxpath{translate( 'bob', 'abc', 'ZXY' )  XoX}
+    
+\end{itemize}
+\end{minipage}
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\subslide{Functions - Core Library - Boolean Functions}
+\begin{minipage}{\textwidth}
+\small
+\begin{itemize}
+  \item \bemph{boolean(\textsl{object})}
+    Convert the argument to a boolean value.
+    \egxpath{boolean(/journal/article/author/last[.='Strachan']}
+  \item \bemph{not(\textsl{boolean})}
+    Negate a boolean value.
+    \egxpath{not(/journal/article/author/last[.='Strachan']}
+  \item \bemph{true()}
+    Boolean true.
+  \item \bemph{false()}
+    Boolean false.
+  \item \bemph{lang(\textsl{string})}
+    Test if the lang, as set by \verb|xml:lang| attributes is
+    the language specified.
+      \egxpath{/journal/article[1]/content[lang('en')]}
+\end{itemize}
+\end{minipage}
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\subslide{Functions - Core Library - Number Functions}
+\begin{minipage}{\textwidth}
+\small
+\begin{itemize}
+  \item \bemph{number(\textsl{object?})}
+    Convert the argument or context node to a number value.
+      \egxpath{/journal[number(year)=2003]}
+  \item \bemph{sum(\textsl{node-set})}
+    Sum the values of the node-set.
+      \egxpath{sum(/journal/article/author/age)}
+  \item \bemph{floor(\textsl{number})}
+    Return the largest integer that is not greater than
+    the number argument.
+  \item \bemph{ceiling(\textsl{number})}
+    Return the smallest integer that is not less than the
+    number argument.
+  \item \bemph{round(\textsl{number})}
+    Round the number argument.
+\end{itemize}
+\end{minipage}
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\subslide{Functions - Function Context}
+
+Like most other things in XPath, there is a \emph{function context}
+that contains the core library of functions. The set of functions available
+within an expression is extensible.  
+
+XSLT has added the
+\emph{document(\textsl{url})} function.  Other technologies, such as 
+\emph{XPointer} and \emph{BPEL4WS} add even more functions to
+the XPath function context.
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\subslide{Functions - Jaxen - Function Context}
+
+An extensible function context is supported in jaxen through the
+\emph{FunctionContext} interface.
+
+\begin{codelisting}
+package org.jaxen;
+
+public interface FunctionContext
+\{
+    Function getFunction(String namepsaceUri,
+                         String prefix,
+                         String localName)
+        throws UnresolvableException;
+\}
+\end{codelisting}
+
+The three parameters to the \emph{getFunction(...)}
+method are:
+
+\begin{minipage}{\textwidth}
+\small
+\begin{enumerate}
+  \item \bemph{namespaceUri} The namespace URI associated with the\\
+    prefix as determined by the current \emph{NamespaceContext}.
+  \item \bemph{prefix} The actual prefix used in the XPath expression.
+  \item \bemph{localName} The portion of the variable name that is\\ 
+    not the namespace prefix.
+\end{enumerate}
+\end{minipage}
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\breakslide{Quick Romp Through Advanced XPath}
+
+\slide{Advanced Axes}
+
+XPath provides many different semantic methods for navigating
+a document.  Each direction is an \emph{axis} that defines
+which nodes each \emph{step} will be applied to.  Some we
+have already visited.
+
+Each axis allows the effects of a particular step to be 
+constrained to a certain set of nodes for matching.
+
+The general syntax for a step with an explicit axis is:
+
+\egxpath{\hiblue{\$\{AXIS\}::}\$\{NAME\}}
+
+\egxpath{/\hiblue{child::}journal/\hiblue{child::}article/\hiblue{attribute::}id}
+\egxpath{\small{/journal/article/@id}}
+
+\subslide{Advanced Axes - Descriptions}
+
+\begin{minipage}{\textwidth}
+\small
+\begin{itemize}
+  \item \bemph{child} 
+    Children of the context node.  This is the default implicit axis.
+  \item \bemph{descendant} 
+    Descendent of the context node.  
+  \item \bemph{parent} 
+    Parent of the context node.
+  \item \bemph{ancestor} 
+    Ancestors of the context node.
+  \item \bemph{following-sibling} 
+    Following siblings of the context node.
+  \item \bemph{preceding-sibling} 
+    Preceding siblings of the context node.
+  \item \bemph{following} 
+    Nodes following the context node.
+  \item \bemph{preceding} 
+    Nodes preceding the context node.
+  \item \bemph{attribute} 
+    Attributes of the context node.  Steps begining with `@' operate
+    along the attribute axis.
+  \item \bemph{namespace} 
+    Namespaces of the context node.  
+  \item \bemph{self} 
+    The context node. 
+  \item \bemph{descendant-or-self} 
+    The context node or its descendants.
+  \item \bemph{ancestor-or-self} 
+    The context node or its ancestors
+\end{itemize}
+\end{minipage}
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\subslide{Advanced Axes - Examples}
+
+In the following slides, the context node will be highlighed
+in \hiblue{blue} and the axis will be demonstrated in
+\hired{red}.  When the context node is a part of the axis,
+it will be highlighted in \hipurple{purple}.
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\subslide{Advanced Axes - Examples - child}
+
+\begin{codelisting}
+\hifade{<library>
+    <journal> ... </journal>
+    <journal>
+        <article id="article.1">
+            <author>
+                <last></last>
+                <first></first>
+            </author>
+        </article>
+        \hiblue{<article id="article.2">}
+            \hired{<author>}
+                <last></last>
+                <first></first>
+            \hired{</author>}
+        \hiblue{</article>}
+        <article id="article.3">
+            <author>
+                <last></last>
+                <first></first>
+            </author>
+        </article>
+    </journal>
+    <journal> ... </journal>
+</library>}
+\end{codelisting}
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\subslide{Advanced Axes - Examples - descendant}
+
+\begin{codelisting}
+\hifade{<library>
+    <journal> ... </journal>
+    <journal>
+        <article id="article.1">
+            <author>
+                <last></last>
+                <first></first>
+            </author>
+        </article>
+        \hiblue{<article id="article.2">
+            \hired{<author>
+                <last></last>
+                <first></first>
+            </author>}
+        </article>}
+        <article id="article.3">
+            <author>
+                <last></last>
+                <first></first>
+            </author>
+        </article>
+    </journal>
+    <journal> ... </journal>
+</library>}
+\end{codelisting}
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\subslide{Advanced Axes - Examples - parent}
+
+\begin{codelisting}
+\hifade{<library>
+    <journal> ... </journal>
+    \hired{<journal>}
+        <article id="article.1">
+            <author>
+                <last></last>
+                <first></first>
+            </author>
+        </article>
+        \hiblue{<article id="article.2">}
+            <author>
+                <last></last>
+                <first></first>
+            </author>
+        \hiblue{</article>}
+        <article id="article.3">
+            <author>
+                <last></last>
+                <first></first>
+            </author>
+        </article>
+    \hired{</journal>}
+    <journal> ... </journal>
+</library>}
+\end{codelisting}
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\subslide{Advanced Axes - Examples - ancestor}
+
+\begin{codelisting}
+\hifade{\hired{<library>}
+    <journal> ... </journal>
+    \hired{<journal>}
+        <article id="article.1">
+            <author>
+                <last></last>
+                <first></first>
+            </author>
+        </article>
+        \hiblue{<article id="article.2">}
+            <author>
+                <last></last>
+                <first></first>
+            </author>
+        \hiblue{</article>}
+        <article id="article.3">
+            <author>
+                <last></last>
+                <first></first>
+            </author>
+        </article>
+    \hired{</journal>}
+    <journal> ... </journal>
+\hired{</library>}}
+\end{codelisting}
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\subslide{Advanced Axes - Examples - following-sibling}
+
+\begin{codelisting}
+\hifade{<library>
+    <journal> ... </journal>
+    <journal>
+        <article id="article.1">
+            <author>
+                <last></last>
+                <first></first>
+            </author>
+        </article>
+        \hiblue{<article id="article.2">}
+            <author>
+                <last></last>
+                <first></first>
+            </author>
+        \hiblue{</article>}
+        \hired{<article id="article.3">}
+            <author>
+                <last></last>
+                <first></first>
+            </author>
+        \hired{</article>}
+    </journal>
+    <journal> ... </journal>
+</library>}
+\end{codelisting}
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\subslide{Advanced Axes - Examples - preceding-sibling}
+
+\begin{codelisting}
+\hifade{<library>
+    <journal> ... </journal>
+    <journal>
+        \hired{<article id="article.1">}
+            <author>
+                <last></last>
+                <first></first>
+            </author>
+        \hired{</article>}
+        \hiblue{<article id="article.2">}
+            <author>
+                <last></last>
+                <first></first>
+            </author>
+        \hiblue{</article>}
+        <article id="article.3">
+            <author>
+                <last></last>
+                <first></first>
+            </author>
+        </article>
+    </journal>
+    <journal> ... </journal>
+</library>}
+\end{codelisting}
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\subslide{Advanced Axes - Examples - following}
+
+\begin{codelisting}
+\hifade{<library>
+    <journal> ... </journal>
+    <journal>
+        <article id="article.1">
+            <author>
+                <last></last>
+                <first></first>
+            </author>
+        </article>
+        \hiblue{<article id="article.2">}
+            <author>
+                <last></last>
+                <first></first>
+            </author>
+        \hiblue{</article>}
+        \hired{<article id="article.3">}
+            <author>
+                <last></last>
+                <first></first>
+            </author>
+        \hired{</article>}
+    </journal>
+    \hired{<journal> ... </journal>}
+</library>}
+\end{codelisting}
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\subslide{Advanced Axes - Examples - preceding}
+
+\begin{codelisting}
+\hifade{<library>
+    \hired{<journal> ... </journal>}
+    <journal>
+        \hired{<article id="article.1">}
+            <author>
+                <last></last>
+                <first></first>
+            </author>
+        \hired{</article>}
+        \hiblue{<article id="article.2">}
+            <author>
+                <last></last>
+                <first></first>
+            </author>
+        \hiblue{</article>}
+        <article id="article.3">
+            <author>
+                <last></last>
+                <first></first>
+            </author>
+        </article>
+    </journal>
+    <journal> ... </journal>
+</library>}
+\end{codelisting}
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\subslide{Advanced Axes - Examples - attribute}
+
+\begin{codelisting}
+\hifade{<library>
+    <journal> ... </journal>
+    <journal>
+        <article id="article.1">
+            <author>
+                <last></last>
+                <first></first>
+            </author>
+        </article>
+        \hiblue{<article \hired{id="article.2"}>}
+            <author>
+                <last></last>
+                <first></first>
+            </author>
+        \hiblue{</article>}
+        <article id="article.3">
+            <author>
+                <last></last>
+                <first></first>
+            </author>
+        </article>
+    </journal>
+    <journal> ... </journal>
+</library>}
+\end{codelisting}
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\subslide{Advanced Axes - Examples - self}
+
+\begin{codelisting}
+\hifade{<library>
+    <journal> ... </journal>
+    <journal>
+        <article id="article.1">
+            <author>
+                <last></last>
+                <first></first>
+            </author>
+        </article>
+        \hipurple{<article id="article.2">}
+            <author>
+                <last></last>
+                <first></first>
+            </author>
+        \hipurple{</article>}
+        <article id="article.3">
+            <author>
+                <last></last>
+                <first></first>
+            </author>
+        </article>
+    </journal>
+    <journal> ... </journal>
+</library>}
+\end{codelisting}
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\subslide{Advanced Axes - Examples - descendant-or-self}
+
+\begin{codelisting}
+\hifade{<library>
+    <journal> ... </journal>
+    <journal>
+        <article id="article.1">
+            <author>
+                <last></last>
+                <first></first>
+            </author>
+        </article>
+        \hipurple{<article id="article.2">}
+            \hired{<author>
+                <last></last>
+                <first></first>
+            </author>}
+        \hipurple{</article>}
+        <article id="article.3">
+            <author>
+                <last></last>
+                <first></first>
+            </author>
+        </article>
+    </journal>
+    <journal> ... </journal>
+</library>}
+\end{codelisting}
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\subslide{Advanced Axes - Examples - ancestor-or-self}
+
+\begin{codelisting}
+\hifade{\hired{<library>}
+    <journal> ... </journal>
+    \hired{<journal>}
+        <article id="article.1">
+            <author>
+                <last></last>
+                <first></first>
+            </author>
+        </article>
+        \hipurple{<article id="article.2">}
+            <author>
+                <last></last>
+                <first></first>
+            </author>
+        \hipurple{</article>}
+        <article id="article.3">
+            <author>
+                <last></last>
+                <first></first>
+            </author>
+        </article>
+    \hired{</journal>}
+    <journal> ... </journal>
+\hired{</library>}}
+\end{codelisting}
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\slide{Node Types}
+
+Most of the previous examples have dealt with elements and attributes,
+but XPath defines several types of nodes that can be matched by
+expressions.
+
+\begin{minipage}{\textwidth}
+\small
+\begin{itemize}
+    \item \bemph{comment} Matches any comment node.
+        \egxpath{//\hiblue{comment()}}
+    \item \bemph{text} Matches text nodes.
+        \egxpath{/journal/article/title/\hiblue{text()}}
+    \item \bemph{processing-instruction} Matches processing-instructions.
+        \egxpath{//\hiblue{processing-instruction( 'template' )}}
+    \item \bemph{node} Matches any node.
+        \egxpath{/journal/article/author/\hiblue{node()}}
+\end{itemize}
+\end{minipage}
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\subslide{Node Types - Implicit}
+
+Implicit node types addressable by names include:
+
+\begin{minipage}{\textwidth}
+\small
+\begin{itemize}
+    \item \bemph{element} The default node-type when performing name-based matches:
+        \egxpath{/journal/article/author}
+    \item \bemph{attribute} The nodes matched by steps along the
+\emph{attribute} axis.
+        \egxpath{/journal/article/attribute::id}
+        \egxpath{/journal/article/@id}
+    \item \bemph{namespace} The nodes matched by steps along the
+\emph{namespace} axis.
+        \egxpath{/journal/namespace::*}
+\end{itemize}
+\end{minipage}
+
+ 
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\slide{Abbreviations}
+
+The XPath syntax includes a few abbreviations to make authoring
+expressions easier.  Implicitly, the \emph{child} axis is used
+for any name-based matches.
+
+\egxpath{/journal/article}
+\egxpath{/\hiblue{child::}journal/\hiblue{child::}article}
+
+The `@' symbol is used as an abbreviation for the \emph{attribute}
+axis.
+
+\egxpath{/journal/article/\hiblue{@}id}
+\egxpath{/journal/article/\hiblue{attribute::}id}
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\subslide{Abbreviations}
+
+The `.' character is an abbreviation for \emph{self::node()}.
+
+\egxpath{/journal/article[\hiblue{.}/@id='article.1']}
+
+The `//' sequence is an abbreviation for
+\emph{descendant-or-self::node()}
+which allows for matching nodes with arbitrary nodes in-between.
+
+\egxpath{\hiblue{//}author/last[.='Strachan']}
+\egxpath{\hiblue{/descendant-or-self::node()}/author/last[.='Strachan']}
+
+The `*' character matches any element or attribute name.
+
+\egxpath{/journal/\hiblue{*}[author/last='Strachan']}
+\egxpath{/journal/\hiblue{@*}}
+
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\breakslide{Navigator}
+
+\begin{center}
+Adapting models for XPath
+\end{center}
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\slide{Navigation}
+
+Since XPath expression steps are evaluated in relation to a context
+node across a particular axis of `travel', the main aspects of
+navigating an object-model involves iterating over members of an axis.
+
+The \emph{Navigator} interface has a method for each axis in
+the form of:
+
+\begin{center}
+\begin{minipage}{0.8\textwidth}
+\small
+\begin{alltt}
+Iterator get\hiblue{\$\{AXIS\}}AxisIterator(Object contextNode)
+    throws UnsupportedAxisException;     
+\end{alltt}
+\end{minipage}
+\end{center}
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\subslide{Navigation - Axis Iterators}
+
+
+\begin{codelisting}
+package org.jaxen;
+
+public interface Navigator
+\{
+    Iterator getChildAxisIterator(Object contextNode)
+        throws UnsupportedAxisException;
+
+    Iterator getDescendantAxisIterator(Object contextNode)
+        throws UnsupportedAxisException;
+
+    Iterator getParentAxisIterator(Object contextNode)
+        throws UnsupportedAxisException;
+
+    Iterator getAncestorAxisIterator(Object contextNode)
+        throws UnsupportedAxisException;
+
+    Iterator getFollowingSiblingAxisIterator(Object contextNode)
+        throws UnsupportedAxisException;
+
+    Iterator getPrecedingSiblingAxisIterator(Object contextNode)
+        throws UnsupportedAxisException;
+\end{codelisting}
+
+continues\dots
+
+\subslide{Navigator - Axis Iterator - continued}
+
+\dots\ continued
+
+\begin{codelisting}
+    Iterator getFollowingAxisIterator(Object contextNode)
+        throws UnsupportedAxisException;
+
+    Iterator getPrecedingAxisIterator(Object contextNode)
+        throws UnsupportedAxisException;
+
+    Iterator getAttributeAxisIterator(Object contextNode)
+        throws UnsupportedAxisException;
+
+    Iterator getNamespaceAxisIterator(Object contextNode)
+        throws UnsupportedAxisException;
+
+    Iterator getSelfAxisIterator(Object contextNode)
+        throws UnsupportedAxisException;
+
+    Iterator getDescendantOrSelfAxisIterator(Object contextNode)
+        throws UnsupportedAxisException;
+
+    Iterator getAncestorOrSelfAxisIterator(Object contextNode)
+        throws UnsupportedAxisException;
+\}
+\end{codelisting}
+
+\subslide{Navigation - DefaultNavigator}
+
+Since many of the axes are composite axes that can be synthesized
+from a sub-set, jaxen provides the \emph{DefaultNavigator} which
+is a useful base class for model-specific navigators.
+
+If a model-specific navigator implements
+\emph{getParentAxisIterator(...)}
+then the \emph{DefaultNavigator} can synthesize a useful
+default \emph{getAncestorAxisIterator(...)}.
+
+\subslide{Navigation - DefaultNavigator - Axis Synthesis}
+
+The following axes can be synthesized:
+
+\begin{minipage}{\textwidth}
+\small
+\begin{itemize}
+  \item \bemph{descendant} Built from \emph{child} recursively.
+  \item \bemph{ancestor} Built from \emph{parent} recursively.
+  \item \bemph{self} Completely synthetic.
+  \item \bemph{descendant-or-self} Built from \emph{child} recursively.
+  \item \bemph{ancestor-or-self} Built from \emph{parent} recursively.
+  \item \bemph{following} Built from \emph{parent} and \emph{child}.
+  \item \bemph{preceding} Built from \emph{parent} and \emph{child}.
+  \item \bemph{following-sibling} Built from \emph{parent} and \emph{child}.
+  \item \bemph{preceding-sibling} Built from \emph{parent} and \emph{child}.
+\end{itemize}
+
+Much of the axes are defined by purely providing implementation for
+accessing parent and child relationships.
+\end{minipage}
+
+
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\subslide{Navigation - Node types}
+
+Each method is responsible for inspecting the \emph{contextNode}
+parameter object and returning an \emph{Iterator} over the axis
+in relation to the context-node object.  If the object-model as a
+whole does not support a particular axis of travel,
+\emph{UnsupportedAxisException} may be thrown.
+
+The core jaxen engine will ensure that the methods are not called with
+a non-sensical context.  For example,
+\emph{getAttributeAxisIterator(...)} will never be called with a 
+\emph{comment} node as the parameter.
+
+The \emph{Navigator} provides methods to allow the core engine
+to determine the node's type.
+
+\subslide{Navigation - Node types - Tests}
+
+\begin{codelisting}
+package org.jaxen;
+
+public interface Navigator
+\{
+    boolean isDocument(Object object);
+
+    boolean isElement(Object object);
+
+    boolean isAttribute(Object object);
+
+    boolean isNamespace(Object object);
+
+    boolean isComment(Object object);
+
+    boolean isText(Object object);
+
+    boolean isProcessingInstruction(Object object);
+\}
+\end{codelisting}
+
+\subslide{Navigation - Inspection}
+
+The core jaxen engine requires a way to inspect nodes for various
+properties, such as names, namespace URIs, and string values.
+
+\begin{codelisting} 
+package org.jaxen;
+
+public interface Navigator
+\{
+    String getElementName(Object element);
+    String getElementNamespaceUri(Object element);
+    String getAttributeName(Object attr);
+    String getAttributeNameNamespaceUri(Object attr);
+    String getProcessingInstructionTarget(Object pi);
+    String getProcessingInstructionData(Object pi);
+
+    String getCommentStringValue(Object comment);
+    String getElementStringValue(Object element);
+    String getAttributeStringValue(Object attr);
+    String getNamespaceStringValue(Object ns);
+    String getTextStringValue(Object text);
+    String getTextStringValue(Object text);
+\}
+\end{codelisting} 
+
+\subslide{Navigation - Example Navigator}
+Here are some examples of implementations from the
+\emph{DocumentNavigator} for dom4j.  
+
+\subslide{Navigation - Example Navigator - Axis Iterators}
+
+\begin{codelisting}    
+public Iterator getChildAxisIterator(Object contextNode)
+\{
+    if ( contextNode instanceof Branch )
+    \{
+        Branch node = (Branch) contextNode;
+        
+        return node.nodeIterator();
+    \}
+
+    return null;
+\}
+
+public Iterator getAttributeAxisIterator(Object contextNode)
+\{
+    if ( ! ( contextNode instanceof Element ) )
+    {
+        return null;
+    }
+
+    Element elem = (Element) contextNode;
+
+    return elem.attributeIterator();
+\}
+\end{codelisting}
+
+\subslide{Navigation - Example Navigator - Node Types}
+
+\begin{codelisting}
+public boolean isText(Object obj)
+\{
+    return ( obj instanceof Text 
+             ||
+             obj instanceof CDATA );
+\}
+
+public boolean isAttribute(Object obj)
+\{
+    return obj instanceof Attribute;
+\}    
+
+public boolean isProcessingInstruction(Object obj)
+\{
+    return obj instanceof ProcessingInstruction;
+\}
+\end{codelisting}
+
+\subslide{Navigation - Example Navigator - Inspection}
+
+\begin{codelisting}    
+public String getAttributeName(Object obj)
+\{
+    Attribute attr = (Attribute) obj;
+
+    return attr.getName();
+\}
+
+public String getAttributeNamespaceUri(Object obj)
+\{
+    Attribute attr = (Attribute) obj;
+
+    String uri = attr.getNamespaceURI();
+    if ( uri != null && uri.length() == 0 ) 
+        return null;
+    else
+        return uri;
+\}
+
+public String getNamespaceStringValue(Object obj)
+\{
+    Namespace ns = (Namespace) obj;
+
+    return ns.getURI();
+\}
+\end{codelisting}
+
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+%% ----------------------------------------------------------------------
+
+\breakslide{Thanks}
+
+I'd particularly wish to thank Pete Kazmier and Jeffrey Brekke
+for their diligent review of this presentation.  Any errors that 
+remain herein are purely my own responsibility.
+
+\breakslide{Colophon}
+
+\FoilTeX\ \& \LaTeXe\ were used in the production of these
+slides.  
+
+Images were produced via \texttt{dia}, exported to \texttt{EPS} 
+and converted to \texttt{PDF} for inclusion using 
+the \texttt{epstopdf} utility.
+
+This slide deck is 100\% Microsoft-free and produced using
+only open-source software.
+
+\end{document}
+
+
+
diff --git a/libjaxen-java/xml/axis.xml b/libjaxen-java/xml/axis.xml
new file mode 100644
index 0000000..bc996c5
--- /dev/null
+++ b/libjaxen-java/xml/axis.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0"?>
+
+<root>
+
+  <a>
+    <a.1/>
+    <a.2/>
+    <a.3/>
+    <a.4/>
+    <a.5/>
+  </a>
+
+  <b>
+    <b.1/>
+    <b.2/>
+    <b.3/>
+    <b.4/>
+    <b.5/>
+    <b.6/>
+    <b.7/>
+    <b.8/>
+    <b.9/>
+  </b>
+
+</root>
diff --git a/libjaxen-java/xml/basic.xml b/libjaxen-java/xml/basic.xml
new file mode 100644
index 0000000..88385fb
--- /dev/null
+++ b/libjaxen-java/xml/basic.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+
+<foo>
+    <bar>
+        <baz/>
+        <cheese/>
+        <baz/>
+        <cheese/>
+        <baz/>
+    </bar>
+</foo>
diff --git a/libjaxen-java/xml/basicupdate.xml b/libjaxen-java/xml/basicupdate.xml
new file mode 100644
index 0000000..57d458c
--- /dev/null
+++ b/libjaxen-java/xml/basicupdate.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+
+<xu:modifications xmlns:xu="http://www.xmldb.org/xupdate">
+
+  <xu:append select="/foo/bar/cheese[1]">
+    Goudse kaas
+    <edam type="jong belegen">Rond</edam>
+  </xu:append>
+
+  <xu:remove select="/foo/bar/baz[2]"/>
+
+  <xu:if test="/foo">
+    <xu:insert-before select="/foo/bar/baz[2]">
+      <cheese>More cheese!</cheese>
+    </xu:insert-before>
+  </xu:if>
+
+  <xu:insert-before select="/foo/bar/baz[2]">
+    <cheese>Even more cheese!</cheese>
+  </xu:insert-before>
+
+  <xu:if test="/bar">
+    <xu:insert-before select="/foo/bar/baz[2]">
+      <sausages>No sausages today</sausages>
+    </xu:insert-before>
+  </xu:if>
+
+  <xu:variable
+    xmlns:private="http://www.jaxen.org/private"
+    name="private:twice">
+    <cracker/>
+    <!-- champagne -->
+    <?oisters with a bit of lemon?>
+  </xu:variable>
+
+  <xu:variable name="twice" select="'Twice'"/>
+  
+  <xu:insert-after
+    select="/foo/bar"
+    xmlns:private="http://www.jaxen.org/private"
+    >
+    <xu:value-of select="$private:twice"/>
+    <xu:value-of select="$private:twice"/>
+    <xu:value-of select="$twice"/>
+  </xu:insert-after>
+
+</xu:modifications>
diff --git a/libjaxen-java/xml/cdata.xml b/libjaxen-java/xml/cdata.xml
new file mode 100644
index 0000000..c0383ff
--- /dev/null
+++ b/libjaxen-java/xml/cdata.xml
@@ -0,0 +1 @@
+<p>a<![CDATA[whatever]]>b</p>
\ No newline at end of file
diff --git a/libjaxen-java/xml/contents.xml b/libjaxen-java/xml/contents.xml
new file mode 100644
index 0000000..35e3ac7
--- /dev/null
+++ b/libjaxen-java/xml/contents.xml
@@ -0,0 +1,70 @@
+<?xml version="1.0"?>
+
+<?xml-stylesheet href="XSL\JavaXML.html.xsl" type="text/xsl"?>
+<?xml-stylesheet href="XSL\JavaXML.wml.xsl" type="text/xsl" 
+                 media="wap"?>
+<?cocoon-process type="xslt"?>
+
+<!-- Java and XML -->
+<JavaXML:Book xmlns:JavaXML="http://www.oreilly.com/catalog/javaxml/" 
+              xmlns:ora="http://www.oreilly.com"
+              xmlns:unused="http://www.unused.com"
+              ora:category="Java" 
+> 
+  <!-- comment one -->
+  <!-- comment two -->
+
+ <JavaXML:Title>Java and XML</JavaXML:Title>
+ <JavaXML:Contents xmlns:topic="http://www.oreilly.com/topics">
+  <JavaXML:Chapter topic:focus="XML">
+   <JavaXML:Heading>Introduction</JavaXML:Heading>
+   <JavaXML:Topic subSections="7">
+     What Is It?
+   </JavaXML:Topic>
+   <JavaXML:Topic subSections="3">
+     How Do I Use It?
+   </JavaXML:Topic>
+   <JavaXML:Topic subSections="4">
+     Why Should I Use It?
+   </JavaXML:Topic>
+   <JavaXML:Topic subSections="0">
+     What's Next?
+   </JavaXML:Topic>
+  </JavaXML:Chapter>
+
+  <JavaXML:Chapter topic:focus="XML">
+   <JavaXML:Heading>Creating XML</JavaXML:Heading>
+   <JavaXML:Topic subSections="0">An XML Document</JavaXML:Topic>
+   <JavaXML:Topic subSections="2">The Header</JavaXML:Topic>
+   <JavaXML:Topic subSections="6">The Content</JavaXML:Topic>
+   <JavaXML:Topic subSections="1">What's Next?</JavaXML:Topic>
+  </JavaXML:Chapter>
+
+  <JavaXML:Chapter topic:focus="Java">
+   <JavaXML:Heading>Parsing XML</JavaXML:Heading>
+   <JavaXML:Topic subSections="3">Getting Prepared</JavaXML:Topic>
+   <JavaXML:Topic subSections="3">SAX Readers</JavaXML:Topic>
+   <JavaXML:Topic subSections="9">Content Handlers</JavaXML:Topic>
+   <JavaXML:Topic subSections="4">Error Handlers</JavaXML:Topic>
+   <JavaXML:Topic subSections="0">
+     A Better Way to Load a Parser
+   </JavaXML:Topic>
+   <JavaXML:Topic subSections="4">"Gotcha!"</JavaXML:Topic>
+   <JavaXML:Topic subSections="0">What's Next?</JavaXML:Topic>
+  </JavaXML:Chapter>
+
+  <JavaXML:SectionBreak/>
+
+  <JavaXML:Chapter topic:focus="Java">
+   <JavaXML:Heading>Web Publishing Frameworks</JavaXML:Heading>
+   <JavaXML:Topic subSections="4">Selecting a Framework</JavaXML:Topic>
+   <JavaXML:Topic subSections="4">Installation</JavaXML:Topic>
+   <JavaXML:Topic subSections="3">
+     Using a Publishing Framework
+   </JavaXML:Topic>
+   <JavaXML:Topic subSections="2">XSP</JavaXML:Topic>
+   <JavaXML:Topic subSections="3">Cocoon 2.0 and Beyond</JavaXML:Topic>
+   <JavaXML:Topic subSections="0">What's Next?</JavaXML:Topic>
+  </JavaXML:Chapter>
+ </JavaXML:Contents>
+</JavaXML:Book>
diff --git a/libjaxen-java/xml/defaultNamespace.xml b/libjaxen-java/xml/defaultNamespace.xml
new file mode 100644
index 0000000..1e32981
--- /dev/null
+++ b/libjaxen-java/xml/defaultNamespace.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<a xmlns="http://dummyNamespace/">
+  <b>
+    <c>Hello</c>
+  </b>
+</a>
diff --git a/libjaxen-java/xml/evaluate.xml b/libjaxen-java/xml/evaluate.xml
new file mode 100644
index 0000000..90d06bd
--- /dev/null
+++ b/libjaxen-java/xml/evaluate.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+
+<evaluate>
+  <data>
+    <jumps>
+      <subject>
+        <the/>
+        <fox color="brown"/>
+        <speed category="quick"/>
+      </subject>
+      <over/>
+      <object>
+        <the/>
+        <dog color="unspecified"/>
+        <speed category="lazy"/>
+      </object>
+    </jumps>
+  </data>
+       
+  <!-- there is one element with attribute color="brown" should this
+  meta-test should succeed -->
+  
+  <metatest select="//@color">brown</metatest>
+ 
+  <!-- there is no element with attribute category="moderate" -->
+  <metatest select="//speed/@category">moderate</metatest>
+
+</evaluate>
diff --git a/libjaxen-java/xml/fibo.xml b/libjaxen-java/xml/fibo.xml
new file mode 100644
index 0000000..9b5d0ec
--- /dev/null
+++ b/libjaxen-java/xml/fibo.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Fibonacci_Numbers>
+  <fibonacci index="0">0</fibonacci>
+  <fibonacci index="1">1</fibonacci>
+  <fibonacci index="2">1</fibonacci>
+  <fibonacci index="3">2</fibonacci>
+  <fibonacci index="4">3</fibonacci>
+  <fibonacci index="5">5</fibonacci>
+  <fibonacci index="6">8</fibonacci>
+  <fibonacci index="7">13</fibonacci>
+  <fibonacci index="8">21</fibonacci>
+  <fibonacci index="9">34</fibonacci>
+  <fibonacci index="10">55</fibonacci>
+  <fibonacci index="11">89</fibonacci>
+  <fibonacci index="12">144</fibonacci>
+  <fibonacci index="13">233</fibonacci>
+  <fibonacci index="14">377</fibonacci>
+  <fibonacci index="15">610</fibonacci>
+  <fibonacci index="16">987</fibonacci>
+  <fibonacci index="17">1597</fibonacci>
+  <fibonacci index="18">2584</fibonacci>
+  <fibonacci index="19">4181</fibonacci>
+  <fibonacci index="20">6765</fibonacci>
+  <fibonacci index="21">10946</fibonacci>
+  <fibonacci index="22">17711</fibonacci>
+  <fibonacci index="23">28657</fibonacci>
+  <fibonacci index="24">46368</fibonacci>
+  <fibonacci index="25">75025</fibonacci>
+</Fibonacci_Numbers>
diff --git a/libjaxen-java/xml/id.xml b/libjaxen-java/xml/id.xml
new file mode 100644
index 0000000..749ab20
--- /dev/null
+++ b/libjaxen-java/xml/id.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0"?>
+
+<!DOCTYPE foo [
+
+<!ELEMENT foo (bar)>
+<!ATTLIST foo id CDATA #IMPLIED>
+<!ELEMENT bar (#PCDATA|cheese)*>
+<!ATTLIST bar id ID #REQUIRED>
+<!ELEMENT cheese (#PCDATA)>
+<!ATTLIST cheese kind ID #IMPLIED>
+]>
+
+<foo id="foobar">
+  <bar id="fb1">
+    baz
+    <cheese kind="edam">gouda</cheese>
+    baz
+    <cheese kind="gouda">cheddar</cheese>
+    baz
+  </bar>
+</foo>
diff --git a/libjaxen-java/xml/jaxen24.xml b/libjaxen-java/xml/jaxen24.xml
new file mode 100644
index 0000000..9b81996
--- /dev/null
+++ b/libjaxen-java/xml/jaxen24.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<body><p><span></span></p><div></div></body> 
diff --git a/libjaxen-java/xml/jaxen3.xml b/libjaxen-java/xml/jaxen3.xml
new file mode 100644
index 0000000..a87723a
--- /dev/null
+++ b/libjaxen-java/xml/jaxen3.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Configuration>
+    <hostname>
+        <val>2</val>
+        <attrlist>
+            <hostname>CE-A</hostname>
+        </attrlist>
+    </hostname>
+    <hostname>
+        <val>1</val>
+        <attrlist>
+            <hostname>CE-B</hostname>
+        </attrlist>
+    </hostname>
+</Configuration>
diff --git a/libjaxen-java/xml/lang.xml b/libjaxen-java/xml/lang.xml
new file mode 100644
index 0000000..49b45db
--- /dev/null
+++ b/libjaxen-java/xml/lang.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0"?>
+<e1 xml:lang="hr">
+  <e2 xml:lang="en-US">
+    <e3/>
+  </e2>
+  <e2 xml:lang="hu">
+    <e3/>
+    <e3/>
+    <e3 xml:lang="es"/>
+  </e2>
+</e1>
\ No newline at end of file
diff --git a/libjaxen-java/xml/message.xml b/libjaxen-java/xml/message.xml
new file mode 100644
index 0000000..3b81df2
--- /dev/null
+++ b/libjaxen-java/xml/message.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<message>
+  <header>
+    <service>lookupformservice</service>
+    <connectionid>9</connectionid>
+    <appid>stammdaten</appid>
+    <action>new</action>
+  </header>
+  <body>
+    <data>
+      <items>
+        <item>
+          <name>iteminfo</name>
+          <value>ELE</value>
+        </item>
+        <item>
+          <name>parentinfo</name>
+          <value>Pruefgebiete</value>
+        </item>
+        <item>
+          <name>id</name>
+          <value>1</value>
+        </item>
+      </items>
+    </data>
+  </body>
+</message>
diff --git a/libjaxen-java/xml/moreover.xml b/libjaxen-java/xml/moreover.xml
new file mode 100644
index 0000000..38d4c4f
--- /dev/null
+++ b/libjaxen-java/xml/moreover.xml
@@ -0,0 +1,244 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+   <moreovernews>
+      <article code="13563275">
+         <url>http://c.moreover.com/click/here.pl?x13563273</url>
+         <headline_text>e-Commerce Operators Present Version 1.0 of the XML Standard</headline_text>
+         <source>StockAccess</source>
+         <media_type>text</media_type>
+         <cluster>moreover...</cluster>
+         <tagline> </tagline>
+         <document_url>http://www.stockaccess.com/index.html</document_url>
+         <harvest_time>Dec 24 2000  6:28AM</harvest_time>
+         <access_registration> </access_registration>
+         <access_status> </access_status>
+      </article>
+      <article code="13560996">
+         <url>http://c.moreover.com/click/here.pl?x13560995</url>
+         <headline_text>W3C Publishes XML Protocol Requirements Document</headline_text>
+         <source>Xml</source>
+         <media_type>text</media_type>
+         <cluster>moreover...</cluster>
+         <tagline> </tagline>
+         <document_url>http://www.xml.com/</document_url>
+         <harvest_time>Dec 24 2000 12:22AM</harvest_time>
+         <access_registration> </access_registration>
+         <access_status> </access_status>
+      </article>
+      <article code="13553522">
+         <url>http://c.moreover.com/click/here.pl?x13553521</url>
+         <headline_text>Prowler: Open Source XML-Based Content Management Framework</headline_text>
+         <source>Xml</source>
+         <media_type>text</media_type>
+         <cluster>moreover...</cluster>
+         <tagline> </tagline>
+         <document_url>http://www.xml.com/</document_url>
+         <harvest_time>Dec 23 2000  2:05PM</harvest_time>
+         <access_registration> </access_registration>
+         <access_status> </access_status>
+      </article>
+      <article code="13549014">
+         <url>http://c.moreover.com/click/here.pl?x13549013</url>
+         <headline_text>The Middleware Company Debuts Public Training Courses in Ejb, J2ee And Xml</headline_text>
+         <source>Java Industry Connection</source>
+         <media_type>text</media_type>
+         <cluster>moreover...</cluster>
+         <tagline> </tagline>
+         <document_url>http://industry.java.sun.com/javanews/more/hotnews/</document_url>
+         <harvest_time>Dec 23 2000 12:15PM</harvest_time>
+         <access_registration> </access_registration>
+         <access_status> </access_status>
+      </article>
+      <article code="13544468">
+         <url>http://c.moreover.com/click/here.pl?x13544467</url>
+         <headline_text>Revised Working Draft for the W3C XML Information Set</headline_text>
+         <source>Xml</source>
+         <media_type>text</media_type>
+         <cluster>moreover...</cluster>
+         <tagline> </tagline>
+         <document_url>http://www.xml.com/</document_url>
+         <harvest_time>Dec 23 2000  5:50AM</harvest_time>
+         <access_registration> </access_registration>
+         <access_status> </access_status>
+      </article>
+      <article code="13534837">
+         <url>http://c.moreover.com/click/here.pl?x13534836</url>
+         <headline_text>XML: Its The Great Peacemaker</headline_text>
+         <source>ZDNet</source>
+         <media_type>text</media_type>
+         <cluster>moreover...</cluster>
+         <tagline> </tagline>
+         <document_url>http://www.zdnet.com/intweek/</document_url>
+         <harvest_time>Dec 22 2000  9:05PM</harvest_time>
+         <access_registration> </access_registration>
+         <access_status> </access_status>
+      </article>
+      <article code="13533486">
+         <url>http://c.moreover.com/click/here.pl?x13533485</url>
+         <headline_text>Project eL - The XML Leningrad Codex Markup Project</headline_text>
+         <source>Xml</source>
+         <media_type>text</media_type>
+         <cluster>moreover...</cluster>
+         <tagline> </tagline>
+         <document_url>http://www.xml.com/</document_url>
+         <harvest_time>Dec 22 2000  8:34PM</harvest_time>
+         <access_registration> </access_registration>
+         <access_status> </access_status>
+      </article>
+      <article code="13533489">
+         <url>http://c.moreover.com/click/here.pl?x13533488</url>
+         <headline_text>XML Linking Language (XLink) and XML Base Specifications Issued as W3C Proposed Recommenda</headline_text>
+         <source>Xml</source>
+         <media_type>text</media_type>
+         <cluster>moreover...</cluster>
+         <tagline> </tagline>
+         <document_url>http://www.xml.com/</document_url>
+         <harvest_time>Dec 22 2000  8:34PM</harvest_time>
+         <access_registration> </access_registration>
+         <access_status> </access_status>
+      </article>
+      <article code="13533493">
+         <url>http://c.moreover.com/click/here.pl?x13533492</url>
+         <headline_text>W3C Releases XHTML Basic Specification as a W3C Recommendation</headline_text>
+         <source>Xml</source>
+         <media_type>text</media_type>
+         <cluster>moreover...</cluster>
+         <tagline> </tagline>
+         <document_url>http://www.xml.com/</document_url>
+         <harvest_time>Dec 22 2000  8:34PM</harvest_time>
+         <access_registration> </access_registration>
+         <access_status> </access_status>
+      </article>
+      <article code="13521835">
+         <url>http://c.moreover.com/click/here.pl?x13521827</url>
+         <headline_text>Java, Xml And Oracle9i(TM) Make A Great Team</headline_text>
+         <source>Java Industry Connection</source>
+         <media_type>text</media_type>
+         <cluster>moreover...</cluster>
+         <tagline> </tagline>
+         <document_url>http://industry.java.sun.com/javanews/more/hotnews/</document_url>
+         <harvest_time>Dec 22 2000  3:21PM</harvest_time>
+         <access_registration> </access_registration>
+         <access_status> </access_status>
+      </article>
+      <article code="13512020">
+         <url>http://c.moreover.com/click/here.pl?x13511233</url>
+         <headline_text>Competing initiatives to vie for security standard</headline_text>
+         <source>ZDNet</source>
+         <media_type>text</media_type>
+         <cluster>moreover...</cluster>
+         <tagline> </tagline>
+         <document_url>http://www.zdnet.com/eweek/filters/news/</document_url>
+         <harvest_time>Dec 22 2000 10:54AM</harvest_time>
+         <access_registration> </access_registration>
+         <access_status> </access_status>
+      </article>
+      <article code="13492401">
+         <url>http://c.moreover.com/click/here.pl?x13492397</url>
+         <headline_text>Oracle Provides Developers with Great Xml Reading This Holiday Season</headline_text>
+         <source>Java Industry Connection</source>
+         <media_type>text</media_type>
+         <cluster>moreover...</cluster>
+         <tagline> </tagline>
+         <document_url>http://industry.java.sun.com/javanews/more/hotnews/</document_url>
+         <harvest_time>Dec 21 2000  8:08PM</harvest_time>
+         <access_registration> </access_registration>
+         <access_status> </access_status>
+      </article>
+      <article code="13491296">
+         <url>http://c.moreover.com/click/here.pl?x13491292</url>
+         <headline_text>XML as the great peacemaker - Extensible Markup Language Accomplished The Seemingly Impossible This Year: It B</headline_text>
+         <source>Hospitality Net</source>
+         <media_type>text</media_type>
+         <cluster>moreover...</cluster>
+         <tagline> </tagline>
+         <document_url>http://www.hospitalitynet.org/news/list.htm?c=2000</document_url>
+         <harvest_time>Dec 21 2000  7:45PM</harvest_time>
+         <access_registration> </access_registration>
+         <access_status> </access_status>
+      </article>
+      <article code="13484761">
+         <url>http://c.moreover.com/click/here.pl?x13484758</url>
+         <headline_text>XML as the great peacemaker</headline_text>
+         <source>CNET</source>
+         <media_type>text</media_type>
+         <cluster>moreover...</cluster>
+         <tagline> </tagline>
+         <document_url>http://news.cnet.com/news/0-1003.html?tag=st.ne.1002.dir.1003</document_url>
+         <harvest_time>Dec 21 2000  4:41PM</harvest_time>
+         <access_registration> </access_registration>
+         <access_status> </access_status>
+      </article>
+      <article code="13480897">
+         <url>http://c.moreover.com/click/here.pl?x13480896</url>
+         <headline_text>COOP Switzerland Selects Mercator as Integration Platform</headline_text>
+         <source>Stockhouse Canada</source>
+         <media_type>text</media_type>
+         <cluster>moreover...</cluster>
+         <tagline> </tagline>
+         <document_url>http://www.stockhouse.ca/news/</document_url>
+         <harvest_time>Dec 21 2000  1:55PM</harvest_time>
+         <access_registration> </access_registration>
+         <access_status> </access_status>
+      </article>
+      <article code="13471024">
+         <url>http://c.moreover.com/click/here.pl?x13471023</url>
+         <headline_text>Competing XML Specs Move Toward a Union</headline_text>
+         <source>Internet World</source>
+         <media_type>text</media_type>
+         <cluster>moreover...</cluster>
+         <tagline> </tagline>
+         <document_url>http://www.internetworld.com/</document_url>
+         <harvest_time>Dec 21 2000 11:14AM</harvest_time>
+         <access_registration> </access_registration>
+         <access_status> </access_status>
+      </article>
+      <article code="13452281">
+         <url>http://c.moreover.com/click/here.pl?x13452280</url>
+         <headline_text>Next-generation XHTML stripped down for handhelds</headline_text>
+         <source>CNET</source>
+         <media_type>text</media_type>
+         <cluster>moreover...</cluster>
+         <tagline> </tagline>
+         <document_url>http://news.cnet.com/news/0-1005.html?tag=st.ne.1002.dir.1005</document_url>
+         <harvest_time>Dec 20 2000  9:11PM</harvest_time>
+         <access_registration> </access_registration>
+         <access_status> </access_status>
+      </article>
+      <article code="13451791">
+         <url>http://c.moreover.com/click/here.pl?x13451789</url>
+         <headline_text>Xml Powers Oracle9i(TM) Dynamic Services</headline_text>
+         <source>Java Industry Connection</source>
+         <media_type>text</media_type>
+         <cluster>moreover...</cluster>
+         <tagline> </tagline>
+         <document_url>http://industry.java.sun.com/javanews/more/hotnews/</document_url>
+         <harvest_time>Dec 20 2000  9:05PM</harvest_time>
+         <access_registration> </access_registration>
+         <access_status> </access_status>
+      </article>
+      <article code="13442098">
+         <url>http://c.moreover.com/click/here.pl?x13442097</url>
+         <headline_text>XML DOM reference guide</headline_text>
+         <source>ASPWire</source>
+         <media_type>text</media_type>
+         <cluster>moreover...</cluster>
+         <tagline> </tagline>
+         <document_url>http://aspwire.com/</document_url>
+         <harvest_time>Dec 20 2000  6:26PM</harvest_time>
+         <access_registration> </access_registration>
+         <access_status> </access_status>
+      </article>
+      <article code="13424118">
+         <url>http://c.moreover.com/click/here.pl?x13424117</url>
+         <headline_text>Repeat/Xqsite And Bowstreet Team to Deliver Integrated Xml Solutions</headline_text>
+         <source>Java Industry Connection</source>
+         <media_type>text</media_type>
+         <cluster>moreover...</cluster>
+         <tagline> </tagline>
+         <document_url>http://industry.java.sun.com/javanews/more/hotnews/</document_url>
+         <harvest_time>Dec 20 2000  9:04AM</harvest_time>
+         <access_registration> </access_registration>
+         <access_status> </access_status>
+      </article>
+    </moreovernews>
+
diff --git a/libjaxen-java/xml/much_ado.xml b/libjaxen-java/xml/much_ado.xml
new file mode 100644
index 0000000..f008fad
--- /dev/null
+++ b/libjaxen-java/xml/much_ado.xml
@@ -0,0 +1,6850 @@
+<?xml version="1.0"?>
+<PLAY>
+<TITLE>Much Ado about Nothing</TITLE>
+
+<FM>
+<P>Text placed in the public domain by Moby Lexical Tools, 1992.</P>
+<P>SGML markup by Jon Bosak, 1992-1994.</P>
+<P>XML version by Jon Bosak, 1996-1998.</P>
+<P>This work may be freely copied and distributed worldwide.</P>
+</FM>
+
+
+<PERSONAE>
+<TITLE>Dramatis Personae</TITLE>
+
+<PERSONA>DON PEDRO, prince of Arragon.</PERSONA>
+<PERSONA>DON JOHN, his bastard brother.</PERSONA>
+<PERSONA>CLAUDIO, a young lord of Florence.</PERSONA>
+<PERSONA>BENEDICK, a young lord of Padua.</PERSONA>
+<PERSONA>LEONATO, governor of Messina.</PERSONA>
+<PERSONA>ANTONIO, his brother.</PERSONA>
+<PERSONA>BALTHASAR, attendant on Don Pedro.</PERSONA>
+
+<PGROUP>
+<PERSONA>CONRADE</PERSONA>
+<PERSONA>BORACHIO</PERSONA>
+<GRPDESCR>followers of Don John.</GRPDESCR>
+</PGROUP>
+
+<PERSONA>FRIAR FRANCIS</PERSONA>
+<PERSONA>DOGBERRY, a constable.</PERSONA>
+<PERSONA>VERGES, a headborough.</PERSONA>
+<PERSONA>A Sexton.</PERSONA>
+<PERSONA>A Boy.</PERSONA>
+<PERSONA>HERO, daughter to Leonato.</PERSONA>
+<PERSONA>BEATRICE, niece to Leonato.</PERSONA>
+
+<PGROUP>
+<PERSONA>MARGARET</PERSONA>
+<PERSONA>URSULA</PERSONA>
+<GRPDESCR>gentlewomen attending on Hero.</GRPDESCR>
+</PGROUP>
+
+<PERSONA>Messengers, Watch, Attendants, &c. </PERSONA>
+</PERSONAE>
+
+<SCNDESCR>SCENE  Messina.</SCNDESCR>
+
+<PLAYSUBT>MUCH ADO ABOUT NOTHING</PLAYSUBT>
+
+<ACT><TITLE>ACT I</TITLE>
+
+<SCENE><TITLE>SCENE I.  Before LEONATO'S house.</TITLE>
+<STAGEDIR>Enter LEONATO, HERO, and BEATRICE, with a
+Messenger</STAGEDIR>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>I learn in this letter that Don Peter of Arragon</LINE>
+<LINE>comes this night to Messina.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>Messenger</SPEAKER>
+<LINE>He is very near by this: he was not three leagues off</LINE>
+<LINE>when I left him.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>How many gentlemen have you lost in this action?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>Messenger</SPEAKER>
+<LINE>But few of any sort, and none of name.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>A victory is twice itself when the achiever brings</LINE>
+<LINE>home full numbers. I find here that Don Peter hath</LINE>
+<LINE>bestowed much honour on a young Florentine called Claudio.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>Messenger</SPEAKER>
+<LINE>Much deserved on his part and equally remembered by</LINE>
+<LINE>Don Pedro: he hath borne himself beyond the</LINE>
+<LINE>promise of his age, doing, in the figure of a lamb,</LINE>
+<LINE>the feats of a lion: he hath indeed better</LINE>
+<LINE>bettered expectation than you must expect of me to</LINE>
+<LINE>tell you how.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>He hath an uncle here in Messina will be very much</LINE>
+<LINE>glad of it.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>Messenger</SPEAKER>
+<LINE>I have already delivered him letters, and there</LINE>
+<LINE>appears much joy in him; even so much that joy could</LINE>
+<LINE>not show itself modest enough without a badge of</LINE>
+<LINE>bitterness.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>Did he break out into tears?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>Messenger</SPEAKER>
+<LINE>In great measure.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>A kind overflow of kindness: there are no faces</LINE>
+<LINE>truer than those that are so washed. How much</LINE>
+<LINE>better is it to weep at joy than to joy at weeping!</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>I pray you, is Signior Mountanto returned from the</LINE>
+<LINE>wars or no?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>Messenger</SPEAKER>
+<LINE>I know none of that name, lady: there was none such</LINE>
+<LINE>in the army of any sort.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>What is he that you ask for, niece?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>HERO</SPEAKER>
+<LINE>My cousin means Signior Benedick of Padua.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>Messenger</SPEAKER>
+<LINE>O, he's returned; and as pleasant as ever he was.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>He set up his bills here in Messina and challenged</LINE>
+<LINE>Cupid at the flight; and my uncle's fool, reading</LINE>
+<LINE>the challenge, subscribed for Cupid, and challenged</LINE>
+<LINE>him at the bird-bolt. I pray you, how many hath he</LINE>
+<LINE>killed and eaten in these wars? But how many hath</LINE>
+<LINE>he killed? for indeed I promised to eat all of his killing.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>Faith, niece, you tax Signior Benedick too much;</LINE>
+<LINE>but he'll be meet with you, I doubt it not.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>Messenger</SPEAKER>
+<LINE>He hath done good service, lady, in these wars.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>You had musty victual, and he hath holp to eat it:</LINE>
+<LINE>he is a very valiant trencherman; he hath an</LINE>
+<LINE>excellent stomach.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>Messenger</SPEAKER>
+<LINE>And a good soldier too, lady.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>And a good soldier to a lady: but what is he to a lord?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>Messenger</SPEAKER>
+<LINE>A lord to a lord, a man to a man; stuffed with all</LINE>
+<LINE>honourable virtues.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>It is so, indeed; he is no less than a stuffed man:</LINE>
+<LINE>but for the stuffing,--well, we are all mortal.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>You must not, sir, mistake my niece. There is a</LINE>
+<LINE>kind of merry war betwixt Signior Benedick and her:</LINE>
+<LINE>they never meet but there's a skirmish of wit</LINE>
+<LINE>between them.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>Alas! he gets nothing by that. In our last</LINE>
+<LINE>conflict four of his five wits went halting off, and</LINE>
+<LINE>now is the whole man governed with one: so that if</LINE>
+<LINE>he have wit enough to keep himself warm, let him</LINE>
+<LINE>bear it for a difference between himself and his</LINE>
+<LINE>horse; for it is all the wealth that he hath left,</LINE>
+<LINE>to be known a reasonable creature. Who is his</LINE>
+<LINE>companion now? He hath every month a new sworn brother.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>Messenger</SPEAKER>
+<LINE>Is't possible?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>Very easily possible: he wears his faith but as</LINE>
+<LINE>the fashion of his hat; it ever changes with the</LINE>
+<LINE>next block.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>Messenger</SPEAKER>
+<LINE>I see, lady, the gentleman is not in your books.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>No; an he were, I would burn my study. But, I pray</LINE>
+<LINE>you, who is his companion? Is there no young</LINE>
+<LINE>squarer now that will make a voyage with him to the devil?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>Messenger</SPEAKER>
+<LINE>He is most in the company of the right noble Claudio.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>O Lord, he will hang upon him like a disease: he</LINE>
+<LINE>is sooner caught than the pestilence, and the taker</LINE>
+<LINE>runs presently mad. God help the noble Claudio! if</LINE>
+<LINE>he have caught the Benedick, it will cost him a</LINE>
+<LINE>thousand pound ere a' be cured.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>Messenger</SPEAKER>
+<LINE>I will hold friends with you, lady.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>Do, good friend.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>You will never run mad, niece.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>No, not till a hot January.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>Messenger</SPEAKER>
+<LINE>Don Pedro is approached.</LINE>
+</SPEECH>
+
+
+<STAGEDIR>Enter DON PEDRO, DON JOHN, CLAUDIO, BENEDICK,
+and BALTHASAR</STAGEDIR>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>Good Signior Leonato, you are come to meet your</LINE>
+<LINE>trouble: the fashion of the world is to avoid</LINE>
+<LINE>cost, and you encounter it.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>Never came trouble to my house in the likeness of</LINE>
+<LINE>your grace: for trouble being gone, comfort should</LINE>
+<LINE>remain; but when you depart from me, sorrow abides</LINE>
+<LINE>and happiness takes his leave.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>You embrace your charge too willingly. I think this</LINE>
+<LINE>is your daughter.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>Her mother hath many times told me so.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>Were you in doubt, sir, that you asked her?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>Signior Benedick, no; for then were you a child.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>You have it full, Benedick: we may guess by this</LINE>
+<LINE>what you are, being a man. Truly, the lady fathers</LINE>
+<LINE>herself. Be happy, lady; for you are like an</LINE>
+<LINE>honourable father.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>If Signior Leonato be her father, she would not</LINE>
+<LINE>have his head on her shoulders for all Messina, as</LINE>
+<LINE>like him as she is.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>I wonder that you will still be talking, Signior</LINE>
+<LINE>Benedick: nobody marks you.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>What, my dear Lady Disdain! are you yet living?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>Is it possible disdain should die while she hath</LINE>
+<LINE>such meet food to feed it as Signior Benedick?</LINE>
+<LINE>Courtesy itself must convert to disdain, if you come</LINE>
+<LINE>in her presence.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>Then is courtesy a turncoat. But it is certain I</LINE>
+<LINE>am loved of all ladies, only you excepted: and I</LINE>
+<LINE>would I could find in my heart that I had not a hard</LINE>
+<LINE>heart; for, truly, I love none.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>A dear happiness to women: they would else have</LINE>
+<LINE>been troubled with a pernicious suitor. I thank God</LINE>
+<LINE>and my cold blood, I am of your humour for that: I</LINE>
+<LINE>had rather hear my dog bark at a crow than a man</LINE>
+<LINE>swear he loves me.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>God keep your ladyship still in that mind! so some</LINE>
+<LINE>gentleman or other shall 'scape a predestinate</LINE>
+<LINE>scratched face.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>Scratching could not make it worse, an 'twere such</LINE>
+<LINE>a face as yours were.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>Well, you are a rare parrot-teacher.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>A bird of my tongue is better than a beast of yours.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>I would my horse had the speed of your tongue, and</LINE>
+<LINE>so good a continuer. But keep your way, i' God's</LINE>
+<LINE>name; I have done.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>You always end with a jade's trick: I know you of old.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>That is the sum of all, Leonato. Signior Claudio</LINE>
+<LINE>and Signior Benedick, my dear friend Leonato hath</LINE>
+<LINE>invited you all. I tell him we shall stay here at</LINE>
+<LINE>the least a month; and he heartily prays some</LINE>
+<LINE>occasion may detain us longer. I dare swear he is no</LINE>
+<LINE>hypocrite, but prays from his heart.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>If you swear, my lord, you shall not be forsworn.</LINE>
+<STAGEDIR>To DON JOHN</STAGEDIR>
+<LINE>Let me bid you welcome, my lord: being reconciled to</LINE>
+<LINE>the prince your brother, I owe you all duty.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON JOHN</SPEAKER>
+<LINE>I thank you: I am not of many words, but I thank</LINE>
+<LINE>you.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>Please it your grace lead on?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>Your hand, Leonato; we will go together.</LINE>
+</SPEECH>
+
+
+<STAGEDIR>Exeunt all except BENEDICK and CLAUDIO</STAGEDIR>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>Benedick, didst thou note the daughter of Signior Leonato?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>I noted her not; but I looked on her.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>Is she not a modest young lady?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>Do you question me, as an honest man should do, for</LINE>
+<LINE>my simple true judgment; or would you have me speak</LINE>
+<LINE>after my custom, as being a professed tyrant to their sex?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>No; I pray thee speak in sober judgment.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>Why, i' faith, methinks she's too low for a high</LINE>
+<LINE>praise, too brown for a fair praise and too little</LINE>
+<LINE>for a great praise: only this commendation I can</LINE>
+<LINE>afford her, that were she other than she is, she</LINE>
+<LINE>were unhandsome; and being no other but as she is, I</LINE>
+<LINE>do not like her.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>Thou thinkest I am in sport: I pray thee tell me</LINE>
+<LINE>truly how thou likest her.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>Would you buy her, that you inquire after her?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>Can the world buy such a jewel?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>Yea, and a case to put it into. But speak you this</LINE>
+<LINE>with a sad brow? or do you play the flouting Jack,</LINE>
+<LINE>to tell us Cupid is a good hare-finder and Vulcan a</LINE>
+<LINE>rare carpenter? Come, in what key shall a man take</LINE>
+<LINE>you, to go in the song?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>In mine eye she is the sweetest lady that ever I</LINE>
+<LINE>looked on.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>I can see yet without spectacles and I see no such</LINE>
+<LINE>matter: there's her cousin, an she were not</LINE>
+<LINE>possessed with a fury, exceeds her as much in beauty</LINE>
+<LINE>as the first of May doth the last of December. But I</LINE>
+<LINE>hope you have no intent to turn husband, have you?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>I would scarce trust myself, though I had sworn the</LINE>
+<LINE>contrary, if Hero would be my wife.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>Is't come to this? In faith, hath not the world</LINE>
+<LINE>one man but he will wear his cap with suspicion?</LINE>
+<LINE>Shall I never see a bachelor of three-score again?</LINE>
+<LINE>Go to, i' faith; an thou wilt needs thrust thy neck</LINE>
+<LINE>into a yoke, wear the print of it and sigh away</LINE>
+<LINE>Sundays. Look Don Pedro is returned to seek you.</LINE>
+</SPEECH>
+
+
+<STAGEDIR>Re-enter DON PEDRO</STAGEDIR>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>What secret hath held you here, that you followed</LINE>
+<LINE>not to Leonato's?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>I would your grace would constrain me to tell.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>I charge thee on thy allegiance.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>You hear, Count Claudio: I can be secret as a dumb</LINE>
+<LINE>man; I would have you think so; but, on my</LINE>
+<LINE>allegiance, mark you this, on my allegiance. He is</LINE>
+<LINE>in love. With who? now that is your grace's part.</LINE>
+<LINE>Mark how short his answer is;--With Hero, Leonato's</LINE>
+<LINE>short daughter.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>If this were so, so were it uttered.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>Like the old tale, my lord: 'it is not so, nor</LINE>
+<LINE>'twas not so, but, indeed, God forbid it should be</LINE>
+<LINE>so.'</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>If my passion change not shortly, God forbid it</LINE>
+<LINE>should be otherwise.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>Amen, if you love her; for the lady is very well worthy.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>You speak this to fetch me in, my lord.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>By my troth, I speak my thought.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>And, in faith, my lord, I spoke mine.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>And, by my two faiths and troths, my lord, I spoke mine.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>That I love her, I feel.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>That she is worthy, I know.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>That I neither feel how she should be loved nor</LINE>
+<LINE>know how she should be worthy, is the opinion that</LINE>
+<LINE>fire cannot melt out of me: I will die in it at the stake.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>Thou wast ever an obstinate heretic in the despite</LINE>
+<LINE>of beauty.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>And never could maintain his part but in the force</LINE>
+<LINE>of his will.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>That a woman conceived me, I thank her; that she</LINE>
+<LINE>brought me up, I likewise give her most humble</LINE>
+<LINE>thanks: but that I will have a recheat winded in my</LINE>
+<LINE>forehead, or hang my bugle in an invisible baldrick,</LINE>
+<LINE>all women shall pardon me. Because I will not do</LINE>
+<LINE>them the wrong to mistrust any, I will do myself the</LINE>
+<LINE>right to trust none; and the fine is, for the which</LINE>
+<LINE>I may go the finer, I will live a bachelor.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>I shall see thee, ere I die, look pale with love.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>With anger, with sickness, or with hunger, my lord,</LINE>
+<LINE>not with love: prove that ever I lose more blood</LINE>
+<LINE>with love than I will get again with drinking, pick</LINE>
+<LINE>out mine eyes with a ballad-maker's pen and hang me</LINE>
+<LINE>up at the door of a brothel-house for the sign of</LINE>
+<LINE>blind Cupid.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>Well, if ever thou dost fall from this faith, thou</LINE>
+<LINE>wilt prove a notable argument.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>If I do, hang me in a bottle like a cat and shoot</LINE>
+<LINE>at me; and he that hits me, let him be clapped on</LINE>
+<LINE>the shoulder, and called Adam.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>Well, as time shall try: 'In time the savage bull</LINE>
+<LINE>doth bear the yoke.'</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>The savage bull may; but if ever the sensible</LINE>
+<LINE>Benedick bear it, pluck off the bull's horns and set</LINE>
+<LINE>them in my forehead: and let me be vilely painted,</LINE>
+<LINE>and in such great letters as they write 'Here is</LINE>
+<LINE>good horse to hire,' let them signify under my sign</LINE>
+<LINE>'Here you may see Benedick the married man.'</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>If this should ever happen, thou wouldst be horn-mad.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>Nay, if Cupid have not spent all his quiver in</LINE>
+<LINE>Venice, thou wilt quake for this shortly.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>I look for an earthquake too, then.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>Well, you temporize with the hours. In the</LINE>
+<LINE>meantime, good Signior Benedick, repair to</LINE>
+<LINE>Leonato's: commend me to him and tell him I will</LINE>
+<LINE>not fail him at supper; for indeed he hath made</LINE>
+<LINE>great preparation.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>I have almost matter enough in me for such an</LINE>
+<LINE>embassage; and so I commit you--</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>To the tuition of God: From my house, if I had it,--</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>The sixth of July: Your loving friend, Benedick.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>Nay, mock not, mock not. The body of your</LINE>
+<LINE>discourse is sometime guarded with fragments, and</LINE>
+<LINE>the guards are but slightly basted on neither: ere</LINE>
+<LINE>you flout old ends any further, examine your</LINE>
+<LINE>conscience: and so I leave you.</LINE>
+</SPEECH>
+
+
+<STAGEDIR>Exit</STAGEDIR>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>My liege, your highness now may do me good.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>My love is thine to teach: teach it but how,</LINE>
+<LINE>And thou shalt see how apt it is to learn</LINE>
+<LINE>Any hard lesson that may do thee good.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>Hath Leonato any son, my lord?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>No child but Hero; she's his only heir.</LINE>
+<LINE>Dost thou affect her, Claudio?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>O, my lord,</LINE>
+<LINE>When you went onward on this ended action,</LINE>
+<LINE>I look'd upon her with a soldier's eye,</LINE>
+<LINE>That liked, but had a rougher task in hand</LINE>
+<LINE>Than to drive liking to the name of love:</LINE>
+<LINE>But now I am return'd and that war-thoughts</LINE>
+<LINE>Have left their places vacant, in their rooms</LINE>
+<LINE>Come thronging soft and delicate desires,</LINE>
+<LINE>All prompting me how fair young Hero is,</LINE>
+<LINE>Saying, I liked her ere I went to wars.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>Thou wilt be like a lover presently</LINE>
+<LINE>And tire the hearer with a book of words.</LINE>
+<LINE>If thou dost love fair Hero, cherish it,</LINE>
+<LINE>And I will break with her and with her father,</LINE>
+<LINE>And thou shalt have her. Was't not to this end</LINE>
+<LINE>That thou began'st to twist so fine a story?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>How sweetly you do minister to love,</LINE>
+<LINE>That know love's grief by his complexion!</LINE>
+<LINE>But lest my liking might too sudden seem,</LINE>
+<LINE>I would have salved it with a longer treatise.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>What need the bridge much broader than the flood?</LINE>
+<LINE>The fairest grant is the necessity.</LINE>
+<LINE>Look, what will serve is fit: 'tis once, thou lovest,</LINE>
+<LINE>And I will fit thee with the remedy.</LINE>
+<LINE>I know we shall have revelling to-night:</LINE>
+<LINE>I will assume thy part in some disguise</LINE>
+<LINE>And tell fair Hero I am Claudio,</LINE>
+<LINE>And in her bosom I'll unclasp my heart</LINE>
+<LINE>And take her hearing prisoner with the force</LINE>
+<LINE>And strong encounter of my amorous tale:</LINE>
+<LINE>Then after to her father will I break;</LINE>
+<LINE>And the conclusion is, she shall be thine.</LINE>
+<LINE>In practise let us put it presently.</LINE>
+</SPEECH>
+
+
+<STAGEDIR>Exeunt</STAGEDIR>
+</SCENE>
+
+<SCENE><TITLE>SCENE II.  A room in LEONATO's house.</TITLE>
+<STAGEDIR>Enter LEONATO and ANTONIO, meeting</STAGEDIR>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>How now, brother! Where is my cousin, your son?</LINE>
+<LINE>hath he provided this music?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>ANTONIO</SPEAKER>
+<LINE>He is very busy about it. But, brother, I can tell</LINE>
+<LINE>you strange news that you yet dreamt not of.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>Are they good?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>ANTONIO</SPEAKER>
+<LINE>As the event stamps them: but they have a good</LINE>
+<LINE>cover; they show well outward. The prince and Count</LINE>
+<LINE>Claudio, walking in a thick-pleached alley in mine</LINE>
+<LINE>orchard, were thus much overheard by a man of mine:</LINE>
+<LINE>the prince discovered to Claudio that he loved my</LINE>
+<LINE>niece your daughter and meant to acknowledge it</LINE>
+<LINE>this night in a dance: and if he found her</LINE>
+<LINE>accordant, he meant to take the present time by the</LINE>
+<LINE>top and instantly break with you of it.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>Hath the fellow any wit that told you this?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>ANTONIO</SPEAKER>
+<LINE>A good sharp fellow: I will send for him; and</LINE>
+<LINE>question him yourself.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>No, no; we will hold it as a dream till it appear</LINE>
+<LINE>itself: but I will acquaint my daughter withal,</LINE>
+<LINE>that she may be the better prepared for an answer,</LINE>
+<LINE>if peradventure this be true. Go you and tell her of it.</LINE>
+<STAGEDIR>Enter Attendants</STAGEDIR>
+<LINE>Cousins, you know what you have to do. O, I cry you</LINE>
+<LINE>mercy, friend; go you with me, and I will use your</LINE>
+<LINE>skill. Good cousin, have a care this busy time.</LINE>
+</SPEECH>
+
+
+<STAGEDIR>Exeunt</STAGEDIR>
+</SCENE>
+
+<SCENE><TITLE>SCENE III.  The same.</TITLE>
+<STAGEDIR>Enter DON JOHN and CONRADE</STAGEDIR>
+
+<SPEECH>
+<SPEAKER>CONRADE</SPEAKER>
+<LINE>What the good-year, my lord! why are you thus out</LINE>
+<LINE>of measure sad?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON JOHN</SPEAKER>
+<LINE>There is no measure in the occasion that breeds;</LINE>
+<LINE>therefore the sadness is without limit.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CONRADE</SPEAKER>
+<LINE>You should hear reason.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON JOHN</SPEAKER>
+<LINE>And when I have heard it, what blessing brings it?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CONRADE</SPEAKER>
+<LINE>If not a present remedy, at least a patient</LINE>
+<LINE>sufferance.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON JOHN</SPEAKER>
+<LINE>I wonder that thou, being, as thou sayest thou art,</LINE>
+<LINE>born under Saturn, goest about to apply a moral</LINE>
+<LINE>medicine to a mortifying mischief. I cannot hide</LINE>
+<LINE>what I am: I must be sad when I have cause and smile</LINE>
+<LINE>at no man's jests, eat when I have stomach and wait</LINE>
+<LINE>for no man's leisure, sleep when I am drowsy and</LINE>
+<LINE>tend on no man's business, laugh when I am merry and</LINE>
+<LINE>claw no man in his humour.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CONRADE</SPEAKER>
+<LINE>Yea, but you must not make the full show of this</LINE>
+<LINE>till you may do it without controlment. You have of</LINE>
+<LINE>late stood out against your brother, and he hath</LINE>
+<LINE>ta'en you newly into his grace; where it is</LINE>
+<LINE>impossible you should take true root but by the</LINE>
+<LINE>fair weather that you make yourself: it is needful</LINE>
+<LINE>that you frame the season for your own harvest.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON JOHN</SPEAKER>
+<LINE>I had rather be a canker in a hedge than a rose in</LINE>
+<LINE>his grace, and it better fits my blood to be</LINE>
+<LINE>disdained of all than to fashion a carriage to rob</LINE>
+<LINE>love from any: in this, though I cannot be said to</LINE>
+<LINE>be a flattering honest man, it must not be denied</LINE>
+<LINE>but I am a plain-dealing villain. I am trusted with</LINE>
+<LINE>a muzzle and enfranchised with a clog; therefore I</LINE>
+<LINE>have decreed not to sing in my cage. If I had my</LINE>
+<LINE>mouth, I would bite; if I had my liberty, I would do</LINE>
+<LINE>my liking: in the meantime let me be that I am and</LINE>
+<LINE>seek not to alter me.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CONRADE</SPEAKER>
+<LINE>Can you make no use of your discontent?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON JOHN</SPEAKER>
+<LINE>I make all use of it, for I use it only.</LINE>
+<LINE>Who comes here?</LINE>
+<STAGEDIR>Enter BORACHIO</STAGEDIR>
+<LINE>What news, Borachio?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BORACHIO</SPEAKER>
+<LINE>I came yonder from a great supper: the prince your</LINE>
+<LINE>brother is royally entertained by Leonato: and I</LINE>
+<LINE>can give you intelligence of an intended marriage.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON JOHN</SPEAKER>
+<LINE>Will it serve for any model to build mischief on?</LINE>
+<LINE>What is he for a fool that betroths himself to</LINE>
+<LINE>unquietness?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BORACHIO</SPEAKER>
+<LINE>Marry, it is your brother's right hand.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON JOHN</SPEAKER>
+<LINE>Who? the most exquisite Claudio?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BORACHIO</SPEAKER>
+<LINE>Even he.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON JOHN</SPEAKER>
+<LINE>A proper squire! And who, and who? which way looks</LINE>
+<LINE>he?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BORACHIO</SPEAKER>
+<LINE>Marry, on Hero, the daughter and heir of Leonato.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON JOHN</SPEAKER>
+<LINE>A very forward March-chick! How came you to this?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BORACHIO</SPEAKER>
+<LINE>Being entertained for a perfumer, as I was smoking a</LINE>
+<LINE>musty room, comes me the prince and Claudio, hand</LINE>
+<LINE>in hand in sad conference: I whipt me behind the</LINE>
+<LINE>arras; and there heard it agreed upon that the</LINE>
+<LINE>prince should woo Hero for himself, and having</LINE>
+<LINE>obtained her, give her to Count Claudio.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON JOHN</SPEAKER>
+<LINE>Come, come, let us thither: this may prove food to</LINE>
+<LINE>my displeasure. That young start-up hath all the</LINE>
+<LINE>glory of my overthrow: if I can cross him any way, I</LINE>
+<LINE>bless myself every way. You are both sure, and will assist me?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CONRADE</SPEAKER>
+<LINE>To the death, my lord.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON JOHN</SPEAKER>
+<LINE>Let us to the great supper: their cheer is the</LINE>
+<LINE>greater that I am subdued. Would the cook were of</LINE>
+<LINE>my mind! Shall we go prove what's to be done?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BORACHIO</SPEAKER>
+<LINE>We'll wait upon your lordship.</LINE>
+</SPEECH>
+
+
+<STAGEDIR>Exeunt</STAGEDIR>
+</SCENE>
+
+</ACT>
+
+<ACT><TITLE>ACT II</TITLE>
+
+<SCENE><TITLE>SCENE I.  A hall in LEONATO'S house.</TITLE>
+<STAGEDIR>Enter LEONATO, ANTONIO, HERO, BEATRICE, and others</STAGEDIR>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>Was not Count John here at supper?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>ANTONIO</SPEAKER>
+<LINE>I saw him not.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>How tartly that gentleman looks! I never can see</LINE>
+<LINE>him but I am heart-burned an hour after.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>HERO</SPEAKER>
+<LINE>He is of a very melancholy disposition.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>He were an excellent man that were made just in the</LINE>
+<LINE>midway between him and Benedick: the one is too</LINE>
+<LINE>like an image and says nothing, and the other too</LINE>
+<LINE>like my lady's eldest son, evermore tattling.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>Then half Signior Benedick's tongue in Count John's</LINE>
+<LINE>mouth, and half Count John's melancholy in Signior</LINE>
+<LINE>Benedick's face,--</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>With a good leg and a good foot, uncle, and money</LINE>
+<LINE>enough in his purse, such a man would win any woman</LINE>
+<LINE>in the world, if a' could get her good-will.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>By my troth, niece, thou wilt never get thee a</LINE>
+<LINE>husband, if thou be so shrewd of thy tongue.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>ANTONIO</SPEAKER>
+<LINE>In faith, she's too curst.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>Too curst is more than curst: I shall lessen God's</LINE>
+<LINE>sending that way; for it is said, 'God sends a curst</LINE>
+<LINE>cow short horns;' but to a cow too curst he sends none.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>So, by being too curst, God will send you no horns.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>Just, if he send me no husband; for the which</LINE>
+<LINE>blessing I am at him upon my knees every morning and</LINE>
+<LINE>evening. Lord, I could not endure a husband with a</LINE>
+<LINE>beard on his face: I had rather lie in the woollen.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>You may light on a husband that hath no beard.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>What should I do with him? dress him in my apparel</LINE>
+<LINE>and make him my waiting-gentlewoman? He that hath a</LINE>
+<LINE>beard is more than a youth, and he that hath no</LINE>
+<LINE>beard is less than a man: and he that is more than</LINE>
+<LINE>a youth is not for me, and he that is less than a</LINE>
+<LINE>man, I am not for him: therefore, I will even take</LINE>
+<LINE>sixpence in earnest of the bear-ward, and lead his</LINE>
+<LINE>apes into hell.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>Well, then, go you into hell?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>No, but to the gate; and there will the devil meet</LINE>
+<LINE>me, like an old cuckold, with horns on his head, and</LINE>
+<LINE>say 'Get you to heaven, Beatrice, get you to</LINE>
+<LINE>heaven; here's no place for you maids:' so deliver</LINE>
+<LINE>I up my apes, and away to Saint Peter for the</LINE>
+<LINE>heavens; he shows me where the bachelors sit, and</LINE>
+<LINE>there live we as merry as the day is long.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>ANTONIO</SPEAKER>
+<LINE><STAGEDIR>To HERO</STAGEDIR>  Well, niece, I trust you will be ruled</LINE>
+<LINE>by your father.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>Yes, faith; it is my cousin's duty to make curtsy</LINE>
+<LINE>and say 'Father, as it please you.' But yet for all</LINE>
+<LINE>that, cousin, let him be a handsome fellow, or else</LINE>
+<LINE>make another curtsy and say 'Father, as it please</LINE>
+<LINE>me.'</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>Well, niece, I hope to see you one day fitted with a husband.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>Not till God make men of some other metal than</LINE>
+<LINE>earth. Would it not grieve a woman to be</LINE>
+<LINE>overmastered with a pierce of valiant dust? to make</LINE>
+<LINE>an account of her life to a clod of wayward marl?</LINE>
+<LINE>No, uncle, I'll none: Adam's sons are my brethren;</LINE>
+<LINE>and, truly, I hold it a sin to match in my kindred.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>Daughter, remember what I told you: if the prince</LINE>
+<LINE>do solicit you in that kind, you know your answer.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>The fault will be in the music, cousin, if you be</LINE>
+<LINE>not wooed in good time: if the prince be too</LINE>
+<LINE>important, tell him there is measure in every thing</LINE>
+<LINE>and so dance out the answer. For, hear me, Hero:</LINE>
+<LINE>wooing, wedding, and repenting, is as a Scotch jig,</LINE>
+<LINE>a measure, and a cinque pace: the first suit is hot</LINE>
+<LINE>and hasty, like a Scotch jig, and full as</LINE>
+<LINE>fantastical; the wedding, mannerly-modest, as a</LINE>
+<LINE>measure, full of state and ancientry; and then comes</LINE>
+<LINE>repentance and, with his bad legs, falls into the</LINE>
+<LINE>cinque pace faster and faster, till he sink into his grave.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>Cousin, you apprehend passing shrewdly.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>I have a good eye, uncle; I can see a church by daylight.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>The revellers are entering, brother: make good room.</LINE>
+</SPEECH>
+
+<STAGEDIR>All put on their masks</STAGEDIR>
+<STAGEDIR>Enter DON PEDRO, CLAUDIO, BENEDICK, BALTHASAR,
+DON JOHN, BORACHIO, MARGARET, URSULA and others, masked</STAGEDIR>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>Lady, will you walk about with your friend?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>HERO</SPEAKER>
+<LINE>So you walk softly and look sweetly and say nothing,</LINE>
+<LINE>I am yours for the walk; and especially when I walk away.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>With me in your company?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>HERO</SPEAKER>
+<LINE>I may say so, when I please.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>And when please you to say so?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>HERO</SPEAKER>
+<LINE>When I like your favour; for God defend the lute</LINE>
+<LINE>should be like the case!</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>My visor is Philemon's roof; within the house is Jove.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>HERO</SPEAKER>
+<LINE>Why, then, your visor should be thatched.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>Speak low, if you speak love.</LINE>
+</SPEECH>
+
+
+<STAGEDIR>Drawing her aside</STAGEDIR>
+
+<SPEECH>
+<SPEAKER>BALTHASAR</SPEAKER>
+<LINE>Well, I would you did like me.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>MARGARET</SPEAKER>
+<LINE>So would not I, for your own sake; for I have many</LINE>
+<LINE>ill-qualities.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BALTHASAR</SPEAKER>
+<LINE>Which is one?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>MARGARET</SPEAKER>
+<LINE>I say my prayers aloud.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BALTHASAR</SPEAKER>
+<LINE>I love you the better: the hearers may cry, Amen.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>MARGARET</SPEAKER>
+<LINE>God match me with a good dancer!</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BALTHASAR</SPEAKER>
+<LINE>Amen.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>MARGARET</SPEAKER>
+<LINE>And God keep him out of my sight when the dance is</LINE>
+<LINE>done! Answer, clerk.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BALTHASAR</SPEAKER>
+<LINE>No more words: the clerk is answered.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>URSULA</SPEAKER>
+<LINE>I know you well enough; you are Signior Antonio.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>ANTONIO</SPEAKER>
+<LINE>At a word, I am not.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>URSULA</SPEAKER>
+<LINE>I know you by the waggling of your head.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>ANTONIO</SPEAKER>
+<LINE>To tell you true, I counterfeit him.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>URSULA</SPEAKER>
+<LINE>You could never do him so ill-well, unless you were</LINE>
+<LINE>the very man. Here's his dry hand up and down: you</LINE>
+<LINE>are he, you are he.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>ANTONIO</SPEAKER>
+<LINE>At a word, I am not.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>URSULA</SPEAKER>
+<LINE>Come, come, do you think I do not know you by your</LINE>
+<LINE>excellent wit? can virtue hide itself? Go to,</LINE>
+<LINE>mum, you are he: graces will appear, and there's an</LINE>
+<LINE>end.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>Will you not tell me who told you so?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>No, you shall pardon me.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>Nor will you not tell me who you are?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>Not now.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>That I was disdainful, and that I had my good wit</LINE>
+<LINE>out of the 'Hundred Merry Tales:'--well this was</LINE>
+<LINE>Signior Benedick that said so.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>What's he?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>I am sure you know him well enough.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>Not I, believe me.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>Did he never make you laugh?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>I pray you, what is he?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>Why, he is the prince's jester: a very dull fool;</LINE>
+<LINE>only his gift is in devising impossible slanders:</LINE>
+<LINE>none but libertines delight in him; and the</LINE>
+<LINE>commendation is not in his wit, but in his villany;</LINE>
+<LINE>for he both pleases men and angers them, and then</LINE>
+<LINE>they laugh at him and beat him. I am sure he is in</LINE>
+<LINE>the fleet: I would he had boarded me.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>When I know the gentleman, I'll tell him what you say.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>Do, do: he'll but break a comparison or two on me;</LINE>
+<LINE>which, peradventure not marked or not laughed at,</LINE>
+<LINE>strikes him into melancholy; and then there's a</LINE>
+<LINE>partridge wing saved, for the fool will eat no</LINE>
+<LINE>supper that night.</LINE>
+<STAGEDIR>Music</STAGEDIR>
+<LINE>We must follow the leaders.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>In every good thing.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>Nay, if they lead to any ill, I will leave them at</LINE>
+<LINE>the next turning.</LINE>
+</SPEECH>
+
+
+<STAGEDIR>Dance. Then exeunt all except DON JOHN, BORACHIO,
+and CLAUDIO</STAGEDIR>
+
+<SPEECH>
+<SPEAKER>DON JOHN</SPEAKER>
+<LINE>Sure my brother is amorous on Hero and hath</LINE>
+<LINE>withdrawn her father to break with him about it.</LINE>
+<LINE>The ladies follow her and but one visor remains.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BORACHIO</SPEAKER>
+<LINE>And that is Claudio: I know him by his bearing.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON JOHN</SPEAKER>
+<LINE>Are not you Signior Benedick?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>You know me well; I am he.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON JOHN</SPEAKER>
+<LINE>Signior, you are very near my brother in his love:</LINE>
+<LINE>he is enamoured on Hero; I pray you, dissuade him</LINE>
+<LINE>from her: she is no equal for his birth: you may</LINE>
+<LINE>do the part of an honest man in it.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>How know you he loves her?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON JOHN</SPEAKER>
+<LINE>I heard him swear his affection.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BORACHIO</SPEAKER>
+<LINE>So did I too; and he swore he would marry her to-night.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON JOHN</SPEAKER>
+<LINE>Come, let us to the banquet.</LINE>
+</SPEECH>
+
+
+<STAGEDIR>Exeunt DON JOHN and BORACHIO</STAGEDIR>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>Thus answer I in the name of Benedick,</LINE>
+<LINE>But hear these ill news with the ears of Claudio.</LINE>
+<LINE>'Tis certain so; the prince wooes for himself.</LINE>
+<LINE>Friendship is constant in all other things</LINE>
+<LINE>Save in the office and affairs of love:</LINE>
+<LINE>Therefore, all hearts in love use their own tongues;</LINE>
+<LINE>Let every eye negotiate for itself</LINE>
+<LINE>And trust no agent; for beauty is a witch</LINE>
+<LINE>Against whose charms faith melteth into blood.</LINE>
+<LINE>This is an accident of hourly proof,</LINE>
+<LINE>Which I mistrusted not. Farewell, therefore, Hero!</LINE>
+</SPEECH>
+
+
+<STAGEDIR>Re-enter BENEDICK</STAGEDIR>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>Count Claudio?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>Yea, the same.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>Come, will you go with me?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>Whither?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>Even to the next willow, about your own business,</LINE>
+<LINE>county. What fashion will you wear the garland of?</LINE>
+<LINE>about your neck, like an usurer's chain? or under</LINE>
+<LINE>your arm, like a lieutenant's scarf? You must wear</LINE>
+<LINE>it one way, for the prince hath got your Hero.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>I wish him joy of her.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>Why, that's spoken like an honest drovier: so they</LINE>
+<LINE>sell bullocks. But did you think the prince would</LINE>
+<LINE>have served you thus?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>I pray you, leave me.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>Ho! now you strike like the blind man: 'twas the</LINE>
+<LINE>boy that stole your meat, and you'll beat the post.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>If it will not be, I'll leave you.</LINE>
+</SPEECH>
+
+
+<STAGEDIR>Exit</STAGEDIR>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>Alas, poor hurt fowl! now will he creep into sedges.</LINE>
+<LINE>But that my Lady Beatrice should know me, and not</LINE>
+<LINE>know me! The prince's fool! Ha? It may be I go</LINE>
+<LINE>under that title because I am merry. Yea, but so I</LINE>
+<LINE>am apt to do myself wrong; I am not so reputed: it</LINE>
+<LINE>is the base, though bitter, disposition of Beatrice</LINE>
+<LINE>that puts the world into her person and so gives me</LINE>
+<LINE>out. Well, I'll be revenged as I may.</LINE>
+</SPEECH>
+
+
+<STAGEDIR>Re-enter DON PEDRO</STAGEDIR>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>Now, signior, where's the count? did you see him?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>Troth, my lord, I have played the part of Lady Fame.</LINE>
+<LINE>I found him here as melancholy as a lodge in a</LINE>
+<LINE>warren: I told him, and I think I told him true,</LINE>
+<LINE>that your grace had got the good will of this young</LINE>
+<LINE>lady; and I offered him my company to a willow-tree,</LINE>
+<LINE>either to make him a garland, as being forsaken, or</LINE>
+<LINE>to bind him up a rod, as being worthy to be whipped.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>To be whipped! What's his fault?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>The flat transgression of a schoolboy, who, being</LINE>
+<LINE>overjoyed with finding a birds' nest, shows it his</LINE>
+<LINE>companion, and he steals it.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>Wilt thou make a trust a transgression? The</LINE>
+<LINE>transgression is in the stealer.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>Yet it had not been amiss the rod had been made,</LINE>
+<LINE>and the garland too; for the garland he might have</LINE>
+<LINE>worn himself, and the rod he might have bestowed on</LINE>
+<LINE>you, who, as I take it, have stolen his birds' nest.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>I will but teach them to sing, and restore them to</LINE>
+<LINE>the owner.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>If their singing answer your saying, by my faith,</LINE>
+<LINE>you say honestly.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>The Lady Beatrice hath a quarrel to you: the</LINE>
+<LINE>gentleman that danced with her told her she is much</LINE>
+<LINE>wronged by you.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>O, she misused me past the endurance of a block!</LINE>
+<LINE>an oak but with one green leaf on it would have</LINE>
+<LINE>answered her; my very visor began to assume life and</LINE>
+<LINE>scold with her. She told me, not thinking I had been</LINE>
+<LINE>myself, that I was the prince's jester, that I was</LINE>
+<LINE>duller than a great thaw; huddling jest upon jest</LINE>
+<LINE>with such impossible conveyance upon me that I stood</LINE>
+<LINE>like a man at a mark, with a whole army shooting at</LINE>
+<LINE>me. She speaks poniards, and every word stabs:</LINE>
+<LINE>if her breath were as terrible as her terminations,</LINE>
+<LINE>there were no living near her; she would infect to</LINE>
+<LINE>the north star. I would not marry her, though she</LINE>
+<LINE>were endowed with all that Adam bad left him before</LINE>
+<LINE>he transgressed: she would have made Hercules have</LINE>
+<LINE>turned spit, yea, and have cleft his club to make</LINE>
+<LINE>the fire too. Come, talk not of her: you shall find</LINE>
+<LINE>her the infernal Ate in good apparel. I would to God</LINE>
+<LINE>some scholar would conjure her; for certainly, while</LINE>
+<LINE>she is here, a man may live as quiet in hell as in a</LINE>
+<LINE>sanctuary; and people sin upon purpose, because they</LINE>
+<LINE>would go thither; so, indeed, all disquiet, horror</LINE>
+<LINE>and perturbation follows her.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>Look, here she comes.</LINE>
+</SPEECH>
+
+
+<STAGEDIR>Enter CLAUDIO, BEATRICE, HERO, and LEONATO</STAGEDIR>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>Will your grace command me any service to the</LINE>
+<LINE>world's end? I will go on the slightest errand now</LINE>
+<LINE>to the Antipodes that you can devise to send me on;</LINE>
+<LINE>I will fetch you a tooth-picker now from the</LINE>
+<LINE>furthest inch of Asia, bring you the length of</LINE>
+<LINE>Prester John's foot, fetch you a hair off the great</LINE>
+<LINE>Cham's beard, do you any embassage to the Pigmies,</LINE>
+<LINE>rather than hold three words' conference with this</LINE>
+<LINE>harpy. You have no employment for me?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>None, but to desire your good company.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>O God, sir, here's a dish I love not: I cannot</LINE>
+<LINE>endure my Lady Tongue.</LINE>
+</SPEECH>
+
+
+<STAGEDIR>Exit</STAGEDIR>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>Come, lady, come; you have lost the heart of</LINE>
+<LINE>Signior Benedick.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>Indeed, my lord, he lent it me awhile; and I gave</LINE>
+<LINE>him use for it, a double heart for his single one:</LINE>
+<LINE>marry, once before he won it of me with false dice,</LINE>
+<LINE>therefore your grace may well say I have lost it.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>You have put him down, lady, you have put him down.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>So I would not he should do me, my lord, lest I</LINE>
+<LINE>should prove the mother of fools. I have brought</LINE>
+<LINE>Count Claudio, whom you sent me to seek.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>Why, how now, count! wherefore are you sad?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>Not sad, my lord.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>How then? sick?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>Neither, my lord.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>The count is neither sad, nor sick, nor merry, nor</LINE>
+<LINE>well; but civil count, civil as an orange, and</LINE>
+<LINE>something of that jealous complexion.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>I' faith, lady, I think your blazon to be true;</LINE>
+<LINE>though, I'll be sworn, if he be so, his conceit is</LINE>
+<LINE>false. Here, Claudio, I have wooed in thy name, and</LINE>
+<LINE>fair Hero is won: I have broke with her father,</LINE>
+<LINE>and his good will obtained: name the day of</LINE>
+<LINE>marriage, and God give thee joy!</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>Count, take of me my daughter, and with her my</LINE>
+<LINE>fortunes: his grace hath made the match, and an</LINE>
+<LINE>grace say Amen to it.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>Speak, count, 'tis your cue.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>Silence is the perfectest herald of joy: I were</LINE>
+<LINE>but little happy, if I could say how much. Lady, as</LINE>
+<LINE>you are mine, I am yours: I give away myself for</LINE>
+<LINE>you and dote upon the exchange.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>Speak, cousin; or, if you cannot, stop his mouth</LINE>
+<LINE>with a kiss, and let not him speak neither.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>In faith, lady, you have a merry heart.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>Yea, my lord; I thank it, poor fool, it keeps on</LINE>
+<LINE>the windy side of care. My cousin tells him in his</LINE>
+<LINE>ear that he is in her heart.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>And so she doth, cousin.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>Good Lord, for alliance! Thus goes every one to the</LINE>
+<LINE>world but I, and I am sunburnt; I may sit in a</LINE>
+<LINE>corner and cry heigh-ho for a husband!</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>Lady Beatrice, I will get you one.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>I would rather have one of your father's getting.</LINE>
+<LINE>Hath your grace ne'er a brother like you? Your</LINE>
+<LINE>father got excellent husbands, if a maid could come by them.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>Will you have me, lady?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>No, my lord, unless I might have another for</LINE>
+<LINE>working-days: your grace is too costly to wear</LINE>
+<LINE>every day. But, I beseech your grace, pardon me: I</LINE>
+<LINE>was born to speak all mirth and no matter.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>Your silence most offends me, and to be merry best</LINE>
+<LINE>becomes you; for, out of question, you were born in</LINE>
+<LINE>a merry hour.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>No, sure, my lord, my mother cried; but then there</LINE>
+<LINE>was a star danced, and under that was I born.</LINE>
+<LINE>Cousins, God give you joy!</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>Niece, will you look to those things I told you of?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>I cry you mercy, uncle. By your grace's pardon.</LINE>
+</SPEECH>
+
+
+<STAGEDIR>Exit</STAGEDIR>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>By my troth, a pleasant-spirited lady.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>There's little of the melancholy element in her, my</LINE>
+<LINE>lord: she is never sad but when she sleeps, and</LINE>
+<LINE>not ever sad then; for I have heard my daughter say,</LINE>
+<LINE>she hath often dreamed of unhappiness and waked</LINE>
+<LINE>herself with laughing.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>She cannot endure to hear tell of a husband.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>O, by no means: she mocks all her wooers out of suit.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>She were an excellent wife for Benedict.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>O Lord, my lord, if they were but a week married,</LINE>
+<LINE>they would talk themselves mad.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>County Claudio, when mean you to go to church?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>To-morrow, my lord: time goes on crutches till love</LINE>
+<LINE>have all his rites.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>Not till Monday, my dear son, which is hence a just</LINE>
+<LINE>seven-night; and a time too brief, too, to have all</LINE>
+<LINE>things answer my mind.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>Come, you shake the head at so long a breathing:</LINE>
+<LINE>but, I warrant thee, Claudio, the time shall not go</LINE>
+<LINE>dully by us. I will in the interim undertake one of</LINE>
+<LINE>Hercules' labours; which is, to bring Signior</LINE>
+<LINE>Benedick and the Lady Beatrice into a mountain of</LINE>
+<LINE>affection the one with the other. I would fain have</LINE>
+<LINE>it a match, and I doubt not but to fashion it, if</LINE>
+<LINE>you three will but minister such assistance as I</LINE>
+<LINE>shall give you direction.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>My lord, I am for you, though it cost me ten</LINE>
+<LINE>nights' watchings.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>And I, my lord.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>And you too, gentle Hero?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>HERO</SPEAKER>
+<LINE>I will do any modest office, my lord, to help my</LINE>
+<LINE>cousin to a good husband.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>And Benedick is not the unhopefullest husband that</LINE>
+<LINE>I know. Thus far can I praise him; he is of a noble</LINE>
+<LINE>strain, of approved valour and confirmed honesty. I</LINE>
+<LINE>will teach you how to humour your cousin, that she</LINE>
+<LINE>shall fall in love with Benedick; and I, with your</LINE>
+<LINE>two helps, will so practise on Benedick that, in</LINE>
+<LINE>despite of his quick wit and his queasy stomach, he</LINE>
+<LINE>shall fall in love with Beatrice. If we can do this,</LINE>
+<LINE>Cupid is no longer an archer: his glory shall be</LINE>
+<LINE>ours, for we are the only love-gods. Go in with me,</LINE>
+<LINE>and I will tell you my drift.</LINE>
+</SPEECH>
+
+
+<STAGEDIR>Exeunt</STAGEDIR>
+</SCENE>
+
+<SCENE><TITLE>SCENE II.  The same.</TITLE>
+<STAGEDIR>Enter DON JOHN and BORACHIO</STAGEDIR>
+
+<SPEECH>
+<SPEAKER>DON JOHN</SPEAKER>
+<LINE>It is so; the Count Claudio shall marry the</LINE>
+<LINE>daughter of Leonato.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BORACHIO</SPEAKER>
+<LINE>Yea, my lord; but I can cross it.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON JOHN</SPEAKER>
+<LINE>Any bar, any cross, any impediment will be</LINE>
+<LINE>medicinable to me: I am sick in displeasure to him,</LINE>
+<LINE>and whatsoever comes athwart his affection ranges</LINE>
+<LINE>evenly with mine. How canst thou cross this marriage?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BORACHIO</SPEAKER>
+<LINE>Not honestly, my lord; but so covertly that no</LINE>
+<LINE>dishonesty shall appear in me.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON JOHN</SPEAKER>
+<LINE>Show me briefly how.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BORACHIO</SPEAKER>
+<LINE>I think I told your lordship a year since, how much</LINE>
+<LINE>I am in the favour of Margaret, the waiting</LINE>
+<LINE>gentlewoman to Hero.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON JOHN</SPEAKER>
+<LINE>I remember.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BORACHIO</SPEAKER>
+<LINE>I can, at any unseasonable instant of the night,</LINE>
+<LINE>appoint her to look out at her lady's chamber window.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON JOHN</SPEAKER>
+<LINE>What life is in that, to be the death of this marriage?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BORACHIO</SPEAKER>
+<LINE>The poison of that lies in you to temper. Go you to</LINE>
+<LINE>the prince your brother; spare not to tell him that</LINE>
+<LINE>he hath wronged his honour in marrying the renowned</LINE>
+<LINE>Claudio--whose estimation do you mightily hold</LINE>
+<LINE>up--to a contaminated stale, such a one as Hero.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON JOHN</SPEAKER>
+<LINE>What proof shall I make of that?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BORACHIO</SPEAKER>
+<LINE>Proof enough to misuse the prince, to vex Claudio,</LINE>
+<LINE>to undo Hero and kill Leonato. Look you for any</LINE>
+<LINE>other issue?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON JOHN</SPEAKER>
+<LINE>Only to despite them, I will endeavour any thing.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BORACHIO</SPEAKER>
+<LINE>Go, then; find me a meet hour to draw Don Pedro and</LINE>
+<LINE>the Count Claudio alone: tell them that you know</LINE>
+<LINE>that Hero loves me; intend a kind of zeal both to the</LINE>
+<LINE>prince and Claudio, as,--in love of your brother's</LINE>
+<LINE>honour, who hath made this match, and his friend's</LINE>
+<LINE>reputation, who is thus like to be cozened with the</LINE>
+<LINE>semblance of a maid,--that you have discovered</LINE>
+<LINE>thus. They will scarcely believe this without trial:</LINE>
+<LINE>offer them instances; which shall bear no less</LINE>
+<LINE>likelihood than to see me at her chamber-window,</LINE>
+<LINE>hear me call Margaret Hero, hear Margaret term me</LINE>
+<LINE>Claudio; and bring them to see this the very night</LINE>
+<LINE>before the intended wedding,--for in the meantime I</LINE>
+<LINE>will so fashion the matter that Hero shall be</LINE>
+<LINE>absent,--and there shall appear such seeming truth</LINE>
+<LINE>of Hero's disloyalty that jealousy shall be called</LINE>
+<LINE>assurance and all the preparation overthrown.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON JOHN</SPEAKER>
+<LINE>Grow this to what adverse issue it can, I will put</LINE>
+<LINE>it in practise. Be cunning in the working this, and</LINE>
+<LINE>thy fee is a thousand ducats.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BORACHIO</SPEAKER>
+<LINE>Be you constant in the accusation, and my cunning</LINE>
+<LINE>shall not shame me.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON JOHN</SPEAKER>
+<LINE>I will presently go learn their day of marriage.</LINE>
+</SPEECH>
+
+
+<STAGEDIR>Exeunt</STAGEDIR>
+</SCENE>
+
+<SCENE><TITLE>SCENE III.  LEONATO'S orchard.</TITLE>
+<STAGEDIR>Enter BENEDICK</STAGEDIR>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>Boy!</LINE>
+</SPEECH>
+
+
+<STAGEDIR>Enter Boy</STAGEDIR>
+
+<SPEECH>
+<SPEAKER>Boy</SPEAKER>
+<LINE>Signior?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>In my chamber-window lies a book: bring it hither</LINE>
+<LINE>to me in the orchard.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>Boy</SPEAKER>
+<LINE>I am here already, sir.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>I know that; but I would have thee hence, and here again.</LINE>
+<STAGEDIR>Exit Boy</STAGEDIR>
+<LINE>I do much wonder that one man, seeing how much</LINE>
+<LINE>another man is a fool when he dedicates his</LINE>
+<LINE>behaviors to love, will, after he hath laughed at</LINE>
+<LINE>such shallow follies in others, become the argument</LINE>
+<LINE>of his own scorn by failing in love: and such a man</LINE>
+<LINE>is Claudio. I have known when there was no music</LINE>
+<LINE>with him but the drum and the fife; and now had he</LINE>
+<LINE>rather hear the tabour and the pipe: I have known</LINE>
+<LINE>when he would have walked ten mile a-foot to see a</LINE>
+<LINE>good armour; and now will he lie ten nights awake,</LINE>
+<LINE>carving the fashion of a new doublet. He was wont to</LINE>
+<LINE>speak plain and to the purpose, like an honest man</LINE>
+<LINE>and a soldier; and now is he turned orthography; his</LINE>
+<LINE>words are a very fantastical banquet, just so many</LINE>
+<LINE>strange dishes. May I be so converted and see with</LINE>
+<LINE>these eyes? I cannot tell; I think not: I will not</LINE>
+<LINE>be sworn, but love may transform me to an oyster; but</LINE>
+<LINE>I'll take my oath on it, till he have made an oyster</LINE>
+<LINE>of me, he shall never make me such a fool. One woman</LINE>
+<LINE>is fair, yet I am well; another is wise, yet I am</LINE>
+<LINE>well; another virtuous, yet I am well; but till all</LINE>
+<LINE>graces be in one woman, one woman shall not come in</LINE>
+<LINE>my grace. Rich she shall be, that's certain; wise,</LINE>
+<LINE>or I'll none; virtuous, or I'll never cheapen her;</LINE>
+<LINE>fair, or I'll   never look on her; mild, or come not</LINE>
+<LINE>near me; noble, or not I for an angel; of good</LINE>
+<LINE>discourse, an excellent musician, and her hair shall</LINE>
+<LINE>be of what colour it please God. Ha! the prince and</LINE>
+<LINE>Monsieur Love! I will hide me in the arbour.</LINE>
+</SPEECH>
+
+<STAGEDIR>Withdraws</STAGEDIR>
+<STAGEDIR>Enter DON PEDRO, CLAUDIO, and LEONATO</STAGEDIR>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>Come, shall we hear this music?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>Yea, my good lord. How still the evening is,</LINE>
+<LINE>As hush'd on purpose to grace harmony!</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>See you where Benedick hath hid himself?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>O, very well, my lord: the music ended,</LINE>
+<LINE>We'll fit the kid-fox with a pennyworth.</LINE>
+</SPEECH>
+
+
+<STAGEDIR>Enter BALTHASAR with Music</STAGEDIR>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>Come, Balthasar, we'll hear that song again.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BALTHASAR</SPEAKER>
+<LINE>O, good my lord, tax not so bad a voice</LINE>
+<LINE>To slander music any more than once.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>It is the witness still of excellency</LINE>
+<LINE>To put a strange face on his own perfection.</LINE>
+<LINE>I pray thee, sing, and let me woo no more.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BALTHASAR</SPEAKER>
+<LINE>Because you talk of wooing, I will sing;</LINE>
+<LINE>Since many a wooer doth commence his suit</LINE>
+<LINE>To her he thinks not worthy, yet he wooes,</LINE>
+<LINE>Yet will he swear he loves.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>Now, pray thee, come;</LINE>
+<LINE>Or, if thou wilt hold longer argument,</LINE>
+<LINE>Do it in notes.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BALTHASAR</SPEAKER>
+<LINE>Note this before my notes;</LINE>
+<LINE>There's not a note of mine that's worth the noting.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>Why, these are very crotchets that he speaks;</LINE>
+<LINE>Note, notes, forsooth, and nothing.</LINE>
+</SPEECH>
+
+
+<STAGEDIR>Air</STAGEDIR>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>Now, divine air! now is his soul ravished! Is it</LINE>
+<LINE>not strange that sheeps' guts should hale souls out</LINE>
+<LINE>of men's bodies? Well, a horn for my money, when</LINE>
+<LINE>all's done.</LINE>
+</SPEECH>
+
+
+<STAGEDIR>The Song</STAGEDIR>
+
+<SPEECH>
+<SPEAKER>BALTHASAR</SPEAKER>
+<LINE>Sigh no more, ladies, sigh no more,</LINE>
+<LINE>Men were deceivers ever,</LINE>
+<LINE>One foot in sea and one on shore,</LINE>
+<LINE>To one thing constant never:</LINE>
+<LINE>Then sigh not so, but let them go,</LINE>
+<LINE>And be you blithe and bonny,</LINE>
+<LINE>Converting all your sounds of woe</LINE>
+<LINE>Into Hey nonny, nonny.</LINE>
+<LINE>Sing no more ditties, sing no moe,</LINE>
+<LINE>Of dumps so dull and heavy;</LINE>
+<LINE>The fraud of men was ever so,</LINE>
+<LINE>Since summer first was leafy:</LINE>
+<LINE>Then sigh not so, &c.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>By my troth, a good song.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BALTHASAR</SPEAKER>
+<LINE>And an ill singer, my lord.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>Ha, no, no, faith; thou singest well enough for a shift.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>An he had been a dog that should have howled thus,</LINE>
+<LINE>they would have hanged him: and I pray God his bad</LINE>
+<LINE>voice bode no mischief. I had as lief have heard the</LINE>
+<LINE>night-raven, come what plague could have come after</LINE>
+<LINE>it.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>Yea, marry, dost thou hear, Balthasar? I pray thee,</LINE>
+<LINE>get us some excellent music; for to-morrow night we</LINE>
+<LINE>would have it at the Lady Hero's chamber-window.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BALTHASAR</SPEAKER>
+<LINE>The best I can, my lord.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>Do so: farewell.</LINE>
+<STAGEDIR>Exit BALTHASAR</STAGEDIR>
+<LINE>Come hither, Leonato. What was it you told me of</LINE>
+<LINE>to-day, that your niece Beatrice was in love with</LINE>
+<LINE>Signior Benedick?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>O, ay: stalk on. stalk on; the fowl sits. I did</LINE>
+<LINE>never think that lady would have loved any man.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>No, nor I neither; but most wonderful that she</LINE>
+<LINE>should so dote on Signior Benedick, whom she hath in</LINE>
+<LINE>all outward behaviors seemed ever to abhor.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>Is't possible? Sits the wind in that corner?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>By my troth, my lord, I cannot tell what to think</LINE>
+<LINE>of it but that she loves him with an enraged</LINE>
+<LINE>affection: it is past the infinite of thought.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>May be she doth but counterfeit.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>Faith, like enough.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>O God, counterfeit! There was never counterfeit of</LINE>
+<LINE>passion came so near the life of passion as she</LINE>
+<LINE>discovers it.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>Why, what effects of passion shows she?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>Bait the hook well; this fish will bite.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>What effects, my lord? She will sit you, you heard</LINE>
+<LINE>my daughter tell you how.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>She did, indeed.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>How, how, pray you? You amaze me: I would have I</LINE>
+<LINE>thought her spirit had been invincible against all</LINE>
+<LINE>assaults of affection.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>I would have sworn it had, my lord; especially</LINE>
+<LINE>against Benedick.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>I should think this a gull, but that the</LINE>
+<LINE>white-bearded fellow speaks it: knavery cannot,</LINE>
+<LINE>sure, hide himself in such reverence.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>He hath ta'en the infection: hold it up.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>Hath she made her affection known to Benedick?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>No; and swears she never will: that's her torment.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>'Tis true, indeed; so your daughter says: 'Shall</LINE>
+<LINE>I,' says she, 'that have so oft encountered him</LINE>
+<LINE>with scorn, write to him that I love him?'</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>This says she now when she is beginning to write to</LINE>
+<LINE>him; for she'll be up twenty times a night, and</LINE>
+<LINE>there will she sit in her smock till she have writ a</LINE>
+<LINE>sheet of paper: my daughter tells us all.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>Now you talk of a sheet of paper, I remember a</LINE>
+<LINE>pretty jest your daughter told us of.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>O, when she had writ it and was reading it over, she</LINE>
+<LINE>found Benedick and Beatrice between the sheet?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>That.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>O, she tore the letter into a thousand halfpence;</LINE>
+<LINE>railed at herself, that she should be so immodest</LINE>
+<LINE>to write to one that she knew would flout her; 'I</LINE>
+<LINE>measure him,' says she, 'by my own spirit; for I</LINE>
+<LINE>should flout him, if he writ to me; yea, though I</LINE>
+<LINE>love him, I should.'</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>Then down upon her knees she falls, weeps, sobs,</LINE>
+<LINE>beats her heart, tears her hair, prays, curses; 'O</LINE>
+<LINE>sweet Benedick! God give me patience!'</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>She doth indeed; my daughter says so: and the</LINE>
+<LINE>ecstasy hath so much overborne her that my daughter</LINE>
+<LINE>is sometime afeared she will do a desperate outrage</LINE>
+<LINE>to herself: it is very true.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>It were good that Benedick knew of it by some</LINE>
+<LINE>other, if she will not discover it.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>To what end? He would make but a sport of it and</LINE>
+<LINE>torment the poor lady worse.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>An he should, it were an alms to hang him. She's an</LINE>
+<LINE>excellent sweet lady; and, out of all suspicion,</LINE>
+<LINE>she is virtuous.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>And she is exceeding wise.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>In every thing but in loving Benedick.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>O, my lord, wisdom and blood combating in so tender</LINE>
+<LINE>a body, we have ten proofs to one that blood hath</LINE>
+<LINE>the victory. I am sorry for her, as I have just</LINE>
+<LINE>cause, being her uncle and her guardian.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>I would she had bestowed this dotage on me: I would</LINE>
+<LINE>have daffed all other respects and made her half</LINE>
+<LINE>myself. I pray you, tell Benedick of it, and hear</LINE>
+<LINE>what a' will say.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>Were it good, think you?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>Hero thinks surely she will die; for she says she</LINE>
+<LINE>will die, if he love her not, and she will die, ere</LINE>
+<LINE>she make her love known, and she will die, if he woo</LINE>
+<LINE>her, rather than she will bate one breath of her</LINE>
+<LINE>accustomed crossness.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>She doth well: if she should make tender of her</LINE>
+<LINE>love, 'tis very possible he'll scorn it; for the</LINE>
+<LINE>man, as you know all, hath a contemptible spirit.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>He is a very proper man.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>He hath indeed a good outward happiness.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>Before God! and, in my mind, very wise.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>He doth indeed show some sparks that are like wit.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>And I take him to be valiant.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>As Hector, I assure you: and in the managing of</LINE>
+<LINE>quarrels you may say he is wise; for either he</LINE>
+<LINE>avoids them with great discretion, or undertakes</LINE>
+<LINE>them with a most Christian-like fear.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>If he do fear God, a' must necessarily keep peace:</LINE>
+<LINE>if he break the peace, he ought to enter into a</LINE>
+<LINE>quarrel with fear and trembling.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>And so will he do; for the man doth fear God,</LINE>
+<LINE>howsoever it seems not in him by some large jests</LINE>
+<LINE>he will make. Well I am sorry for your niece. Shall</LINE>
+<LINE>we go seek Benedick, and tell him of her love?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>Never tell him, my lord: let her wear it out with</LINE>
+<LINE>good counsel.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>Nay, that's impossible: she may wear her heart out first.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>Well, we will hear further of it by your daughter:</LINE>
+<LINE>let it cool the while. I love Benedick well; and I</LINE>
+<LINE>could wish he would modestly examine himself, to see</LINE>
+<LINE>how much he is unworthy so good a lady.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>My lord, will you walk? dinner is ready.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>If he do not dote on her upon this, I will never</LINE>
+<LINE>trust my expectation.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>Let there be the same net spread for her; and that</LINE>
+<LINE>must your daughter and her gentlewomen carry. The</LINE>
+<LINE>sport will be, when they hold one an opinion of</LINE>
+<LINE>another's dotage, and no such matter: that's the</LINE>
+<LINE>scene that I would see, which will be merely a</LINE>
+<LINE>dumb-show. Let us send her to call him in to dinner.</LINE>
+</SPEECH>
+
+
+<STAGEDIR>Exeunt DON PEDRO, CLAUDIO, and LEONATO</STAGEDIR>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE><STAGEDIR>Coming forward</STAGEDIR>  This can be no trick: the</LINE>
+<LINE>conference was sadly borne. They have the truth of</LINE>
+<LINE>this from Hero. They seem to pity the lady: it</LINE>
+<LINE>seems her affections have their full bent. Love me!</LINE>
+<LINE>why, it must be requited. I hear how I am censured:</LINE>
+<LINE>they say I will bear myself proudly, if I perceive</LINE>
+<LINE>the love come from her; they say too that she will</LINE>
+<LINE>rather die than give any sign of affection. I did</LINE>
+<LINE>never think to marry: I must not seem proud: happy</LINE>
+<LINE>are they that hear their detractions and can put</LINE>
+<LINE>them to mending. They say the lady is fair; 'tis a</LINE>
+<LINE>truth, I can bear them witness; and virtuous; 'tis</LINE>
+<LINE>so, I cannot reprove it; and wise, but for loving</LINE>
+<LINE>me; by my troth, it is no addition to her wit, nor</LINE>
+<LINE>no great argument of her folly, for I will be</LINE>
+<LINE>horribly in love with her. I may chance have some</LINE>
+<LINE>odd quirks and remnants of wit broken on me,</LINE>
+<LINE>because I have railed so long against marriage: but</LINE>
+<LINE>doth not the appetite alter? a man loves the meat</LINE>
+<LINE>in his youth that he cannot endure in his age.</LINE>
+<LINE>Shall quips and sentences and these paper bullets of</LINE>
+<LINE>the brain awe a man from the career of his humour?</LINE>
+<LINE>No, the world must be peopled. When I said I would</LINE>
+<LINE>die a bachelor, I did not think I should live till I</LINE>
+<LINE>were married. Here comes Beatrice. By this day!</LINE>
+<LINE>she's a fair lady: I do spy some marks of love in</LINE>
+<LINE>her.</LINE>
+</SPEECH>
+
+
+<STAGEDIR>Enter BEATRICE</STAGEDIR>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>Against my will I am sent to bid you come in to dinner.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>Fair Beatrice, I thank you for your pains.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>I took no more pains for those thanks than you take</LINE>
+<LINE>pains to thank me: if it had been painful, I would</LINE>
+<LINE>not have come.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>You take pleasure then in the message?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>Yea, just so much as you may take upon a knife's</LINE>
+<LINE>point and choke a daw withal. You have no stomach,</LINE>
+<LINE>signior: fare you well.</LINE>
+</SPEECH>
+
+
+<STAGEDIR>Exit</STAGEDIR>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>Ha! 'Against my will I am sent to bid you come in</LINE>
+<LINE>to dinner;' there's a double meaning in that 'I took</LINE>
+<LINE>no more pains for those thanks than you took pains</LINE>
+<LINE>to thank me.' that's as much as to say, Any pains</LINE>
+<LINE>that I take for you is as easy as thanks. If I do</LINE>
+<LINE>not take pity of her, I am a villain; if I do not</LINE>
+<LINE>love her, I am a Jew. I will go get her picture.</LINE>
+</SPEECH>
+
+
+<STAGEDIR>Exit</STAGEDIR>
+</SCENE>
+
+</ACT>
+
+<ACT><TITLE>ACT III</TITLE>
+
+<SCENE><TITLE>SCENE I.  LEONATO'S garden.</TITLE>
+<STAGEDIR>Enter HERO, MARGARET, and URSULA</STAGEDIR>
+
+<SPEECH>
+<SPEAKER>HERO</SPEAKER>
+<LINE>Good Margaret, run thee to the parlor;</LINE>
+<LINE>There shalt thou find my cousin Beatrice</LINE>
+<LINE>Proposing with the prince and Claudio:</LINE>
+<LINE>Whisper her ear and tell her, I and Ursula</LINE>
+<LINE>Walk in the orchard and our whole discourse</LINE>
+<LINE>Is all of her; say that thou overheard'st us;</LINE>
+<LINE>And bid her steal into the pleached bower,</LINE>
+<LINE>Where honeysuckles, ripen'd by the sun,</LINE>
+<LINE>Forbid the sun to enter, like favourites,</LINE>
+<LINE>Made proud by princes, that advance their pride</LINE>
+<LINE>Against that power that bred it: there will she hide her,</LINE>
+<LINE>To listen our purpose.  This is thy office;</LINE>
+<LINE>Bear thee well in it and leave us alone.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>MARGARET</SPEAKER>
+<LINE>I'll make her come, I warrant you, presently.</LINE>
+</SPEECH>
+
+
+<STAGEDIR>Exit</STAGEDIR>
+
+<SPEECH>
+<SPEAKER>HERO</SPEAKER>
+<LINE>Now, Ursula, when Beatrice doth come,</LINE>
+<LINE>As we do trace this alley up and down,</LINE>
+<LINE>Our talk must only be of Benedick.</LINE>
+<LINE>When I do name him, let it be thy part</LINE>
+<LINE>To praise him more than ever man did merit:</LINE>
+<LINE>My talk to thee must be how Benedick</LINE>
+<LINE>Is sick in love with Beatrice. Of this matter</LINE>
+<LINE>Is little Cupid's crafty arrow made,</LINE>
+<LINE>That only wounds by hearsay.</LINE>
+<STAGEDIR>Enter BEATRICE, behind</STAGEDIR>
+<LINE>Now begin;</LINE>
+<LINE>For look where Beatrice, like a lapwing, runs</LINE>
+<LINE>Close by the ground, to hear our conference.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>URSULA</SPEAKER>
+<LINE>The pleasant'st angling is to see the fish</LINE>
+<LINE>Cut with her golden oars the silver stream,</LINE>
+<LINE>And greedily devour the treacherous bait:</LINE>
+<LINE>So angle we for Beatrice; who even now</LINE>
+<LINE>Is couched in the woodbine coverture.</LINE>
+<LINE>Fear you not my part of the dialogue.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>HERO</SPEAKER>
+<LINE>Then go we near her, that her ear lose nothing</LINE>
+<LINE>Of the false sweet bait that we lay for it.</LINE>
+<STAGEDIR>Approaching the bower</STAGEDIR>
+<LINE>No, truly, Ursula, she is too disdainful;</LINE>
+<LINE>I know her spirits are as coy and wild</LINE>
+<LINE>As haggerds of the rock.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>URSULA</SPEAKER>
+<LINE>But are you sure</LINE>
+<LINE>That Benedick loves Beatrice so entirely?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>HERO</SPEAKER>
+<LINE>So says the prince and my new-trothed lord.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>URSULA</SPEAKER>
+<LINE>And did they bid you tell her of it, madam?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>HERO</SPEAKER>
+<LINE>They did entreat me to acquaint her of it;</LINE>
+<LINE>But I persuaded them, if they loved Benedick,</LINE>
+<LINE>To wish him wrestle with affection,</LINE>
+<LINE>And never to let Beatrice know of it.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>URSULA</SPEAKER>
+<LINE>Why did you so? Doth not the gentleman</LINE>
+<LINE>Deserve as full as fortunate a bed</LINE>
+<LINE>As ever Beatrice shall couch upon?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>HERO</SPEAKER>
+<LINE>O god of love! I know he doth deserve</LINE>
+<LINE>As much as may be yielded to a man:</LINE>
+<LINE>But Nature never framed a woman's heart</LINE>
+<LINE>Of prouder stuff than that of Beatrice;</LINE>
+<LINE>Disdain and scorn ride sparkling in her eyes,</LINE>
+<LINE>Misprising what they look on, and her wit</LINE>
+<LINE>Values itself so highly that to her</LINE>
+<LINE>All matter else seems weak: she cannot love,</LINE>
+<LINE>Nor take no shape nor project of affection,</LINE>
+<LINE>She is so self-endeared.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>URSULA</SPEAKER>
+<LINE>Sure, I think so;</LINE>
+<LINE>And therefore certainly it were not good</LINE>
+<LINE>She knew his love, lest she make sport at it.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>HERO</SPEAKER>
+<LINE>Why, you speak truth. I never yet saw man,</LINE>
+<LINE>How wise, how noble, young, how rarely featured,</LINE>
+<LINE>But she would spell him backward: if fair-faced,</LINE>
+<LINE>She would swear the gentleman should be her sister;</LINE>
+<LINE>If black, why, Nature, drawing of an antique,</LINE>
+<LINE>Made a foul blot; if tall, a lance ill-headed;</LINE>
+<LINE>If low, an agate very vilely cut;</LINE>
+<LINE>If speaking, why, a vane blown with all winds;</LINE>
+<LINE>If silent, why, a block moved with none.</LINE>
+<LINE>So turns she every man the wrong side out</LINE>
+<LINE>And never gives to truth and virtue that</LINE>
+<LINE>Which simpleness and merit purchaseth.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>URSULA</SPEAKER>
+<LINE>Sure, sure, such carping is not commendable.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>HERO</SPEAKER>
+<LINE>No, not to be so odd and from all fashions</LINE>
+<LINE>As Beatrice is, cannot be commendable:</LINE>
+<LINE>But who dare tell her so? If I should speak,</LINE>
+<LINE>She would mock me into air; O, she would laugh me</LINE>
+<LINE>Out of myself, press me to death with wit.</LINE>
+<LINE>Therefore let Benedick, like cover'd fire,</LINE>
+<LINE>Consume away in sighs, waste inwardly:</LINE>
+<LINE>It were a better death than die with mocks,</LINE>
+<LINE>Which is as bad as die with tickling.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>URSULA</SPEAKER>
+<LINE>Yet tell her of it: hear what she will say.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>HERO</SPEAKER>
+<LINE>No; rather I will go to Benedick</LINE>
+<LINE>And counsel him to fight against his passion.</LINE>
+<LINE>And, truly, I'll devise some honest slanders</LINE>
+<LINE>To stain my cousin with: one doth not know</LINE>
+<LINE>How much an ill word may empoison liking.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>URSULA</SPEAKER>
+<LINE>O, do not do your cousin such a wrong.</LINE>
+<LINE>She cannot be so much without true judgment--</LINE>
+<LINE>Having so swift and excellent a wit</LINE>
+<LINE>As she is prized to have--as to refuse</LINE>
+<LINE>So rare a gentleman as Signior Benedick.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>HERO</SPEAKER>
+<LINE>He is the only man of Italy.</LINE>
+<LINE>Always excepted my dear Claudio.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>URSULA</SPEAKER>
+<LINE>I pray you, be not angry with me, madam,</LINE>
+<LINE>Speaking my fancy: Signior Benedick,</LINE>
+<LINE>For shape, for bearing, argument and valour,</LINE>
+<LINE>Goes foremost in report through Italy.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>HERO</SPEAKER>
+<LINE>Indeed, he hath an excellent good name.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>URSULA</SPEAKER>
+<LINE>His excellence did earn it, ere he had it.</LINE>
+<LINE>When are you married, madam?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>HERO</SPEAKER>
+<LINE>Why, every day, to-morrow. Come, go in:</LINE>
+<LINE>I'll show thee some attires, and have thy counsel</LINE>
+<LINE>Which is the best to furnish me to-morrow.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>URSULA</SPEAKER>
+<LINE>She's limed, I warrant you: we have caught her, madam.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>HERO</SPEAKER>
+<LINE>If it proves so, then loving goes by haps:</LINE>
+<LINE>Some Cupid kills with arrows, some with traps.</LINE>
+</SPEECH>
+
+
+<STAGEDIR>Exeunt HERO and URSULA</STAGEDIR>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE><STAGEDIR>Coming forward</STAGEDIR></LINE>
+<LINE>What fire is in mine ears? Can this be true?</LINE>
+<LINE>Stand I condemn'd for pride and scorn so much?</LINE>
+<LINE>Contempt, farewell! and maiden pride, adieu!</LINE>
+<LINE>No glory lives behind the back of such.</LINE>
+<LINE>And, Benedick, love on; I will requite thee,</LINE>
+<LINE>Taming my wild heart to thy loving hand:</LINE>
+<LINE>If thou dost love, my kindness shall incite thee</LINE>
+<LINE>To bind our loves up in a holy band;</LINE>
+<LINE>For others say thou dost deserve, and I</LINE>
+<LINE>Believe it better than reportingly.</LINE>
+</SPEECH>
+
+
+<STAGEDIR>Exit</STAGEDIR>
+</SCENE>
+
+<SCENE><TITLE>SCENE II.  A room in LEONATO'S house</TITLE>
+<STAGEDIR>Enter DON PEDRO, CLAUDIO, BENEDICK, and LEONATO</STAGEDIR>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>I do but stay till your marriage be consummate, and</LINE>
+<LINE>then go I toward Arragon.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>I'll bring you thither, my lord, if you'll</LINE>
+<LINE>vouchsafe me.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>Nay, that would be as great a soil in the new gloss</LINE>
+<LINE>of your marriage as to show a child his new coat</LINE>
+<LINE>and forbid him to wear it. I will only be bold</LINE>
+<LINE>with Benedick for his company; for, from the crown</LINE>
+<LINE>of his head to the sole of his foot, he is all</LINE>
+<LINE>mirth: he hath twice or thrice cut Cupid's</LINE>
+<LINE>bow-string and the little hangman dare not shoot at</LINE>
+<LINE>him; he hath a heart as sound as a bell and his</LINE>
+<LINE>tongue is the clapper, for what his heart thinks his</LINE>
+<LINE>tongue speaks.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>Gallants, I am not as I have been.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>So say I methinks you are sadder.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>I hope he be in love.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>Hang him, truant! there's no true drop of blood in</LINE>
+<LINE>him, to be truly touched with love: if he be sad,</LINE>
+<LINE>he wants money.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>I have the toothache.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>Draw it.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>Hang it!</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>You must hang it first, and draw it afterwards.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>What! sigh for the toothache?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>Where is but a humour or a worm.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>Well, every one can master a grief but he that has</LINE>
+<LINE>it.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>Yet say I, he is in love.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>There is no appearance of fancy in him, unless it be</LINE>
+<LINE>a fancy that he hath to strange disguises; as, to be</LINE>
+<LINE>a Dutchman today, a Frenchman to-morrow, or in the</LINE>
+<LINE>shape of two countries at once, as, a German from</LINE>
+<LINE>the waist downward, all slops, and a Spaniard from</LINE>
+<LINE>the hip upward, no doublet. Unless he have a fancy</LINE>
+<LINE>to this foolery, as it appears he hath, he is no</LINE>
+<LINE>fool for fancy, as you would have it appear he is.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>If he be not in love with some woman, there is no</LINE>
+<LINE>believing old signs: a' brushes his hat o'</LINE>
+<LINE>mornings; what should that bode?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>Hath any man seen him at the barber's?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>No, but the barber's man hath been seen with him,</LINE>
+<LINE>and the old ornament of his cheek hath already</LINE>
+<LINE>stuffed tennis-balls.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>Indeed, he looks younger than he did, by the loss of a beard.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>Nay, a' rubs himself with civet: can you smell him</LINE>
+<LINE>out by that?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>That's as much as to say, the sweet youth's in love.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>The greatest note of it is his melancholy.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>And when was he wont to wash his face?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>Yea, or to paint himself? for the which, I hear</LINE>
+<LINE>what they say of him.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>Nay, but his jesting spirit; which is now crept into</LINE>
+<LINE>a lute-string and now governed by stops.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>Indeed, that tells a heavy tale for him: conclude,</LINE>
+<LINE>conclude he is in love.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>Nay, but I know who loves him.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>That would I know too: I warrant, one that knows him not.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>Yes, and his ill conditions; and, in despite of</LINE>
+<LINE>all, dies for him.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>She shall be buried with her face upwards.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>Yet is this no charm for the toothache. Old</LINE>
+<LINE>signior, walk aside with me: I have studied eight</LINE>
+<LINE>or nine wise words to speak to you, which these</LINE>
+<LINE>hobby-horses must not hear.</LINE>
+</SPEECH>
+
+
+<STAGEDIR>Exeunt BENEDICK and LEONATO</STAGEDIR>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>For my life, to break with him about Beatrice.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>'Tis even so. Hero and Margaret have by this</LINE>
+<LINE>played their parts with Beatrice; and then the two</LINE>
+<LINE>bears will not bite one another when they meet.</LINE>
+</SPEECH>
+
+
+<STAGEDIR>Enter DON JOHN</STAGEDIR>
+
+<SPEECH>
+<SPEAKER>DON JOHN</SPEAKER>
+<LINE>My lord and brother, God save you!</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>Good den, brother.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON JOHN</SPEAKER>
+<LINE>If your leisure served, I would speak with you.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>In private?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON JOHN</SPEAKER>
+<LINE>If it please you: yet Count Claudio may hear; for</LINE>
+<LINE>what I would speak of concerns him.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>What's the matter?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON JOHN</SPEAKER>
+<LINE><STAGEDIR>To CLAUDIO</STAGEDIR>  Means your lordship to be married</LINE>
+<LINE>to-morrow?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>You know he does.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON JOHN</SPEAKER>
+<LINE>I know not that, when he knows what I know.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>If there be any impediment, I pray you discover it.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON JOHN</SPEAKER>
+<LINE>You may think I love you not: let that appear</LINE>
+<LINE>hereafter, and aim better at me by that I now will</LINE>
+<LINE>manifest. For my brother, I think he holds you</LINE>
+<LINE>well, and in dearness of heart hath holp to effect</LINE>
+<LINE>your ensuing marriage;--surely suit ill spent and</LINE>
+<LINE>labour ill bestowed.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>Why, what's the matter?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON JOHN</SPEAKER>
+<LINE>I came hither to tell you; and, circumstances</LINE>
+<LINE>shortened, for she has been too long a talking of,</LINE>
+<LINE>the lady is disloyal.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>Who, Hero?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>Even she; Leonato's Hero, your Hero, every man's Hero:</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>Disloyal?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON JOHN</SPEAKER>
+<LINE>The word is too good to paint out her wickedness; I</LINE>
+<LINE>could say she were worse: think you of a worse</LINE>
+<LINE>title, and I will fit her to it. Wonder not till</LINE>
+<LINE>further warrant: go but with me to-night, you shall</LINE>
+<LINE>see her chamber-window entered, even the night</LINE>
+<LINE>before her wedding-day: if you love her then,</LINE>
+<LINE>to-morrow wed her; but it would better fit your honour</LINE>
+<LINE>to change your mind.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>May this be so?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>I will not think it.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON JOHN</SPEAKER>
+<LINE>If you dare not trust that you see, confess not</LINE>
+<LINE>that you know: if you will follow me, I will show</LINE>
+<LINE>you enough; and when you have seen more and heard</LINE>
+<LINE>more, proceed accordingly.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>If I see any thing to-night why I should not marry</LINE>
+<LINE>her to-morrow in the congregation, where I should</LINE>
+<LINE>wed, there will I shame her.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>And, as I wooed for thee to obtain her, I will join</LINE>
+<LINE>with thee to disgrace her.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON JOHN</SPEAKER>
+<LINE>I will disparage her no farther till you are my</LINE>
+<LINE>witnesses: bear it coldly but till midnight, and</LINE>
+<LINE>let the issue show itself.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>O day untowardly turned!</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>O mischief strangely thwarting!</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON JOHN</SPEAKER>
+<LINE>O plague right well prevented! so will you say when</LINE>
+<LINE>you have seen the sequel.</LINE>
+</SPEECH>
+
+
+<STAGEDIR>Exeunt</STAGEDIR>
+</SCENE>
+
+<SCENE><TITLE>SCENE III.  A street.</TITLE>
+<STAGEDIR>Enter DOGBERRY and VERGES with the Watch</STAGEDIR>
+
+<SPEECH>
+<SPEAKER>DOGBERRY</SPEAKER>
+<LINE>Are you good men and true?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>VERGES</SPEAKER>
+<LINE>Yea, or else it were pity but they should suffer</LINE>
+<LINE>salvation, body and soul.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DOGBERRY</SPEAKER>
+<LINE>Nay, that were a punishment too good for them, if</LINE>
+<LINE>they should have any allegiance in them, being</LINE>
+<LINE>chosen for the prince's watch.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>VERGES</SPEAKER>
+<LINE>Well, give them their charge, neighbour Dogberry.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DOGBERRY</SPEAKER>
+<LINE>First, who think you the most desertless man to be</LINE>
+<LINE>constable?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>First Watchman</SPEAKER>
+<LINE>Hugh Otecake, sir, or George Seacole; for they can</LINE>
+<LINE>write and read.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DOGBERRY</SPEAKER>
+<LINE>Come hither, neighbour Seacole. God hath blessed</LINE>
+<LINE>you with a good name: to be a well-favoured man is</LINE>
+<LINE>the gift of fortune; but to write and read comes by nature.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>Second Watchman</SPEAKER>
+<LINE>Both which, master constable,--</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DOGBERRY</SPEAKER>
+<LINE>You have: I knew it would be your answer. Well,</LINE>
+<LINE>for your favour, sir, why, give God thanks, and make</LINE>
+<LINE>no boast of it; and for your writing and reading,</LINE>
+<LINE>let that appear when there is no need of such</LINE>
+<LINE>vanity. You are thought here to be the most</LINE>
+<LINE>senseless and fit man for the constable of the</LINE>
+<LINE>watch; therefore bear you the lantern. This is your</LINE>
+<LINE>charge: you shall comprehend all vagrom men; you are</LINE>
+<LINE>to bid any man stand, in the prince's name.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>Second Watchman</SPEAKER>
+<LINE>How if a' will not stand?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DOGBERRY</SPEAKER>
+<LINE>Why, then, take no note of him, but let him go; and</LINE>
+<LINE>presently call the rest of the watch together and</LINE>
+<LINE>thank God you are rid of a knave.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>VERGES</SPEAKER>
+<LINE>If he will not stand when he is bidden, he is none</LINE>
+<LINE>of the prince's subjects.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DOGBERRY</SPEAKER>
+<LINE>True, and they are to meddle with none but the</LINE>
+<LINE>prince's subjects. You shall also make no noise in</LINE>
+<LINE>the streets; for, for the watch to babble and to</LINE>
+<LINE>talk is most tolerable and not to be endured.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>Watchman</SPEAKER>
+<LINE>We will rather sleep than talk: we know what</LINE>
+<LINE>belongs to a watch.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DOGBERRY</SPEAKER>
+<LINE>Why, you speak like an ancient and most quiet</LINE>
+<LINE>watchman; for I cannot see how sleeping should</LINE>
+<LINE>offend: only, have a care that your bills be not</LINE>
+<LINE>stolen. Well, you are to call at all the</LINE>
+<LINE>ale-houses, and bid those that are drunk get them to bed.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>Watchman</SPEAKER>
+<LINE>How if they will not?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DOGBERRY</SPEAKER>
+<LINE>Why, then, let them alone till they are sober: if</LINE>
+<LINE>they make you not then the better answer, you may</LINE>
+<LINE>say they are not the men you took them for.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>Watchman</SPEAKER>
+<LINE>Well, sir.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DOGBERRY</SPEAKER>
+<LINE>If you meet a thief, you may suspect him, by virtue</LINE>
+<LINE>of your office, to be no true man; and, for such</LINE>
+<LINE>kind of men, the less you meddle or make with them,</LINE>
+<LINE>why the more is for your honesty.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>Watchman</SPEAKER>
+<LINE>If we know him to be a thief, shall we not lay</LINE>
+<LINE>hands on him?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DOGBERRY</SPEAKER>
+<LINE>Truly, by your office, you may; but I think they</LINE>
+<LINE>that touch pitch will be defiled: the most peaceable</LINE>
+<LINE>way for you, if you do take a thief, is to let him</LINE>
+<LINE>show himself what he is and steal out of your company.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>VERGES</SPEAKER>
+<LINE>You have been always called a merciful man, partner.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DOGBERRY</SPEAKER>
+<LINE>Truly, I would not hang a dog by my will, much more</LINE>
+<LINE>a man who hath any honesty in him.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>VERGES</SPEAKER>
+<LINE>If you hear a child cry in the night, you must call</LINE>
+<LINE>to the nurse and bid her still it.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>Watchman</SPEAKER>
+<LINE>How if the nurse be asleep and will not hear us?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DOGBERRY</SPEAKER>
+<LINE>Why, then, depart in peace, and let the child wake</LINE>
+<LINE>her with crying; for the ewe that will not hear her</LINE>
+<LINE>lamb when it baes will never answer a calf when he bleats.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>VERGES</SPEAKER>
+<LINE>'Tis very true.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DOGBERRY</SPEAKER>
+<LINE>This is the end of the charge:--you, constable, are</LINE>
+<LINE>to present the prince's own person: if you meet the</LINE>
+<LINE>prince in the night, you may stay him.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>VERGES</SPEAKER>
+<LINE>Nay, by'r our lady, that I think a' cannot.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DOGBERRY</SPEAKER>
+<LINE>Five shillings to one on't, with any man that knows</LINE>
+<LINE>the statutes, he may stay him: marry, not without</LINE>
+<LINE>the prince be willing; for, indeed, the watch ought</LINE>
+<LINE>to offend no man; and it is an offence to stay a</LINE>
+<LINE>man against his will.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>VERGES</SPEAKER>
+<LINE>By'r lady, I think it be so.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DOGBERRY</SPEAKER>
+<LINE>Ha, ha, ha! Well, masters, good night: an there be</LINE>
+<LINE>any matter of weight chances, call up me: keep your</LINE>
+<LINE>fellows' counsels and your own; and good night.</LINE>
+<LINE>Come, neighbour.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>Watchman</SPEAKER>
+<LINE>Well, masters, we hear our charge: let us go sit here</LINE>
+<LINE>upon the church-bench till two, and then all to bed.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DOGBERRY</SPEAKER>
+<LINE>One word more, honest neighbours. I pray you watch</LINE>
+<LINE>about Signior Leonato's door; for the wedding being</LINE>
+<LINE>there to-morrow, there is a great coil to-night.</LINE>
+<LINE>Adieu: be vigitant, I beseech you.</LINE>
+</SPEECH>
+
+<STAGEDIR>Exeunt DOGBERRY and VERGES</STAGEDIR>
+<STAGEDIR>Enter BORACHIO and CONRADE</STAGEDIR>
+
+<SPEECH>
+<SPEAKER>BORACHIO</SPEAKER>
+<LINE>What Conrade!</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>Watchman</SPEAKER>
+<LINE><STAGEDIR>Aside</STAGEDIR>  Peace! stir not.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BORACHIO</SPEAKER>
+<LINE>Conrade, I say!</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CONRADE</SPEAKER>
+<LINE>Here, man; I am at thy elbow.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BORACHIO</SPEAKER>
+<LINE>Mass, and my elbow itched; I thought there would a</LINE>
+<LINE>scab follow.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CONRADE</SPEAKER>
+<LINE>I will owe thee an answer for that: and now forward</LINE>
+<LINE>with thy tale.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BORACHIO</SPEAKER>
+<LINE>Stand thee close, then, under this pent-house, for</LINE>
+<LINE>it drizzles rain; and I will, like a true drunkard,</LINE>
+<LINE>utter all to thee.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>Watchman</SPEAKER>
+<LINE><STAGEDIR>Aside</STAGEDIR>  Some treason, masters: yet stand close.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BORACHIO</SPEAKER>
+<LINE>Therefore know I have earned of Don John a thousand ducats.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CONRADE</SPEAKER>
+<LINE>Is it possible that any villany should be so dear?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BORACHIO</SPEAKER>
+<LINE>Thou shouldst rather ask if it were possible any</LINE>
+<LINE>villany should be so rich; for when rich villains</LINE>
+<LINE>have need of poor ones, poor ones may make what</LINE>
+<LINE>price they will.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CONRADE</SPEAKER>
+<LINE>I wonder at it.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BORACHIO</SPEAKER>
+<LINE>That shows thou art unconfirmed. Thou knowest that</LINE>
+<LINE>the fashion of a doublet, or a hat, or a cloak, is</LINE>
+<LINE>nothing to a man.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CONRADE</SPEAKER>
+<LINE>Yes, it is apparel.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BORACHIO</SPEAKER>
+<LINE>I mean, the fashion.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CONRADE</SPEAKER>
+<LINE>Yes, the fashion is the fashion.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BORACHIO</SPEAKER>
+<LINE>Tush! I may as well say the fool's the fool. But</LINE>
+<LINE>seest thou not what a deformed thief this fashion</LINE>
+<LINE>is?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>Watchman</SPEAKER>
+<LINE><STAGEDIR>Aside</STAGEDIR>  I know that Deformed; a' has been a vile</LINE>
+<LINE>thief this seven year; a' goes up and down like a</LINE>
+<LINE>gentleman: I remember his name.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BORACHIO</SPEAKER>
+<LINE>Didst thou not hear somebody?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CONRADE</SPEAKER>
+<LINE>No; 'twas the vane on the house.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BORACHIO</SPEAKER>
+<LINE>Seest thou not, I say, what a deformed thief this</LINE>
+<LINE>fashion is? how giddily a' turns about all the hot</LINE>
+<LINE>bloods between fourteen and five-and-thirty?</LINE>
+<LINE>sometimes fashioning them like Pharaoh's soldiers</LINE>
+<LINE>in the reeky painting, sometime like god Bel's</LINE>
+<LINE>priests in the old church-window, sometime like the</LINE>
+<LINE>shaven Hercules in the smirched worm-eaten tapestry,</LINE>
+<LINE>where his codpiece seems as massy as his club?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CONRADE</SPEAKER>
+<LINE>All this I see; and I see that the fashion wears</LINE>
+<LINE>out more apparel than the man. But art not thou</LINE>
+<LINE>thyself giddy with the fashion too, that thou hast</LINE>
+<LINE>shifted out of thy tale into telling me of the fashion?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BORACHIO</SPEAKER>
+<LINE>Not so, neither: but know that I have to-night</LINE>
+<LINE>wooed Margaret, the Lady Hero's gentlewoman, by the</LINE>
+<LINE>name of Hero: she leans me out at her mistress'</LINE>
+<LINE>chamber-window, bids me a thousand times good</LINE>
+<LINE>night,--I tell this tale vilely:--I should first</LINE>
+<LINE>tell thee how the prince, Claudio and my master,</LINE>
+<LINE>planted and placed and possessed by my master Don</LINE>
+<LINE>John, saw afar off in the orchard this amiable encounter.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CONRADE</SPEAKER>
+<LINE>And thought they Margaret was Hero?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BORACHIO</SPEAKER>
+<LINE>Two of them did, the prince and Claudio; but the</LINE>
+<LINE>devil my master knew she was Margaret; and partly</LINE>
+<LINE>by his oaths, which first possessed them, partly by</LINE>
+<LINE>the dark night, which did deceive them, but chiefly</LINE>
+<LINE>by my villany, which did confirm any slander that</LINE>
+<LINE>Don John had made, away went Claudio enraged; swore</LINE>
+<LINE>he would meet her, as he was appointed, next morning</LINE>
+<LINE>at the temple, and there, before the whole</LINE>
+<LINE>congregation, shame her with what he saw o'er night</LINE>
+<LINE>and send her home again without a husband.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>First Watchman</SPEAKER>
+<LINE>We charge you, in the prince's name, stand!</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>Second Watchman</SPEAKER>
+<LINE>Call up the right master constable. We have here</LINE>
+<LINE>recovered the most dangerous piece of lechery that</LINE>
+<LINE>ever was known in the commonwealth.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>First Watchman</SPEAKER>
+<LINE>And one Deformed is one of them: I know him; a'</LINE>
+<LINE>wears a lock.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CONRADE</SPEAKER>
+<LINE>Masters, masters,--</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>Second Watchman</SPEAKER>
+<LINE>You'll be made bring Deformed forth, I warrant you.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CONRADE</SPEAKER>
+<LINE>Masters,--</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>First Watchman</SPEAKER>
+<LINE>Never speak: we charge you let us obey you to go with us.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BORACHIO</SPEAKER>
+<LINE>We are like to prove a goodly commodity, being taken</LINE>
+<LINE>up of these men's bills.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CONRADE</SPEAKER>
+<LINE>A commodity in question, I warrant you. Come, we'll obey you.</LINE>
+</SPEECH>
+
+
+<STAGEDIR>Exeunt</STAGEDIR>
+</SCENE>
+
+<SCENE><TITLE>SCENE IV.  HERO's apartment.</TITLE>
+<STAGEDIR>Enter HERO, MARGARET, and URSULA</STAGEDIR>
+
+<SPEECH>
+<SPEAKER>HERO</SPEAKER>
+<LINE>Good Ursula, wake my cousin Beatrice, and desire</LINE>
+<LINE>her to rise.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>URSULA</SPEAKER>
+<LINE>I will, lady.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>HERO</SPEAKER>
+<LINE>And bid her come hither.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>URSULA</SPEAKER>
+<LINE>Well.</LINE>
+</SPEECH>
+
+
+<STAGEDIR>Exit</STAGEDIR>
+
+<SPEECH>
+<SPEAKER>MARGARET</SPEAKER>
+<LINE>Troth, I think your other rabato were better.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>HERO</SPEAKER>
+<LINE>No, pray thee, good Meg, I'll wear this.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>MARGARET</SPEAKER>
+<LINE>By my troth, 's not so good; and I warrant your</LINE>
+<LINE>cousin will say so.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>HERO</SPEAKER>
+<LINE>My cousin's a fool, and thou art another: I'll wear</LINE>
+<LINE>none but this.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>MARGARET</SPEAKER>
+<LINE>I like the new tire within excellently, if the hair</LINE>
+<LINE>were a thought browner; and your gown's a most rare</LINE>
+<LINE>fashion, i' faith. I saw the Duchess of Milan's</LINE>
+<LINE>gown that they praise so.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>HERO</SPEAKER>
+<LINE>O, that exceeds, they say.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>MARGARET</SPEAKER>
+<LINE>By my troth, 's but a night-gown in respect of</LINE>
+<LINE>yours: cloth o' gold, and cuts, and laced with</LINE>
+<LINE>silver, set with pearls, down sleeves, side sleeves,</LINE>
+<LINE>and skirts, round underborne with a bluish tinsel:</LINE>
+<LINE>but for a fine, quaint, graceful and excellent</LINE>
+<LINE>fashion, yours is worth ten on 't.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>HERO</SPEAKER>
+<LINE>God give me joy to wear it! for my heart is</LINE>
+<LINE>exceeding heavy.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>MARGARET</SPEAKER>
+<LINE>'Twill be heavier soon by the weight of a man.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>HERO</SPEAKER>
+<LINE>Fie upon thee! art not ashamed?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>MARGARET</SPEAKER>
+<LINE>Of what, lady? of speaking honourably? Is not</LINE>
+<LINE>marriage honourable in a beggar? Is not your lord</LINE>
+<LINE>honourable without marriage? I think you would have</LINE>
+<LINE>me say, 'saving your reverence, a husband:' and bad</LINE>
+<LINE>thinking do not wrest true speaking, I'll offend</LINE>
+<LINE>nobody: is there any harm in 'the heavier for a</LINE>
+<LINE>husband'? None, I think, and it be the right husband</LINE>
+<LINE>and the right wife; otherwise 'tis light, and not</LINE>
+<LINE>heavy: ask my Lady Beatrice else; here she comes.</LINE>
+</SPEECH>
+
+
+<STAGEDIR>Enter BEATRICE</STAGEDIR>
+
+<SPEECH>
+<SPEAKER>HERO</SPEAKER>
+<LINE>Good morrow, coz.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>Good morrow, sweet Hero.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>HERO</SPEAKER>
+<LINE>Why how now? do you speak in the sick tune?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>I am out of all other tune, methinks.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>MARGARET</SPEAKER>
+<LINE>Clap's into 'Light o' love;' that goes without a</LINE>
+<LINE>burden: do you sing it, and I'll dance it.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>Ye light o' love, with your heels! then, if your</LINE>
+<LINE>husband have stables enough, you'll see he shall</LINE>
+<LINE>lack no barns.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>MARGARET</SPEAKER>
+<LINE>O illegitimate construction! I scorn that with my heels.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>'Tis almost five o'clock, cousin; tis time you were</LINE>
+<LINE>ready. By my troth, I am exceeding ill: heigh-ho!</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>MARGARET</SPEAKER>
+<LINE>For a hawk, a horse, or a husband?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>For the letter that begins them all, H.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>MARGARET</SPEAKER>
+<LINE>Well, and you be not turned Turk, there's no more</LINE>
+<LINE>sailing by the star.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>What means the fool, trow?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>MARGARET</SPEAKER>
+<LINE>Nothing I; but God send every one their heart's desire!</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>HERO</SPEAKER>
+<LINE>These gloves the count sent me; they are an</LINE>
+<LINE>excellent perfume.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>I am stuffed, cousin; I cannot smell.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>MARGARET</SPEAKER>
+<LINE>A maid, and stuffed! there's goodly catching of cold.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>O, God help me! God help me! how long have you</LINE>
+<LINE>professed apprehension?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>MARGARET</SPEAKER>
+<LINE>Even since you left it. Doth not my wit become me rarely?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>It is not seen enough, you should wear it in your</LINE>
+<LINE>cap. By my troth, I am sick.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>MARGARET</SPEAKER>
+<LINE>Get you some of this distilled Carduus Benedictus,</LINE>
+<LINE>and lay it to your heart: it is the only thing for a qualm.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>HERO</SPEAKER>
+<LINE>There thou prickest her with a thistle.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>Benedictus! why Benedictus? you have some moral in</LINE>
+<LINE>this Benedictus.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>MARGARET</SPEAKER>
+<LINE>Moral! no, by my troth, I have no moral meaning; I</LINE>
+<LINE>meant, plain holy-thistle. You may think perchance</LINE>
+<LINE>that I think you are in love: nay, by'r lady, I am</LINE>
+<LINE>not such a fool to think what I list, nor I list</LINE>
+<LINE>not to think what I can, nor indeed I cannot think,</LINE>
+<LINE>if I would think my heart out of thinking, that you</LINE>
+<LINE>are in love or that you will be in love or that you</LINE>
+<LINE>can be in love. Yet Benedick was such another, and</LINE>
+<LINE>now is he become a man: he swore he would never</LINE>
+<LINE>marry, and yet now, in despite of his heart, he eats</LINE>
+<LINE>his meat without grudging: and how you may be</LINE>
+<LINE>converted I know not, but methinks you look with</LINE>
+<LINE>your eyes as other women do.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>What pace is this that thy tongue keeps?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>MARGARET</SPEAKER>
+<LINE>Not a false gallop.</LINE>
+</SPEECH>
+
+
+<STAGEDIR>Re-enter URSULA</STAGEDIR>
+
+<SPEECH>
+<SPEAKER>URSULA</SPEAKER>
+<LINE>Madam, withdraw: the prince, the count, Signior</LINE>
+<LINE>Benedick, Don John, and all the gallants of the</LINE>
+<LINE>town, are come to fetch you to church.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>HERO</SPEAKER>
+<LINE>Help to dress me, good coz, good Meg, good Ursula.</LINE>
+</SPEECH>
+
+
+<STAGEDIR>Exeunt</STAGEDIR>
+</SCENE>
+
+<SCENE><TITLE>SCENE V.  Another room in LEONATO'S house.</TITLE>
+<STAGEDIR>Enter LEONATO, with DOGBERRY and VERGES</STAGEDIR>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>What would you with me, honest neighbour?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DOGBERRY</SPEAKER>
+<LINE>Marry, sir, I would have some confidence with you</LINE>
+<LINE>that decerns you nearly.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>Brief, I pray you; for you see it is a busy time with me.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DOGBERRY</SPEAKER>
+<LINE>Marry, this it is, sir.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>VERGES</SPEAKER>
+<LINE>Yes, in truth it is, sir.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>What is it, my good friends?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DOGBERRY</SPEAKER>
+<LINE>Goodman Verges, sir, speaks a little off the</LINE>
+<LINE>matter: an old man, sir, and his wits are not so</LINE>
+<LINE>blunt as, God help, I would desire they were; but,</LINE>
+<LINE>in faith, honest as the skin between his brows.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>VERGES</SPEAKER>
+<LINE>Yes, I thank God I am as honest as any man living</LINE>
+<LINE>that is an old man and no honester than I.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DOGBERRY</SPEAKER>
+<LINE>Comparisons are odorous: palabras, neighbour Verges.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>Neighbours, you are tedious.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DOGBERRY</SPEAKER>
+<LINE>It pleases your worship to say so, but we are the</LINE>
+<LINE>poor duke's officers; but truly, for mine own part,</LINE>
+<LINE>if I were as tedious as a king, I could find it in</LINE>
+<LINE>my heart to bestow it all of your worship.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>All thy tediousness on me, ah?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DOGBERRY</SPEAKER>
+<LINE>Yea, an 'twere a thousand pound more than 'tis; for</LINE>
+<LINE>I hear as good exclamation on your worship as of any</LINE>
+<LINE>man in the city; and though I be but a poor man, I</LINE>
+<LINE>am glad to hear it.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>VERGES</SPEAKER>
+<LINE>And so am I.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>I would fain know what you have to say.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>VERGES</SPEAKER>
+<LINE>Marry, sir, our watch to-night, excepting your</LINE>
+<LINE>worship's presence, ha' ta'en a couple of as arrant</LINE>
+<LINE>knaves as any in Messina.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DOGBERRY</SPEAKER>
+<LINE>A good old man, sir; he will be talking: as they</LINE>
+<LINE>say, when the age is in, the wit is out: God help</LINE>
+<LINE>us! it is a world to see. Well said, i' faith,</LINE>
+<LINE>neighbour Verges: well, God's a good man; an two men</LINE>
+<LINE>ride of a horse, one must ride behind. An honest</LINE>
+<LINE>soul, i' faith, sir; by my troth he is, as ever</LINE>
+<LINE>broke bread; but God is to be worshipped; all men</LINE>
+<LINE>are not alike; alas, good neighbour!</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>Indeed, neighbour, he comes too short of you.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DOGBERRY</SPEAKER>
+<LINE>Gifts that God gives.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>I must leave you.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DOGBERRY</SPEAKER>
+<LINE>One word, sir: our watch, sir, have indeed</LINE>
+<LINE>comprehended two aspicious persons, and we would</LINE>
+<LINE>have them this morning examined before your worship.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>Take their examination yourself and bring it me: I</LINE>
+<LINE>am now in great haste, as it may appear unto you.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DOGBERRY</SPEAKER>
+<LINE>It shall be suffigance.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>Drink some wine ere you go: fare you well.</LINE>
+</SPEECH>
+
+
+<STAGEDIR>Enter a Messenger</STAGEDIR>
+
+<SPEECH>
+<SPEAKER>Messenger</SPEAKER>
+<LINE>My lord, they stay for you to give your daughter to</LINE>
+<LINE>her husband.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>I'll wait upon them: I am ready.</LINE>
+</SPEECH>
+
+
+<STAGEDIR>Exeunt LEONATO and Messenger</STAGEDIR>
+
+<SPEECH>
+<SPEAKER>DOGBERRY</SPEAKER>
+<LINE>Go, good partner, go, get you to Francis Seacole;</LINE>
+<LINE>bid him bring his pen and inkhorn to the gaol: we</LINE>
+<LINE>are now to examination these men.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>VERGES</SPEAKER>
+<LINE>And we must do it wisely.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DOGBERRY</SPEAKER>
+<LINE>We will spare for no wit, I warrant you; here's</LINE>
+<LINE>that shall drive some of them to a non-come: only</LINE>
+<LINE>get the learned writer to set down our</LINE>
+<LINE>excommunication and meet me at the gaol.</LINE>
+</SPEECH>
+
+
+<STAGEDIR>Exeunt</STAGEDIR>
+</SCENE>
+
+</ACT>
+
+<ACT><TITLE>ACT IV</TITLE>
+
+<SCENE><TITLE>SCENE I.  A church.</TITLE>
+<STAGEDIR>Enter DON PEDRO, DON JOHN, LEONATO, FRIAR FRANCIS,
+CLAUDIO, BENEDICK, HERO, BEATRICE, and Attendants</STAGEDIR>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>Come, Friar Francis, be brief; only to the plain</LINE>
+<LINE>form of marriage, and you shall recount their</LINE>
+<LINE>particular duties afterwards.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>FRIAR FRANCIS</SPEAKER>
+<LINE>You come hither, my lord, to marry this lady.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>No.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>To be married to her: friar, you come to marry her.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>FRIAR FRANCIS</SPEAKER>
+<LINE>Lady, you come hither to be married to this count.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>HERO</SPEAKER>
+<LINE>I do.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>FRIAR FRANCIS</SPEAKER>
+<LINE>If either of you know any inward impediment why you</LINE>
+<LINE>should not be conjoined, charge you, on your souls,</LINE>
+<LINE>to utter it.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>Know you any, Hero?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>HERO</SPEAKER>
+<LINE>None, my lord.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>FRIAR FRANCIS</SPEAKER>
+<LINE>Know you any, count?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>I dare make his answer, none.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>O, what men dare do! what men may do! what men daily</LINE>
+<LINE>do, not knowing what they do!</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>How now! interjections? Why, then, some be of</LINE>
+<LINE>laughing, as, ah, ha, he!</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>Stand thee by, friar. Father, by your leave:</LINE>
+<LINE>Will you with free and unconstrained soul</LINE>
+<LINE>Give me this maid, your daughter?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>As freely, son, as God did give her me.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>And what have I to give you back, whose worth</LINE>
+<LINE>May counterpoise this rich and precious gift?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>Nothing, unless you render her again.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>Sweet prince, you learn me noble thankfulness.</LINE>
+<LINE>There, Leonato, take her back again:</LINE>
+<LINE>Give not this rotten orange to your friend;</LINE>
+<LINE>She's but the sign and semblance of her honour.</LINE>
+<LINE>Behold how like a maid she blushes here!</LINE>
+<LINE>O, what authority and show of truth</LINE>
+<LINE>Can cunning sin cover itself withal!</LINE>
+<LINE>Comes not that blood as modest evidence</LINE>
+<LINE>To witness simple virtue? Would you not swear,</LINE>
+<LINE>All you that see her, that she were a maid,</LINE>
+<LINE>By these exterior shows? But she is none:</LINE>
+<LINE>She knows the heat of a luxurious bed;</LINE>
+<LINE>Her blush is guiltiness, not modesty.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>What do you mean, my lord?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>Not to be married,</LINE>
+<LINE>Not to knit my soul to an approved wanton.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>Dear my lord, if you, in your own proof,</LINE>
+<LINE>Have vanquish'd the resistance of her youth,</LINE>
+<LINE>And made defeat of her virginity,--</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>I know what you would say: if I have known her,</LINE>
+<LINE>You will say she did embrace me as a husband,</LINE>
+<LINE>And so extenuate the 'forehand sin:</LINE>
+<LINE>No, Leonato,</LINE>
+<LINE>I never tempted her with word too large;</LINE>
+<LINE>But, as a brother to his sister, show'd</LINE>
+<LINE>Bashful sincerity and comely love.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>HERO</SPEAKER>
+<LINE>And seem'd I ever otherwise to you?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>Out on thee! Seeming! I will write against it:</LINE>
+<LINE>You seem to me as Dian in her orb,</LINE>
+<LINE>As chaste as is the bud ere it be blown;</LINE>
+<LINE>But you are more intemperate in your blood</LINE>
+<LINE>Than Venus, or those pamper'd animals</LINE>
+<LINE>That rage in savage sensuality.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>HERO</SPEAKER>
+<LINE>Is my lord well, that he doth speak so wide?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>Sweet prince, why speak not you?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>What should I speak?</LINE>
+<LINE>I stand dishonour'd, that have gone about</LINE>
+<LINE>To link my dear friend to a common stale.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>Are these things spoken, or do I but dream?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON JOHN</SPEAKER>
+<LINE>Sir, they are spoken, and these things are true.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>This looks not like a nuptial.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>HERO</SPEAKER>
+<LINE>True! O God!</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>Leonato, stand I here?</LINE>
+<LINE>Is this the prince? is this the prince's brother?</LINE>
+<LINE>Is this face Hero's? are our eyes our own?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>All this is so: but what of this, my lord?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>Let me but move one question to your daughter;</LINE>
+<LINE>And, by that fatherly and kindly power</LINE>
+<LINE>That you have in her, bid her answer truly.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>I charge thee do so, as thou art my child.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>HERO</SPEAKER>
+<LINE>O, God defend me! how am I beset!</LINE>
+<LINE>What kind of catechising call you this?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>To make you answer truly to your name.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>HERO</SPEAKER>
+<LINE>Is it not Hero? Who can blot that name</LINE>
+<LINE>With any just reproach?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>Marry, that can Hero;</LINE>
+<LINE>Hero itself can blot out Hero's virtue.</LINE>
+<LINE>What man was he talk'd with you yesternight</LINE>
+<LINE>Out at your window betwixt twelve and one?</LINE>
+<LINE>Now, if you are a maid, answer to this.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>HERO</SPEAKER>
+<LINE>I talk'd with no man at that hour, my lord.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>Why, then are you no maiden. Leonato,</LINE>
+<LINE>I am sorry you must hear: upon mine honour,</LINE>
+<LINE>Myself, my brother and this grieved count</LINE>
+<LINE>Did see her, hear her, at that hour last night</LINE>
+<LINE>Talk with a ruffian at her chamber-window</LINE>
+<LINE>Who hath indeed, most like a liberal villain,</LINE>
+<LINE>Confess'd the vile encounters they have had</LINE>
+<LINE>A thousand times in secret.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON JOHN</SPEAKER>
+<LINE>Fie, fie! they are not to be named, my lord,</LINE>
+<LINE>Not to be spoke of;</LINE>
+<LINE>There is not chastity enough in language</LINE>
+<LINE>Without offence to utter them. Thus, pretty lady,</LINE>
+<LINE>I am sorry for thy much misgovernment.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>O Hero, what a Hero hadst thou been,</LINE>
+<LINE>If half thy outward graces had been placed</LINE>
+<LINE>About thy thoughts and counsels of thy heart!</LINE>
+<LINE>But fare thee well, most foul, most fair! farewell,</LINE>
+<LINE>Thou pure impiety and impious purity!</LINE>
+<LINE>For thee I'll lock up all the gates of love,</LINE>
+<LINE>And on my eyelids shall conjecture hang,</LINE>
+<LINE>To turn all beauty into thoughts of harm,</LINE>
+<LINE>And never shall it more be gracious.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>Hath no man's dagger here a point for me?</LINE>
+</SPEECH>
+
+
+<STAGEDIR>HERO swoons</STAGEDIR>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>Why, how now, cousin! wherefore sink you down?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON JOHN</SPEAKER>
+<LINE>Come, let us go. These things, come thus to light,</LINE>
+<LINE>Smother her spirits up.</LINE>
+</SPEECH>
+
+
+<STAGEDIR>Exeunt DON PEDRO, DON JOHN, and CLAUDIO</STAGEDIR>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>How doth the lady?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>Dead, I think. Help, uncle!</LINE>
+<LINE>Hero! why, Hero! Uncle! Signior Benedick! Friar!</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>O Fate! take not away thy heavy hand.</LINE>
+<LINE>Death is the fairest cover for her shame</LINE>
+<LINE>That may be wish'd for.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>How now, cousin Hero!</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>FRIAR FRANCIS</SPEAKER>
+<LINE>Have comfort, lady.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>Dost thou look up?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>FRIAR FRANCIS</SPEAKER>
+<LINE>Yea, wherefore should she not?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>Wherefore! Why, doth not every earthly thing</LINE>
+<LINE>Cry shame upon her? Could she here deny</LINE>
+<LINE>The story that is printed in her blood?</LINE>
+<LINE>Do not live, Hero; do not ope thine eyes:</LINE>
+<LINE>For, did I think thou wouldst not quickly die,</LINE>
+<LINE>Thought I thy spirits were stronger than thy shames,</LINE>
+<LINE>Myself would, on the rearward of reproaches,</LINE>
+<LINE>Strike at thy life. Grieved I, I had but one?</LINE>
+<LINE>Chid I for that at frugal nature's frame?</LINE>
+<LINE>O, one too much by thee! Why had I one?</LINE>
+<LINE>Why ever wast thou lovely in my eyes?</LINE>
+<LINE>Why had I not with charitable hand</LINE>
+<LINE>Took up a beggar's issue at my gates,</LINE>
+<LINE>Who smirch'd thus and mired with infamy,</LINE>
+<LINE>I might have said 'No part of it is mine;</LINE>
+<LINE>This shame derives itself from unknown loins'?</LINE>
+<LINE>But mine and mine I loved and mine I praised</LINE>
+<LINE>And mine that I was proud on, mine so much</LINE>
+<LINE>That I myself was to myself not mine,</LINE>
+<LINE>Valuing of her,--why, she, O, she is fallen</LINE>
+<LINE>Into a pit of ink, that the wide sea</LINE>
+<LINE>Hath drops too few to wash her clean again</LINE>
+<LINE>And salt too little which may season give</LINE>
+<LINE>To her foul-tainted flesh!</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>Sir, sir, be patient.</LINE>
+<LINE>For my part, I am so attired in wonder,</LINE>
+<LINE>I know not what to say.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>O, on my soul, my cousin is belied!</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>Lady, were you her bedfellow last night?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>No, truly not; although, until last night,</LINE>
+<LINE>I have this twelvemonth been her bedfellow.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>Confirm'd, confirm'd! O, that is stronger made</LINE>
+<LINE>Which was before barr'd up with ribs of iron!</LINE>
+<LINE>Would the two princes lie, and Claudio lie,</LINE>
+<LINE>Who loved her so, that, speaking of her foulness,</LINE>
+<LINE>Wash'd it with tears? Hence from her! let her die.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>FRIAR FRANCIS</SPEAKER>
+<LINE>Hear me a little; for I have only been</LINE>
+<LINE>Silent so long and given way unto</LINE>
+<LINE>This course of fortune</LINE>
+<LINE>By noting of the lady. I have mark'd</LINE>
+<LINE>A thousand blushing apparitions</LINE>
+<LINE>To start into her face, a thousand innocent shames</LINE>
+<LINE>In angel whiteness beat away those blushes;</LINE>
+<LINE>And in her eye there hath appear'd a fire,</LINE>
+<LINE>To burn the errors that these princes hold</LINE>
+<LINE>Against her maiden truth. Call me a fool;</LINE>
+<LINE>Trust not my reading nor my observations,</LINE>
+<LINE>Which with experimental seal doth warrant</LINE>
+<LINE>The tenor of my book; trust not my age,</LINE>
+<LINE>My reverence, calling, nor divinity,</LINE>
+<LINE>If this sweet lady lie not guiltless here</LINE>
+<LINE>Under some biting error.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>Friar, it cannot be.</LINE>
+<LINE>Thou seest that all the grace that she hath left</LINE>
+<LINE>Is that she will not add to her damnation</LINE>
+<LINE>A sin of perjury; she not denies it:</LINE>
+<LINE>Why seek'st thou then to cover with excuse</LINE>
+<LINE>That which appears in proper nakedness?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>FRIAR FRANCIS</SPEAKER>
+<LINE>Lady, what man is he you are accused of?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>HERO</SPEAKER>
+<LINE>They know that do accuse me; I know none:</LINE>
+<LINE>If I know more of any man alive</LINE>
+<LINE>Than that which maiden modesty doth warrant,</LINE>
+<LINE>Let all my sins lack mercy! O my father,</LINE>
+<LINE>Prove you that any man with me conversed</LINE>
+<LINE>At hours unmeet, or that I yesternight</LINE>
+<LINE>Maintain'd the change of words with any creature,</LINE>
+<LINE>Refuse me, hate me, torture me to death!</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>FRIAR FRANCIS</SPEAKER>
+<LINE>There is some strange misprision in the princes.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>Two of them have the very bent of honour;</LINE>
+<LINE>And if their wisdoms be misled in this,</LINE>
+<LINE>The practise of it lives in John the bastard,</LINE>
+<LINE>Whose spirits toil in frame of villanies.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>I know not. If they speak but truth of her,</LINE>
+<LINE>These hands shall tear her; if they wrong her honour,</LINE>
+<LINE>The proudest of them shall well hear of it.</LINE>
+<LINE>Time hath not yet so dried this blood of mine,</LINE>
+<LINE>Nor age so eat up my invention,</LINE>
+<LINE>Nor fortune made such havoc of my means,</LINE>
+<LINE>Nor my bad life reft me so much of friends,</LINE>
+<LINE>But they shall find, awaked in such a kind,</LINE>
+<LINE>Both strength of limb and policy of mind,</LINE>
+<LINE>Ability in means and choice of friends,</LINE>
+<LINE>To quit me of them throughly.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>FRIAR FRANCIS</SPEAKER>
+<LINE>Pause awhile,</LINE>
+<LINE>And let my counsel sway you in this case.</LINE>
+<LINE>Your daughter here the princes left for dead:</LINE>
+<LINE>Let her awhile be secretly kept in,</LINE>
+<LINE>And publish it that she is dead indeed;</LINE>
+<LINE>Maintain a mourning ostentation</LINE>
+<LINE>And on your family's old monument</LINE>
+<LINE>Hang mournful epitaphs and do all rites</LINE>
+<LINE>That appertain unto a burial.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>What shall become of this? what will this do?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>FRIAR FRANCIS</SPEAKER>
+<LINE>Marry, this well carried shall on her behalf</LINE>
+<LINE>Change slander to remorse; that is some good:</LINE>
+<LINE>But not for that dream I on this strange course,</LINE>
+<LINE>But on this travail look for greater birth.</LINE>
+<LINE>She dying, as it must so be maintain'd,</LINE>
+<LINE>Upon the instant that she was accused,</LINE>
+<LINE>Shall be lamented, pitied and excused</LINE>
+<LINE>Of every hearer: for it so falls out</LINE>
+<LINE>That what we have we prize not to the worth</LINE>
+<LINE>Whiles we enjoy it, but being lack'd and lost,</LINE>
+<LINE>Why, then we rack the value, then we find</LINE>
+<LINE>The virtue that possession would not show us</LINE>
+<LINE>Whiles it was ours. So will it fare with Claudio:</LINE>
+<LINE>When he shall hear she died upon his words,</LINE>
+<LINE>The idea of her life shall sweetly creep</LINE>
+<LINE>Into his study of imagination,</LINE>
+<LINE>And every lovely organ of her life</LINE>
+<LINE>Shall come apparell'd in more precious habit,</LINE>
+<LINE>More moving-delicate and full of life,</LINE>
+<LINE>Into the eye and prospect of his soul,</LINE>
+<LINE>Than when she lived indeed; then shall he mourn,</LINE>
+<LINE>If ever love had interest in his liver,</LINE>
+<LINE>And wish he had not so accused her,</LINE>
+<LINE>No, though he thought his accusation true.</LINE>
+<LINE>Let this be so, and doubt not but success</LINE>
+<LINE>Will fashion the event in better shape</LINE>
+<LINE>Than I can lay it down in likelihood.</LINE>
+<LINE>But if all aim but this be levell'd false,</LINE>
+<LINE>The supposition of the lady's death</LINE>
+<LINE>Will quench the wonder of her infamy:</LINE>
+<LINE>And if it sort not well, you may conceal her,</LINE>
+<LINE>As best befits her wounded reputation,</LINE>
+<LINE>In some reclusive and religious life,</LINE>
+<LINE>Out of all eyes, tongues, minds and injuries.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>Signior Leonato, let the friar advise you:</LINE>
+<LINE>And though you know my inwardness and love</LINE>
+<LINE>Is very much unto the prince and Claudio,</LINE>
+<LINE>Yet, by mine honour, I will deal in this</LINE>
+<LINE>As secretly and justly as your soul</LINE>
+<LINE>Should with your body.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>Being that I flow in grief,</LINE>
+<LINE>The smallest twine may lead me.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>FRIAR FRANCIS</SPEAKER>
+<LINE>'Tis well consented: presently away;</LINE>
+<LINE>For to strange sores strangely they strain the cure.</LINE>
+<LINE>Come, lady, die to live: this wedding-day</LINE>
+<LINE>Perhaps is but prolong'd: have patience and endure.</LINE>
+</SPEECH>
+
+
+<STAGEDIR>Exeunt all but BENEDICK and BEATRICE</STAGEDIR>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>Lady Beatrice, have you wept all this while?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>Yea, and I will weep a while longer.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>I will not desire that.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>You have no reason; I do it freely.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>Surely I do believe your fair cousin is wronged.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>Ah, how much might the man deserve of me that would right her!</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>Is there any way to show such friendship?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>A very even way, but no such friend.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>May a man do it?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>It is a man's office, but not yours.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>I do love nothing in the world so well as you: is</LINE>
+<LINE>not that strange?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>As strange as the thing I know not. It were as</LINE>
+<LINE>possible for me to say I loved nothing so well as</LINE>
+<LINE>you: but believe me not; and yet I lie not; I</LINE>
+<LINE>confess nothing, nor I deny nothing. I am sorry for my cousin.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>By my sword, Beatrice, thou lovest me.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>Do not swear, and eat it.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>I will swear by it that you love me; and I will make</LINE>
+<LINE>him eat it that says I love not you.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>Will you not eat your word?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>With no sauce that can be devised to it. I protest</LINE>
+<LINE>I love thee.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>Why, then, God forgive me!</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>What offence, sweet Beatrice?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>You have stayed me in a happy hour: I was about to</LINE>
+<LINE>protest I loved you.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>And do it with all thy heart.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>I love you with so much of my heart that none is</LINE>
+<LINE>left to protest.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>Come, bid me do any thing for thee.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>Kill Claudio.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>Ha! not for the wide world.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>You kill me to deny it. Farewell.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>Tarry, sweet Beatrice.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>I am gone, though I am here: there is no love in</LINE>
+<LINE>you: nay, I pray you, let me go.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>Beatrice,--</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>In faith, I will go.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>We'll be friends first.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>You dare easier be friends with me than fight with mine enemy.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>Is Claudio thine enemy?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>Is he not approved in the height a villain, that</LINE>
+<LINE>hath slandered, scorned, dishonoured my kinswoman? O</LINE>
+<LINE>that I were a man! What, bear her in hand until they</LINE>
+<LINE>come to take hands; and then, with public</LINE>
+<LINE>accusation, uncovered slander, unmitigated rancour,</LINE>
+<LINE>--O God, that I were a man! I would eat his heart</LINE>
+<LINE>in the market-place.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>Hear me, Beatrice,--</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>Talk with a man out at a window! A proper saying!</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>Nay, but, Beatrice,--</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>Sweet Hero! She is wronged, she is slandered, she is undone.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>Beat--</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>Princes and counties! Surely, a princely testimony,</LINE>
+<LINE>a goodly count, Count Comfect; a sweet gallant,</LINE>
+<LINE>surely! O that I were a man for his sake! or that I</LINE>
+<LINE>had any friend would be a man for my sake! But</LINE>
+<LINE>manhood is melted into courtesies, valour into</LINE>
+<LINE>compliment, and men are only turned into tongue, and</LINE>
+<LINE>trim ones too: he is now as valiant as Hercules</LINE>
+<LINE>that only tells a lie and swears it. I cannot be a</LINE>
+<LINE>man with wishing, therefore I will die a woman with grieving.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>Tarry, good Beatrice. By this hand, I love thee.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>Use it for my love some other way than swearing by it.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>Think you in your soul the Count Claudio hath wronged Hero?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>Yea, as sure as I have a thought or a soul.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>Enough, I am engaged; I will challenge him. I will</LINE>
+<LINE>kiss your hand, and so I leave you. By this hand,</LINE>
+<LINE>Claudio shall render me a dear account. As you</LINE>
+<LINE>hear of me, so think of me. Go, comfort your</LINE>
+<LINE>cousin: I must say she is dead: and so, farewell.</LINE>
+</SPEECH>
+
+
+<STAGEDIR>Exeunt</STAGEDIR>
+</SCENE>
+
+<SCENE><TITLE>SCENE II.  A prison.</TITLE>
+<STAGEDIR>Enter DOGBERRY, VERGES, and Sexton, in gowns; and
+the Watch, with CONRADE and BORACHIO</STAGEDIR>
+
+<SPEECH>
+<SPEAKER>DOGBERRY</SPEAKER>
+<LINE>Is our whole dissembly appeared?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>VERGES</SPEAKER>
+<LINE>O, a stool and a cushion for the sexton.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>Sexton</SPEAKER>
+<LINE>Which be the malefactors?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DOGBERRY</SPEAKER>
+<LINE>Marry, that am I and my partner.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>VERGES</SPEAKER>
+<LINE>Nay, that's certain; we have the exhibition to examine.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>Sexton</SPEAKER>
+<LINE>But which are the offenders that are to be</LINE>
+<LINE>examined? let them come before master constable.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DOGBERRY</SPEAKER>
+<LINE>Yea, marry, let them come before me. What is your</LINE>
+<LINE>name, friend?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BORACHIO</SPEAKER>
+<LINE>Borachio.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DOGBERRY</SPEAKER>
+<LINE>Pray, write down, Borachio. Yours, sirrah?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CONRADE</SPEAKER>
+<LINE>I am a gentleman, sir, and my name is Conrade.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DOGBERRY</SPEAKER>
+<LINE>Write down, master gentleman Conrade. Masters, do</LINE>
+<LINE>you serve God?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CONRADE</SPEAKER>
+<SPEAKER>BORACHIO</SPEAKER>
+<LINE>Yea, sir, we hope.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DOGBERRY</SPEAKER>
+<LINE>Write down, that they hope they serve God: and</LINE>
+<LINE>write God first; for God defend but God should go</LINE>
+<LINE>before such villains! Masters, it is proved already</LINE>
+<LINE>that you are little better than false knaves; and it</LINE>
+<LINE>will go near to be thought so shortly. How answer</LINE>
+<LINE>you for yourselves?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CONRADE</SPEAKER>
+<LINE>Marry, sir, we say we are none.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DOGBERRY</SPEAKER>
+<LINE>A marvellous witty fellow, I assure you: but I</LINE>
+<LINE>will go about with him. Come you hither, sirrah; a</LINE>
+<LINE>word in your ear: sir, I say to you, it is thought</LINE>
+<LINE>you are false knaves.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BORACHIO</SPEAKER>
+<LINE>Sir, I say to you we are none.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DOGBERRY</SPEAKER>
+<LINE>Well, stand aside. 'Fore God, they are both in a</LINE>
+<LINE>tale. Have you writ down, that they are none?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>Sexton</SPEAKER>
+<LINE>Master constable, you go not the way to examine:</LINE>
+<LINE>you must call forth the watch that are their accusers.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DOGBERRY</SPEAKER>
+<LINE>Yea, marry, that's the eftest way. Let the watch</LINE>
+<LINE>come forth. Masters, I charge you, in the prince's</LINE>
+<LINE>name, accuse these men.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>First Watchman</SPEAKER>
+<LINE>This man said, sir, that Don John, the prince's</LINE>
+<LINE>brother, was a villain.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DOGBERRY</SPEAKER>
+<LINE>Write down Prince John a villain. Why, this is flat</LINE>
+<LINE>perjury, to call a prince's brother villain.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BORACHIO</SPEAKER>
+<LINE>Master constable,--</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DOGBERRY</SPEAKER>
+<LINE>Pray thee, fellow, peace: I do not like thy look,</LINE>
+<LINE>I promise thee.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>Sexton</SPEAKER>
+<LINE>What heard you him say else?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>Second Watchman</SPEAKER>
+<LINE>Marry, that he had received a thousand ducats of</LINE>
+<LINE>Don John for accusing the Lady Hero wrongfully.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DOGBERRY</SPEAKER>
+<LINE>Flat burglary as ever was committed.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>VERGES</SPEAKER>
+<LINE>Yea, by mass, that it is.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>Sexton</SPEAKER>
+<LINE>What else, fellow?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>First Watchman</SPEAKER>
+<LINE>And that Count Claudio did mean, upon his words, to</LINE>
+<LINE>disgrace Hero before the whole assembly. and not marry her.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DOGBERRY</SPEAKER>
+<LINE>O villain! thou wilt be condemned into everlasting</LINE>
+<LINE>redemption for this.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>Sexton</SPEAKER>
+<LINE>What else?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>Watchman</SPEAKER>
+<LINE>This is all.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>Sexton</SPEAKER>
+<LINE>And this is more, masters, than you can deny.</LINE>
+<LINE>Prince John is this morning secretly stolen away;</LINE>
+<LINE>Hero was in this manner accused, in this very manner</LINE>
+<LINE>refused, and upon the grief of this suddenly died.</LINE>
+<LINE>Master constable, let these men be bound, and</LINE>
+<LINE>brought to Leonato's: I will go before and show</LINE>
+<LINE>him their examination.</LINE>
+</SPEECH>
+
+
+<STAGEDIR>Exit</STAGEDIR>
+
+<SPEECH>
+<SPEAKER>DOGBERRY</SPEAKER>
+<LINE>Come, let them be opinioned.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>VERGES</SPEAKER>
+<LINE>Let them be in the hands--</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CONRADE</SPEAKER>
+<LINE>Off, coxcomb!</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DOGBERRY</SPEAKER>
+<LINE>God's my life, where's the sexton? let him write</LINE>
+<LINE>down the prince's officer coxcomb. Come, bind them.</LINE>
+<LINE>Thou naughty varlet!</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CONRADE</SPEAKER>
+<LINE>Away! you are an ass, you are an ass.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DOGBERRY</SPEAKER>
+<LINE>Dost thou not suspect my place? dost thou not</LINE>
+<LINE>suspect my years? O that he were here to write me</LINE>
+<LINE>down an ass! But, masters, remember that I am an</LINE>
+<LINE>ass; though it be not written down, yet forget not</LINE>
+<LINE>that I am an ass. No, thou villain, thou art full of</LINE>
+<LINE>piety, as shall be proved upon thee by good witness.</LINE>
+<LINE>I am a wise fellow, and, which is more, an officer,</LINE>
+<LINE>and, which is more, a householder, and, which is</LINE>
+<LINE>more, as pretty a piece of flesh as any is in</LINE>
+<LINE>Messina, and one that knows the law, go to; and a</LINE>
+<LINE>rich fellow enough, go to; and a fellow that hath</LINE>
+<LINE>had losses, and one that hath two gowns and every</LINE>
+<LINE>thing handsome about him. Bring him away. O that</LINE>
+<LINE>I had been writ down an ass!</LINE>
+</SPEECH>
+
+
+<STAGEDIR>Exeunt</STAGEDIR>
+</SCENE>
+
+</ACT>
+
+<ACT><TITLE>ACT V</TITLE>
+
+<SCENE><TITLE>SCENE I.  Before LEONATO'S house.</TITLE>
+<STAGEDIR>Enter LEONATO and ANTONIO</STAGEDIR>
+
+<SPEECH>
+<SPEAKER>ANTONIO</SPEAKER>
+<LINE>If you go on thus, you will kill yourself:</LINE>
+<LINE>And 'tis not wisdom thus to second grief</LINE>
+<LINE>Against yourself.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>I pray thee, cease thy counsel,</LINE>
+<LINE>Which falls into mine ears as profitless</LINE>
+<LINE>As water in a sieve: give not me counsel;</LINE>
+<LINE>Nor let no comforter delight mine ear</LINE>
+<LINE>But such a one whose wrongs do suit with mine.</LINE>
+<LINE>Bring me a father that so loved his child,</LINE>
+<LINE>Whose joy of her is overwhelm'd like mine,</LINE>
+<LINE>And bid him speak of patience;</LINE>
+<LINE>Measure his woe the length and breadth of mine</LINE>
+<LINE>And let it answer every strain for strain,</LINE>
+<LINE>As thus for thus and such a grief for such,</LINE>
+<LINE>In every lineament, branch, shape, and form:</LINE>
+<LINE>If such a one will smile and stroke his beard,</LINE>
+<LINE>Bid sorrow wag, cry 'hem!' when he should groan,</LINE>
+<LINE>Patch grief with proverbs, make misfortune drunk</LINE>
+<LINE>With candle-wasters; bring him yet to me,</LINE>
+<LINE>And I of him will gather patience.</LINE>
+<LINE>But there is no such man: for, brother, men</LINE>
+<LINE>Can counsel and speak comfort to that grief</LINE>
+<LINE>Which they themselves not feel; but, tasting it,</LINE>
+<LINE>Their counsel turns to passion, which before</LINE>
+<LINE>Would give preceptial medicine to rage,</LINE>
+<LINE>Fetter strong madness in a silken thread,</LINE>
+<LINE>Charm ache with air and agony with words:</LINE>
+<LINE>No, no; 'tis all men's office to speak patience</LINE>
+<LINE>To those that wring under the load of sorrow,</LINE>
+<LINE>But no man's virtue nor sufficiency</LINE>
+<LINE>To be so moral when he shall endure</LINE>
+<LINE>The like himself. Therefore give me no counsel:</LINE>
+<LINE>My griefs cry louder than advertisement.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>ANTONIO</SPEAKER>
+<LINE>Therein do men from children nothing differ.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>I pray thee, peace. I will be flesh and blood;</LINE>
+<LINE>For there was never yet philosopher</LINE>
+<LINE>That could endure the toothache patiently,</LINE>
+<LINE>However they have writ the style of gods</LINE>
+<LINE>And made a push at chance and sufferance.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>ANTONIO</SPEAKER>
+<LINE>Yet bend not all the harm upon yourself;</LINE>
+<LINE>Make those that do offend you suffer too.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>There thou speak'st reason: nay, I will do so.</LINE>
+<LINE>My soul doth tell me Hero is belied;</LINE>
+<LINE>And that shall Claudio know; so shall the prince</LINE>
+<LINE>And all of them that thus dishonour her.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>ANTONIO</SPEAKER>
+<LINE>Here comes the prince and Claudio hastily.</LINE>
+</SPEECH>
+
+
+<STAGEDIR>Enter DON PEDRO and CLAUDIO</STAGEDIR>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>Good den, good den.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>Good day to both of you.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>Hear you. my lords,--</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>We have some haste, Leonato.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>Some haste, my lord! well, fare you well, my lord:</LINE>
+<LINE>Are you so hasty now? well, all is one.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>Nay, do not quarrel with us, good old man.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>ANTONIO</SPEAKER>
+<LINE>If he could right himself with quarreling,</LINE>
+<LINE>Some of us would lie low.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>Who wrongs him?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>Marry, thou dost wrong me; thou dissembler, thou:--</LINE>
+<LINE>Nay, never lay thy hand upon thy sword;</LINE>
+<LINE>I fear thee not.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>Marry, beshrew my hand,</LINE>
+<LINE>If it should give your age such cause of fear:</LINE>
+<LINE>In faith, my hand meant nothing to my sword.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>Tush, tush, man; never fleer and jest at me:</LINE>
+<LINE>I speak not like a dotard nor a fool,</LINE>
+<LINE>As under privilege of age to brag</LINE>
+<LINE>What I have done being young, or what would do</LINE>
+<LINE>Were I not old. Know, Claudio, to thy head,</LINE>
+<LINE>Thou hast so wrong'd mine innocent child and me</LINE>
+<LINE>That I am forced to lay my reverence by</LINE>
+<LINE>And, with grey hairs and bruise of many days,</LINE>
+<LINE>Do challenge thee to trial of a man.</LINE>
+<LINE>I say thou hast belied mine innocent child;</LINE>
+<LINE>Thy slander hath gone through and through her heart,</LINE>
+<LINE>And she lies buried with her ancestors;</LINE>
+<LINE>O, in a tomb where never scandal slept,</LINE>
+<LINE>Save this of hers, framed by thy villany!</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>My villany?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>Thine, Claudio; thine, I say.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>You say not right, old man.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>My lord, my lord,</LINE>
+<LINE>I'll prove it on his body, if he dare,</LINE>
+<LINE>Despite his nice fence and his active practise,</LINE>
+<LINE>His May of youth and bloom of lustihood.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>Away! I will not have to do with you.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>Canst thou so daff me? Thou hast kill'd my child:</LINE>
+<LINE>If thou kill'st me, boy, thou shalt kill a man.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>ANTONIO</SPEAKER>
+<LINE>He shall kill two of us, and men indeed:</LINE>
+<LINE>But that's no matter; let him kill one first;</LINE>
+<LINE>Win me and wear me; let him answer me.</LINE>
+<LINE>Come, follow me, boy; come, sir boy, come, follow me:</LINE>
+<LINE>Sir boy, I'll whip you from your foining fence;</LINE>
+<LINE>Nay, as I am a gentleman, I will.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>Brother,--</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>ANTONIO</SPEAKER>
+<LINE>Content yourself. God knows I loved my niece;</LINE>
+<LINE>And she is dead, slander'd to death by villains,</LINE>
+<LINE>That dare as well answer a man indeed</LINE>
+<LINE>As I dare take a serpent by the tongue:</LINE>
+<LINE>Boys, apes, braggarts, Jacks, milksops!</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>Brother Antony,--</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>ANTONIO</SPEAKER>
+<LINE>Hold you content. What, man! I know them, yea,</LINE>
+<LINE>And what they weigh, even to the utmost scruple,--</LINE>
+<LINE>Scrambling, out-facing, fashion-monging boys,</LINE>
+<LINE>That lie and cog and flout, deprave and slander,</LINE>
+<LINE>Go anticly, show outward hideousness,</LINE>
+<LINE>And speak off half a dozen dangerous words,</LINE>
+<LINE>How they might hurt their enemies, if they durst;</LINE>
+<LINE>And this is all.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>But, brother Antony,--</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>ANTONIO</SPEAKER>
+<LINE>Come, 'tis no matter:</LINE>
+<LINE>Do not you meddle; let me deal in this.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>Gentlemen both, we will not wake your patience.</LINE>
+<LINE>My heart is sorry for your daughter's death:</LINE>
+<LINE>But, on my honour, she was charged with nothing</LINE>
+<LINE>But what was true and very full of proof.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>My lord, my lord,--</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>I will not hear you.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>No? Come, brother; away! I will be heard.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>ANTONIO</SPEAKER>
+<LINE>And shall, or some of us will smart for it.</LINE>
+</SPEECH>
+
+
+<STAGEDIR>Exeunt LEONATO and ANTONIO</STAGEDIR>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>See, see; here comes the man we went to seek.</LINE>
+</SPEECH>
+
+
+<STAGEDIR>Enter BENEDICK</STAGEDIR>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>Now, signior, what news?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>Good day, my lord.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>Welcome, signior: you are almost come to part</LINE>
+<LINE>almost a fray.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>We had like to have had our two noses snapped off</LINE>
+<LINE>with two old men without teeth.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>Leonato and his brother. What thinkest thou? Had</LINE>
+<LINE>we fought, I doubt we should have been too young for them.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>In a false quarrel there is no true valour. I came</LINE>
+<LINE>to seek you both.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>We have been up and down to seek thee; for we are</LINE>
+<LINE>high-proof melancholy and would fain have it beaten</LINE>
+<LINE>away. Wilt thou use thy wit?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>It is in my scabbard: shall I draw it?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>Dost thou wear thy wit by thy side?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>Never any did so, though very many have been beside</LINE>
+<LINE>their wit. I will bid thee draw, as we do the</LINE>
+<LINE>minstrels; draw, to pleasure us.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>As I am an honest man, he looks pale. Art thou</LINE>
+<LINE>sick, or angry?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>What, courage, man! What though care killed a cat,</LINE>
+<LINE>thou hast mettle enough in thee to kill care.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>Sir, I shall meet your wit in the career, and you</LINE>
+<LINE>charge it against me. I pray you choose another subject.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>Nay, then, give him another staff: this last was</LINE>
+<LINE>broke cross.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>By this light, he changes more and more: I think</LINE>
+<LINE>he be angry indeed.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>If he be, he knows how to turn his girdle.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>Shall I speak a word in your ear?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>God bless me from a challenge!</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE><STAGEDIR>Aside to CLAUDIO</STAGEDIR>  You are a villain; I jest not:</LINE>
+<LINE>I will make it good how you dare, with what you</LINE>
+<LINE>dare, and when you dare. Do me right, or I will</LINE>
+<LINE>protest your cowardice. You have killed a sweet</LINE>
+<LINE>lady, and her death shall fall heavy on you. Let me</LINE>
+<LINE>hear from you.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>Well, I will meet you, so I may have good cheer.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>What, a feast, a feast?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>I' faith, I thank him; he hath bid me to a calf's</LINE>
+<LINE>head and a capon; the which if I do not carve most</LINE>
+<LINE>curiously, say my knife's naught. Shall I not find</LINE>
+<LINE>a woodcock too?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>Sir, your wit ambles well; it goes easily.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>I'll tell thee how Beatrice praised thy wit the</LINE>
+<LINE>other day. I said, thou hadst a fine wit: 'True,'</LINE>
+<LINE>said she, 'a fine little one.' 'No,' said I, 'a</LINE>
+<LINE>great wit:' 'Right,' says she, 'a great gross one.'</LINE>
+<LINE>'Nay,' said I, 'a good wit:' 'Just,' said she, 'it</LINE>
+<LINE>hurts nobody.' 'Nay,' said I, 'the gentleman</LINE>
+<LINE>is wise:' 'Certain,' said she, 'a wise gentleman.'</LINE>
+<LINE>'Nay,' said I, 'he hath the tongues:' 'That I</LINE>
+<LINE>believe,' said she, 'for he swore a thing to me on</LINE>
+<LINE>Monday night, which he forswore on Tuesday morning;</LINE>
+<LINE>there's a double tongue; there's two tongues.' Thus</LINE>
+<LINE>did she, an hour together, transshape thy particular</LINE>
+<LINE>virtues: yet at last she concluded with a sigh, thou</LINE>
+<LINE>wast the properest man in Italy.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>For the which she wept heartily and said she cared</LINE>
+<LINE>not.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>Yea, that she did: but yet, for all that, an if she</LINE>
+<LINE>did not hate him deadly, she would love him dearly:</LINE>
+<LINE>the old man's daughter told us all.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>All, all; and, moreover, God saw him when he was</LINE>
+<LINE>hid in the garden.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>But when shall we set the savage bull's horns on</LINE>
+<LINE>the sensible Benedick's head?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>Yea, and text underneath, 'Here dwells Benedick the</LINE>
+<LINE>married man'?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>Fare you well, boy: you know my mind. I will leave</LINE>
+<LINE>you now to your gossip-like humour: you break jests</LINE>
+<LINE>as braggarts do their blades, which God be thanked,</LINE>
+<LINE>hurt not. My lord, for your many courtesies I thank</LINE>
+<LINE>you: I must discontinue your company: your brother</LINE>
+<LINE>the bastard is fled from Messina: you have among</LINE>
+<LINE>you killed a sweet and innocent lady. For my Lord</LINE>
+<LINE>Lackbeard there, he and I shall meet: and, till</LINE>
+<LINE>then, peace be with him.</LINE>
+</SPEECH>
+
+
+<STAGEDIR>Exit</STAGEDIR>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>He is in earnest.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>In most profound earnest; and, I'll warrant you, for</LINE>
+<LINE>the love of Beatrice.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>And hath challenged thee.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>Most sincerely.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>What a pretty thing man is when he goes in his</LINE>
+<LINE>doublet and hose and leaves off his wit!</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>He is then a giant to an ape; but then is an ape a</LINE>
+<LINE>doctor to such a man.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>But, soft you, let me be: pluck up, my heart, and</LINE>
+<LINE>be sad. Did he not say, my brother was fled?</LINE>
+</SPEECH>
+
+
+<STAGEDIR>Enter DOGBERRY, VERGES, and the Watch, with CONRADE
+and BORACHIO</STAGEDIR>
+
+<SPEECH>
+<SPEAKER>DOGBERRY</SPEAKER>
+<LINE>Come you, sir: if justice cannot tame you, she</LINE>
+<LINE>shall ne'er weigh more reasons in her balance: nay,</LINE>
+<LINE>an you be a cursing hypocrite once, you must be looked to.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>How now? two of my brother's men bound! Borachio</LINE>
+<LINE>one!</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>Hearken after their offence, my lord.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>Officers, what offence have these men done?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DOGBERRY</SPEAKER>
+<LINE>Marry, sir, they have committed false report;</LINE>
+<LINE>moreover, they have spoken untruths; secondarily,</LINE>
+<LINE>they are slanders; sixth and lastly, they have</LINE>
+<LINE>belied a lady; thirdly, they have verified unjust</LINE>
+<LINE>things; and, to conclude, they are lying knaves.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>First, I ask thee what they have done; thirdly, I</LINE>
+<LINE>ask thee what's their offence; sixth and lastly, why</LINE>
+<LINE>they are committed; and, to conclude, what you lay</LINE>
+<LINE>to their charge.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>Rightly reasoned, and in his own division: and, by</LINE>
+<LINE>my troth, there's one meaning well suited.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>Who have you offended, masters, that you are thus</LINE>
+<LINE>bound to your answer? this learned constable is</LINE>
+<LINE>too cunning to be understood: what's your offence?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BORACHIO</SPEAKER>
+<LINE>Sweet prince, let me go no farther to mine answer:</LINE>
+<LINE>do you hear me, and let this count kill me. I have</LINE>
+<LINE>deceived even your very eyes: what your wisdoms</LINE>
+<LINE>could not discover, these shallow fools have brought</LINE>
+<LINE>to light: who in the night overheard me confessing</LINE>
+<LINE>to this man how Don John your brother incensed me</LINE>
+<LINE>to slander the Lady Hero, how you were brought into</LINE>
+<LINE>the orchard and saw me court Margaret in Hero's</LINE>
+<LINE>garments, how you disgraced her, when you should</LINE>
+<LINE>marry her: my villany they have upon record; which</LINE>
+<LINE>I had rather seal with my death than repeat over</LINE>
+<LINE>to my shame. The lady is dead upon mine and my</LINE>
+<LINE>master's false accusation; and, briefly, I desire</LINE>
+<LINE>nothing but the reward of a villain.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>Runs not this speech like iron through your blood?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>I have drunk poison whiles he utter'd it.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>But did my brother set thee on to this?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BORACHIO</SPEAKER>
+<LINE>Yea, and paid me richly for the practise of it.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>He is composed and framed of treachery:</LINE>
+<LINE>And fled he is upon this villany.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>Sweet Hero! now thy image doth appear</LINE>
+<LINE>In the rare semblance that I loved it first.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DOGBERRY</SPEAKER>
+<LINE>Come, bring away the plaintiffs: by this time our</LINE>
+<LINE>sexton hath reformed Signior Leonato of the matter:</LINE>
+<LINE>and, masters, do not forget to specify, when time</LINE>
+<LINE>and place shall serve, that I am an ass.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>VERGES</SPEAKER>
+<LINE>Here, here comes master Signior Leonato, and the</LINE>
+<LINE>Sexton too.</LINE>
+</SPEECH>
+
+
+<STAGEDIR>Re-enter LEONATO and ANTONIO, with the Sexton</STAGEDIR>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>Which is the villain? let me see his eyes,</LINE>
+<LINE>That, when I note another man like him,</LINE>
+<LINE>I may avoid him: which of these is he?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BORACHIO</SPEAKER>
+<LINE>If you would know your wronger, look on me.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>Art thou the slave that with thy breath hast kill'd</LINE>
+<LINE>Mine innocent child?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BORACHIO</SPEAKER>
+<LINE>Yea, even I alone.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>No, not so, villain; thou beliest thyself:</LINE>
+<LINE>Here stand a pair of honourable men;</LINE>
+<LINE>A third is fled, that had a hand in it.</LINE>
+<LINE>I thank you, princes, for my daughter's death:</LINE>
+<LINE>Record it with your high and worthy deeds:</LINE>
+<LINE>'Twas bravely done, if you bethink you of it.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>I know not how to pray your patience;</LINE>
+<LINE>Yet I must speak. Choose your revenge yourself;</LINE>
+<LINE>Impose me to what penance your invention</LINE>
+<LINE>Can lay upon my sin: yet sinn'd I not</LINE>
+<LINE>But in mistaking.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>By my soul, nor I:</LINE>
+<LINE>And yet, to satisfy this good old man,</LINE>
+<LINE>I would bend under any heavy weight</LINE>
+<LINE>That he'll enjoin me to.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>I cannot bid you bid my daughter live;</LINE>
+<LINE>That were impossible: but, I pray you both,</LINE>
+<LINE>Possess the people in Messina here</LINE>
+<LINE>How innocent she died; and if your love</LINE>
+<LINE>Can labour ought in sad invention,</LINE>
+<LINE>Hang her an epitaph upon her tomb</LINE>
+<LINE>And sing it to her bones, sing it to-night:</LINE>
+<LINE>To-morrow morning come you to my house,</LINE>
+<LINE>And since you could not be my son-in-law,</LINE>
+<LINE>Be yet my nephew: my brother hath a daughter,</LINE>
+<LINE>Almost the copy of my child that's dead,</LINE>
+<LINE>And she alone is heir to both of us:</LINE>
+<LINE>Give her the right you should have given her cousin,</LINE>
+<LINE>And so dies my revenge.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>O noble sir,</LINE>
+<LINE>Your over-kindness doth wring tears from me!</LINE>
+<LINE>I do embrace your offer; and dispose</LINE>
+<LINE>For henceforth of poor Claudio.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>To-morrow then I will expect your coming;</LINE>
+<LINE>To-night I take my leave. This naughty man</LINE>
+<LINE>Shall face to face be brought to Margaret,</LINE>
+<LINE>Who I believe was pack'd in all this wrong,</LINE>
+<LINE>Hired to it by your brother.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BORACHIO</SPEAKER>
+<LINE>No, by my soul, she was not,</LINE>
+<LINE>Nor knew not what she did when she spoke to me,</LINE>
+<LINE>But always hath been just and virtuous</LINE>
+<LINE>In any thing that I do know by her.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DOGBERRY</SPEAKER>
+<LINE>Moreover, sir, which indeed is not under white and</LINE>
+<LINE>black, this plaintiff here, the offender, did call</LINE>
+<LINE>me ass: I beseech you, let it be remembered in his</LINE>
+<LINE>punishment. And also, the watch heard them talk of</LINE>
+<LINE>one Deformed: they say be wears a key in his ear and</LINE>
+<LINE>a lock hanging by it, and borrows money in God's</LINE>
+<LINE>name, the which he hath used so long and never paid</LINE>
+<LINE>that now men grow hard-hearted and will lend nothing</LINE>
+<LINE>for God's sake: pray you, examine him upon that point.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>I thank thee for thy care and honest pains.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DOGBERRY</SPEAKER>
+<LINE>Your worship speaks like a most thankful and</LINE>
+<LINE>reverend youth; and I praise God for you.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>There's for thy pains.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DOGBERRY</SPEAKER>
+<LINE>God save the foundation!</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>Go, I discharge thee of thy prisoner, and I thank thee.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DOGBERRY</SPEAKER>
+<LINE>I leave an arrant knave with your worship; which I</LINE>
+<LINE>beseech your worship to correct yourself, for the</LINE>
+<LINE>example of others. God keep your worship! I wish</LINE>
+<LINE>your worship well; God restore you to health! I</LINE>
+<LINE>humbly give you leave to depart; and if a merry</LINE>
+<LINE>meeting may be wished, God prohibit it! Come, neighbour.</LINE>
+</SPEECH>
+
+
+<STAGEDIR>Exeunt DOGBERRY and VERGES</STAGEDIR>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>Until to-morrow morning, lords, farewell.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>ANTONIO</SPEAKER>
+<LINE>Farewell, my lords: we look for you to-morrow.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>We will not fail.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>To-night I'll mourn with Hero.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE><STAGEDIR>To the Watch</STAGEDIR>  Bring you these fellows on. We'll</LINE>
+<LINE>talk with Margaret,</LINE>
+<LINE>How her acquaintance grew with this lewd fellow.</LINE>
+</SPEECH>
+
+
+<STAGEDIR>Exeunt, severally</STAGEDIR>
+</SCENE>
+
+<SCENE><TITLE>SCENE II.  LEONATO'S garden.</TITLE>
+<STAGEDIR>Enter BENEDICK and MARGARET, meeting</STAGEDIR>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>Pray thee, sweet Mistress Margaret, deserve well at</LINE>
+<LINE>my hands by helping me to the speech of Beatrice.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>MARGARET</SPEAKER>
+<LINE>Will you then write me a sonnet in praise of my beauty?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>In so high a style, Margaret, that no man living</LINE>
+<LINE>shall come over it; for, in most comely truth, thou</LINE>
+<LINE>deservest it.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>MARGARET</SPEAKER>
+<LINE>To have no man come over me! why, shall I always</LINE>
+<LINE>keep below stairs?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>Thy wit is as quick as the greyhound's mouth; it catches.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>MARGARET</SPEAKER>
+<LINE>And yours as blunt as the fencer's foils, which hit,</LINE>
+<LINE>but hurt not.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>A most manly wit, Margaret; it will not hurt a</LINE>
+<LINE>woman: and so, I pray thee, call Beatrice: I give</LINE>
+<LINE>thee the bucklers.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>MARGARET</SPEAKER>
+<LINE>Give us the swords; we have bucklers of our own.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>If you use them, Margaret, you must put in the</LINE>
+<LINE>pikes with a vice; and they are dangerous weapons for maids.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>MARGARET</SPEAKER>
+<LINE>Well, I will call Beatrice to you, who I think hath legs.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>And therefore will come.</LINE>
+<STAGEDIR>Exit MARGARET</STAGEDIR>
+<STAGEDIR>Sings</STAGEDIR>
+<LINE>The god of love,</LINE>
+<LINE>That sits above,</LINE>
+<LINE>And knows me, and knows me,</LINE>
+<LINE>How pitiful I deserve,--</LINE>
+<LINE>I mean in singing; but in loving, Leander the good</LINE>
+<LINE>swimmer, Troilus the first employer of panders, and</LINE>
+<LINE>a whole bookful of these quondam carpet-mangers,</LINE>
+<LINE>whose names yet run smoothly in the even road of a</LINE>
+<LINE>blank verse, why, they were never so truly turned</LINE>
+<LINE>over and over as my poor self in love. Marry, I</LINE>
+<LINE>cannot show it in rhyme; I have tried: I can find</LINE>
+<LINE>out no rhyme to 'lady' but 'baby,' an innocent</LINE>
+<LINE>rhyme; for 'scorn,' 'horn,' a hard rhyme; for,</LINE>
+<LINE>'school,' 'fool,' a babbling rhyme; very ominous</LINE>
+<LINE>endings: no, I was not born under a rhyming planet,</LINE>
+<LINE>nor I cannot woo in festival terms.</LINE>
+<STAGEDIR>Enter BEATRICE</STAGEDIR>
+<LINE>Sweet Beatrice, wouldst thou come when I called thee?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>Yea, signior, and depart when you bid me.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>O, stay but till then!</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>'Then' is spoken; fare you well now: and yet, ere</LINE>
+<LINE>I go, let me go with that I came; which is, with</LINE>
+<LINE>knowing what hath passed between you and Claudio.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>Only foul words; and thereupon I will kiss thee.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>Foul words is but foul wind, and foul wind is but</LINE>
+<LINE>foul breath, and foul breath is noisome; therefore I</LINE>
+<LINE>will depart unkissed.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>Thou hast frighted the word out of his right sense,</LINE>
+<LINE>so forcible is thy wit. But I must tell thee</LINE>
+<LINE>plainly, Claudio undergoes my challenge; and either</LINE>
+<LINE>I must shortly hear from him, or I will subscribe</LINE>
+<LINE>him a coward. And, I pray thee now, tell me for</LINE>
+<LINE>which of my bad parts didst thou first fall in love with me?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>For them all together; which maintained so politic</LINE>
+<LINE>a state of evil that they will not admit any good</LINE>
+<LINE>part to intermingle with them. But for which of my</LINE>
+<LINE>good parts did you first suffer love for me?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>Suffer love! a good epithet! I do suffer love</LINE>
+<LINE>indeed, for I love thee against my will.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>In spite of your heart, I think; alas, poor heart!</LINE>
+<LINE>If you spite it for my sake, I will spite it for</LINE>
+<LINE>yours; for I will never love that which my friend hates.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>Thou and I are too wise to woo peaceably.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>It appears not in this confession: there's not one</LINE>
+<LINE>wise man among twenty that will praise himself.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>An old, an old instance, Beatrice, that lived in</LINE>
+<LINE>the lime of good neighbours. If a man do not erect</LINE>
+<LINE>in this age his own tomb ere he dies, he shall live</LINE>
+<LINE>no longer in monument than the bell rings and the</LINE>
+<LINE>widow weeps.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>And how long is that, think you?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>Question: why, an hour in clamour and a quarter in</LINE>
+<LINE>rheum: therefore is it most expedient for the</LINE>
+<LINE>wise, if Don Worm, his conscience, find no</LINE>
+<LINE>impediment to the contrary, to be the trumpet of his</LINE>
+<LINE>own virtues, as I am to myself. So much for</LINE>
+<LINE>praising myself, who, I myself will bear witness, is</LINE>
+<LINE>praiseworthy: and now tell me, how doth your cousin?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>Very ill.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>And how do you?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>Very ill too.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>Serve God, love me and mend. There will I leave</LINE>
+<LINE>you too, for here comes one in haste.</LINE>
+</SPEECH>
+
+
+<STAGEDIR>Enter URSULA</STAGEDIR>
+
+<SPEECH>
+<SPEAKER>URSULA</SPEAKER>
+<LINE>Madam, you must come to your uncle. Yonder's old</LINE>
+<LINE>coil at home: it is proved my Lady Hero hath been</LINE>
+<LINE>falsely accused, the prince and Claudio mightily</LINE>
+<LINE>abused; and Don John is the author of all, who is</LINE>
+<LINE>fed and gone. Will you come presently?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>Will you go hear this news, signior?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>I will live in thy heart, die in thy lap, and be</LINE>
+<LINE>buried in thy eyes; and moreover I will go with</LINE>
+<LINE>thee to thy uncle's.</LINE>
+</SPEECH>
+
+
+<STAGEDIR>Exeunt</STAGEDIR>
+</SCENE>
+
+<SCENE><TITLE>SCENE III.  A church.</TITLE>
+<STAGEDIR>Enter DON PEDRO, CLAUDIO, and three or four
+with tapers</STAGEDIR>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>Is this the monument of Leonato?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>Lord</SPEAKER>
+<LINE>It is, my lord.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE><STAGEDIR>Reading out of a scroll</STAGEDIR></LINE>
+<LINE>Done to death by slanderous tongues</LINE>
+<LINE>Was the Hero that here lies:</LINE>
+<LINE>Death, in guerdon of her wrongs,</LINE>
+<LINE>Gives her fame which never dies.</LINE>
+<LINE>So the life that died with shame</LINE>
+<LINE>Lives in death with glorious fame.</LINE>
+<LINE>Hang thou there upon the tomb,</LINE>
+<LINE>Praising her when I am dumb.</LINE>
+<LINE>Now, music, sound, and sing your solemn hymn.</LINE>
+<SUBHEAD>SONG.</SUBHEAD>
+<LINE>Pardon, goddess of the night,</LINE>
+<LINE>Those that slew thy virgin knight;</LINE>
+<LINE>For the which, with songs of woe,</LINE>
+<LINE>Round about her tomb they go.</LINE>
+<LINE>Midnight, assist our moan;</LINE>
+<LINE>Help us to sigh and groan,</LINE>
+<LINE>Heavily, heavily:</LINE>
+<LINE>Graves, yawn and yield your dead,</LINE>
+<LINE>Till death be uttered,</LINE>
+<LINE>Heavily, heavily.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>Now, unto thy bones good night!</LINE>
+<LINE>Yearly will I do this rite.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>Good morrow, masters; put your torches out:</LINE>
+<LINE>The wolves have prey'd; and look, the gentle day,</LINE>
+<LINE>Before the wheels of Phoebus, round about</LINE>
+<LINE>Dapples the drowsy east with spots of grey.</LINE>
+<LINE>Thanks to you all, and leave us: fare you well.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>Good morrow, masters: each his several way.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>Come, let us hence, and put on other weeds;</LINE>
+<LINE>And then to Leonato's we will go.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>And Hymen now with luckier issue speed's</LINE>
+<LINE>Than this for whom we render'd up this woe.</LINE>
+</SPEECH>
+
+
+<STAGEDIR>Exeunt</STAGEDIR>
+</SCENE>
+
+<SCENE><TITLE>SCENE IV.  A room in LEONATO'S house.</TITLE>
+<STAGEDIR>Enter LEONATO, ANTONIO, BENEDICK, BEATRICE,
+MARGARET, URSULA, FRIAR FRANCIS, and HERO</STAGEDIR>
+
+<SPEECH>
+<SPEAKER>FRIAR FRANCIS</SPEAKER>
+<LINE>Did I not tell you she was innocent?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>So are the prince and Claudio, who accused her</LINE>
+<LINE>Upon the error that you heard debated:</LINE>
+<LINE>But Margaret was in some fault for this,</LINE>
+<LINE>Although against her will, as it appears</LINE>
+<LINE>In the true course of all the question.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>ANTONIO</SPEAKER>
+<LINE>Well, I am glad that all things sort so well.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>And so am I, being else by faith enforced</LINE>
+<LINE>To call young Claudio to a reckoning for it.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>Well, daughter, and you gentle-women all,</LINE>
+<LINE>Withdraw into a chamber by yourselves,</LINE>
+<LINE>And when I send for you, come hither mask'd.</LINE>
+<STAGEDIR>Exeunt Ladies</STAGEDIR>
+<LINE>The prince and Claudio promised by this hour</LINE>
+<LINE>To visit me. You know your office, brother:</LINE>
+<LINE>You must be father to your brother's daughter</LINE>
+<LINE>And give her to young Claudio.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>ANTONIO</SPEAKER>
+<LINE>Which I will do with confirm'd countenance.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>Friar, I must entreat your pains, I think.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>FRIAR FRANCIS</SPEAKER>
+<LINE>To do what, signior?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>To bind me, or undo me; one of them.</LINE>
+<LINE>Signior Leonato, truth it is, good signior,</LINE>
+<LINE>Your niece regards me with an eye of favour.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>That eye my daughter lent her: 'tis most true.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>And I do with an eye of love requite her.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>The sight whereof I think you had from me,</LINE>
+<LINE>From Claudio and the prince: but what's your will?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>Your answer, sir, is enigmatical:</LINE>
+<LINE>But, for my will, my will is your good will</LINE>
+<LINE>May stand with ours, this day to be conjoin'd</LINE>
+<LINE>In the state of honourable marriage:</LINE>
+<LINE>In which, good friar, I shall desire your help.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>My heart is with your liking.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>FRIAR FRANCIS</SPEAKER>
+<LINE>And my help.</LINE>
+<LINE>Here comes the prince and Claudio.</LINE>
+</SPEECH>
+
+
+<STAGEDIR>Enter DON PEDRO and CLAUDIO, and two or
+three others</STAGEDIR>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>Good morrow to this fair assembly.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>Good morrow, prince; good morrow, Claudio:</LINE>
+<LINE>We here attend you. Are you yet determined</LINE>
+<LINE>To-day to marry with my brother's daughter?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>I'll hold my mind, were she an Ethiope.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>Call her forth, brother; here's the friar ready.</LINE>
+</SPEECH>
+
+
+<STAGEDIR>Exit ANTONIO</STAGEDIR>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>Good morrow, Benedick. Why, what's the matter,</LINE>
+<LINE>That you have such a February face,</LINE>
+<LINE>So full of frost, of storm and cloudiness?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>I think he thinks upon the savage bull.</LINE>
+<LINE>Tush, fear not, man; we'll tip thy horns with gold</LINE>
+<LINE>And all Europa shall rejoice at thee,</LINE>
+<LINE>As once Europa did at lusty Jove,</LINE>
+<LINE>When he would play the noble beast in love.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>Bull Jove, sir, had an amiable low;</LINE>
+<LINE>And some such strange bull leap'd your father's cow,</LINE>
+<LINE>And got a calf in that same noble feat</LINE>
+<LINE>Much like to you, for you have just his bleat.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>For this I owe you: here comes other reckonings.</LINE>
+<STAGEDIR>Re-enter ANTONIO, with the Ladies masked</STAGEDIR>
+<LINE>Which is the lady I must seize upon?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>ANTONIO</SPEAKER>
+<LINE>This same is she, and I do give you her.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>Why, then she's mine. Sweet, let me see your face.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>No, that you shall not, till you take her hand</LINE>
+<LINE>Before this friar and swear to marry her.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>Give me your hand: before this holy friar,</LINE>
+<LINE>I am your husband, if you like of me.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>HERO</SPEAKER>
+<LINE>And when I lived, I was your other wife:</LINE>
+<STAGEDIR>Unmasking</STAGEDIR>
+<LINE>And when you loved, you were my other husband.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>Another Hero!</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>HERO</SPEAKER>
+<LINE>Nothing certainer:</LINE>
+<LINE>One Hero died defiled, but I do live,</LINE>
+<LINE>And surely as I live, I am a maid.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>The former Hero! Hero that is dead!</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>She died, my lord, but whiles her slander lived.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>FRIAR FRANCIS</SPEAKER>
+<LINE>All this amazement can I qualify:</LINE>
+<LINE>When after that the holy rites are ended,</LINE>
+<LINE>I'll tell you largely of fair Hero's death:</LINE>
+<LINE>Meantime let wonder seem familiar,</LINE>
+<LINE>And to the chapel let us presently.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>Soft and fair, friar. Which is Beatrice?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE><STAGEDIR>Unmasking</STAGEDIR>  I answer to that name. What is your will?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>Do not you love me?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>Why, no; no more than reason.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>Why, then your uncle and the prince and Claudio</LINE>
+<LINE>Have been deceived; they swore you did.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>Do not you love me?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>Troth, no; no more than reason.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>Why, then my cousin Margaret and Ursula</LINE>
+<LINE>Are much deceived; for they did swear you did.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>They swore that you were almost sick for me.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>They swore that you were well-nigh dead for me.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>'Tis no such matter. Then you do not love me?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>No, truly, but in friendly recompense.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>Come, cousin, I am sure you love the gentleman.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>And I'll be sworn upon't that he loves her;</LINE>
+<LINE>For here's a paper written in his hand,</LINE>
+<LINE>A halting sonnet of his own pure brain,</LINE>
+<LINE>Fashion'd to Beatrice.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>HERO</SPEAKER>
+<LINE>And here's another</LINE>
+<LINE>Writ in my cousin's hand, stolen from her pocket,</LINE>
+<LINE>Containing her affection unto Benedick.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>A miracle! here's our own hands against our hearts.</LINE>
+<LINE>Come, I will have thee; but, by this light, I take</LINE>
+<LINE>thee for pity.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BEATRICE</SPEAKER>
+<LINE>I would not deny you; but, by this good day, I yield</LINE>
+<LINE>upon great persuasion; and partly to save your life,</LINE>
+<LINE>for I was told you were in a consumption.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>Peace! I will stop your mouth.</LINE>
+</SPEECH>
+
+
+<STAGEDIR>Kissing her</STAGEDIR>
+
+<SPEECH>
+<SPEAKER>DON PEDRO</SPEAKER>
+<LINE>How dost thou, Benedick, the married man?</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>I'll tell thee what, prince; a college of</LINE>
+<LINE>wit-crackers cannot flout me out of my humour. Dost</LINE>
+<LINE>thou think I  care for a satire or an epigram? No:</LINE>
+<LINE>if a man will be beaten with brains, a' shall wear</LINE>
+<LINE>nothing handsome about him. In brief, since I do</LINE>
+<LINE>purpose to marry, I will think nothing to any</LINE>
+<LINE>purpose that the world can say against it; and</LINE>
+<LINE>therefore never flout at me for what I have said</LINE>
+<LINE>against it; for man is a giddy thing, and this is my</LINE>
+<LINE>conclusion. For thy part, Claudio, I did think to</LINE>
+<LINE>have beaten thee, but in that thou art like to be my</LINE>
+<LINE>kinsman, live unbruised and love my cousin.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>CLAUDIO</SPEAKER>
+<LINE>I had well hoped thou wouldst have denied Beatrice,</LINE>
+<LINE>that I might have cudgelled thee out of thy single</LINE>
+<LINE>life, to make thee a double-dealer; which, out of</LINE>
+<LINE>question, thou wilt be, if my cousin do not look</LINE>
+<LINE>exceedingly narrowly to thee.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>Come, come, we are friends: let's have a dance ere</LINE>
+<LINE>we are married, that we may lighten our own hearts</LINE>
+<LINE>and our wives' heels.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>LEONATO</SPEAKER>
+<LINE>We'll have dancing afterward.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>First, of my word; therefore play, music. Prince,</LINE>
+<LINE>thou art sad; get thee a wife, get thee a wife:</LINE>
+<LINE>there is no staff more reverend than one tipped with horn.</LINE>
+</SPEECH>
+
+
+<STAGEDIR>Enter a Messenger</STAGEDIR>
+
+<SPEECH>
+<SPEAKER>Messenger</SPEAKER>
+<LINE>My lord, your brother John is ta'en in flight,</LINE>
+<LINE>And brought with armed men back to Messina.</LINE>
+</SPEECH>
+
+<SPEECH>
+<SPEAKER>BENEDICK</SPEAKER>
+<LINE>Think not on him till to-morrow:</LINE>
+<LINE>I'll devise thee brave punishments for him.</LINE>
+<LINE>Strike up, pipers.</LINE>
+</SPEECH>
+
+<STAGEDIR>Dance</STAGEDIR>
+<STAGEDIR>Exeunt</STAGEDIR>
+</SCENE>
+</ACT>
+</PLAY>
diff --git a/libjaxen-java/xml/namespaces.xml b/libjaxen-java/xml/namespaces.xml
new file mode 100644
index 0000000..e8e4df8
--- /dev/null
+++ b/libjaxen-java/xml/namespaces.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+<foo:a xmlns:foo="http://fooNamespace/">
+  <b>
+    <c>Hello</c>
+  </b>
+
+  <foo:d>
+    <foo:e>Hey</foo:e>
+  </foo:d>
+
+  <bar:f xmlns:bar="http://barNamespace/">
+    <bar:g>Hey2</bar:g>
+  </bar:f>
+
+  <alias:x xmlns:alias="http://fooNamespace/">
+    <alias:y>Hey3</alias:y>
+  </alias:x>
+</foo:a>
diff --git a/libjaxen-java/xml/nitf.xml b/libjaxen-java/xml/nitf.xml
new file mode 100644
index 0000000..269d99e
--- /dev/null
+++ b/libjaxen-java/xml/nitf.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<nitf>
+
+  <!-- Example of markup of URLs (at the bottom of the story) -->
+
+ <head>
+  <meta name="ap-cycle" content="AP"/>
+  <meta name="ap-online-code" content="1700"/>
+  <meta name="ap-company" content="CO:Media Metrix Inc;TS:MMXI;IG:SVC;"/>
+  <meta name="ap-routing" content="ENTITLEMENTS,pfONLINE,pf1700"/>
+  <meta name="ap-format" content="bx"/>
+  <meta name="ap-category" content="f"/>
+  <meta name="ap-selector" content="-----"/>
+  <meta name="ap-transref" content="V0347"/>
+  <docdata>
+   <doc-id regsrc="AP" id-string="D76UIMO80"/>
+   <urgency ed-urg="7"/>
+   <date.issue norm="20000911T185842Z"/>
+   <du-key key="Napster Traffic"/>
+   <doc.copyright holder="(AP)"/>
+  </docdata>
+ </head>
+ <body>
+  <body.head>
+   <hedline>
+    <hl1>Use of Napster Quadruples</hl1>
+   </hedline>
+   <byline>By PETER SVENSSON
+    <byttl>AP Business Writer</byttl>
+   </byline>
+   <distributor>The Associated Press</distributor>
+   <dateline>
+    <location>NEW YORK</location>
+   </dateline>
+  </body.head>
+  <body.content>
+   <block>
+    <p>Despite the uncertain legality of the Napster online music-sharing service, the number of people
+using it more than quadrupled in just five months, Media Metrix said Monday.</p>
+    <p>That made Napster the fastest-growing software application ever recorded by the Internet research
+company.</p>
+    <p>From 1.1 million home users in the United States in February, the first month Media Metrix
+tracked the application, Napster use rocketed to 4.9 million users in July.</p>
+    <p>That represents 6 percent of U.S. home PC users who have modems, said Media Metrix, which pays
+people to install monitoring software on their computers.</p>
+    <p>It estimates total usage from a panel of about 50,000 people in the United States.</p>
+    <p>Napster was also used at work by 887,000 people in July, Media Metrix said.</p>
+    <p>Napster Inc. has been sued by the recording industry for allegedly enabling copyright
+infringement. The federal government weighed in on the case Friday, saying the service is not protected
+under a key copyright law, as the San Mateo, Calif., company claims.</p>
+    <p>Bruce Ryon, head of Media Metrix's New Media Group, said Napster was used by "the full spectrum of PC users, not just the youth with time on their hands and a passion for music."</p>
+    <p>The Napster program allows users to copy digital music files from the hard drives of other
+users over the Internet.</p>
+    <p>Napster Inc. said last week that 28 million people had downloaded its program. It does not reveal
+its own figures for how many people actually use the software.</p>
+    <p>Because the program connects to the company's computers over the Internet every time
+it is run, Napster Inc. can track usage exactly.</p>
+    <p>__</p>
+    <p>On the Net:</p>
+    <p><a href="http://www.napster.com">
+http://www.napster.com</a></p>
+    <p><a href="http://www.mediametrix.com">
+http://www.mediametrix.com</a></p>
+   </block>
+  </body.content>
+ </body>
+</nitf>
diff --git a/libjaxen-java/xml/numbers.xml b/libjaxen-java/xml/numbers.xml
new file mode 100644
index 0000000..a1791cd
--- /dev/null
+++ b/libjaxen-java/xml/numbers.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+
+<numbers>
+  <set>
+    <nr>3</nr>
+    <nr>24</nr>
+    <nr>55</nr>
+    <nr>11</nr>
+    <nr>2</nr>
+    <nr>-3</nr>
+  </set>
+  <set>
+    <nr value="66"/>
+    <nr value="123"/>
+    <nr value="55"/>
+    <nr value="9999"/>
+  </set>
+</numbers>
diff --git a/libjaxen-java/xml/pi.xml b/libjaxen-java/xml/pi.xml
new file mode 100644
index 0000000..980bbf9
--- /dev/null
+++ b/libjaxen-java/xml/pi.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0"?>
+<foo>
+	<?cheese is tasty?>
+	<bar>
+		<baz/>
+		<cheese/>
+		<baz/>
+		<?toast is tasty?>
+		<cheese/>
+		<baz/>
+	</bar>
+	<?cheese is gooey?>
+</foo>
diff --git a/libjaxen-java/xml/pi2.xml b/libjaxen-java/xml/pi2.xml
new file mode 100644
index 0000000..46bce45
--- /dev/null
+++ b/libjaxen-java/xml/pi2.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<a>
+  <b>foo</b>
+  <?toc order-by="x"?>
+  <c>bar</c>
+</a>
diff --git a/libjaxen-java/xml/simple.xml b/libjaxen-java/xml/simple.xml
new file mode 100644
index 0000000..3cff71a
--- /dev/null
+++ b/libjaxen-java/xml/simple.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" ?>
+<root><a>a</a><b>b</b><c><d>d</d></c></root>
diff --git a/libjaxen-java/xml/simplevariablecontext.ser b/libjaxen-java/xml/simplevariablecontext.ser
new file mode 100644
index 0000000..c1e2e3f
Binary files /dev/null and b/libjaxen-java/xml/simplevariablecontext.ser differ
diff --git a/libjaxen-java/xml/test/tests.xml b/libjaxen-java/xml/test/tests.xml
new file mode 100644
index 0000000..ee327b6
--- /dev/null
+++ b/libjaxen-java/xml/test/tests.xml
@@ -0,0 +1,685 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<tests xmlns:var="http://jaxen.org/test-harness/var">
+    <!-- test for jaxen-24 -->
+   <document url="xml/jaxen24.xml">
+       <context select="/body/div">
+           <test select="preceding::*[1]" count="1"/>
+           <valueOf select="local-name(preceding::*[1])">span</valueOf>
+       </context>
+        <!-- jaxen-58 -->
+       <context select="/">
+           <test select="//preceding::x" count="0"/>
+           <test select="//following::x" count="0"/>
+           <test select="/descendant::*/preceding::x" count="0"/>
+           <test select="/descendant::node()/preceding::x" count="0"/>
+       </context>
+   </document>
+
+    <!-- test for jaxen-3 -->
+  <document url="xml/simple.xml">
+    <context select="/">
+      <valueOf select="string()">abd</valueOf>
+    </context>
+    <context select="/root">
+      <valueOf select="string()">abd</valueOf>
+    </context>
+    <context select="/root/a">
+      <valueOf select="string()">a</valueOf>
+    </context>
+    <context select="/root/c">
+      <valueOf select="string()">d</valueOf>
+    </context>
+  </document>
+
+
+    <!-- test for jaxen-3 -->
+  <document url="xml/jaxen3.xml">
+    <context select="/">
+      <test select="/Configuration/hostname/attrlist/hostname[. = 'CE-A'] " count="1"/>
+    </context>
+  </document>
+
+    <!-- parser test cases all of which should fail-->
+  <document url="xml/numbers.xml">
+    <context select="/">
+        <!-- repeated xpaths, jaxen-35 -->
+      <test exception="true" select="/numbers numbers" count="0"/>
+        <!-- invalid xpath, jaxen-34 -->
+      <test exception="true" select="/a/b[c > d]efg" count="0"/>
+        <!-- invalid xpath, jaxen-27 -->
+      <test exception="true" select="/inv/child::" count="0"/>
+        <!-- invalid xpath, jaxen-26 -->
+      <test exception="true" select="/invoice/@test[abcd" count="0"/>
+      <test exception="true" select="/invoice/@test[abcd > x" count="0"/>
+
+        <!-- unterminated string -->
+      <test exception="true" select="string-length('a" count="0"/>
+      <!-- various edge cases where code threw no exception -->
+      <test exception="true" select="/descendant::()" count="0"/>
+      <test exception="true" select="(1 + 1" count="0"/>
+
+    </context>
+  </document>
+
+
+  <!-- test cases for the use of underscores in names -->
+  <document url="xml/underscore.xml">
+    <context select="/">
+      <test select="/root/@a" count="1"/>
+      <test select="/root/@_a" count="1"/>
+      <test select="/root/b" count="1"/>
+      <test select="/root/_b" count="1"/>
+      <valueOf select="/root/@a">1</valueOf>
+      <valueOf select="/root/@_a">2</valueOf>
+      <valueOf select="/root/b">1</valueOf>
+      <valueOf select="/root/_b">2</valueOf>
+    </context>
+  </document>
+
+  <!-- test cases for the use of = with nodesets -->
+  <document url="xml/web.xml">
+    <context select="/">
+      <valueOf select="/web-app/servlet/servlet-name = 'file'">true</valueOf>
+      <valueOf select="/web-app/servlet/servlet-name = 'snoop'">true</valueOf>
+    </context>
+  </document>
+
+  <document url="xml/numbers.xml">
+    <context select="/">
+      <valueOf select="/numbers/set/nr = '-3'">true</valueOf>
+      <valueOf select="/numbers/set/nr = -3">true</valueOf>
+      <valueOf select="/numbers/set/nr = 24">true</valueOf>
+      <valueOf select="/numbers/set/nr/@value = '9999'">true</valueOf>
+      <valueOf select="/numbers/set/nr/@value = 9999.0">true</valueOf>
+      <valueOf select="/numbers/set/nr/@value = 66">true</valueOf>
+    </context>
+  </document>
+
+  <!-- test basic math... -->
+  <document url="xml/numbers.xml">
+    <context select="/">
+      <valueOf select="(8 * 2 + 1) = 17">true</valueOf>
+      <valueOf select="(1 + 8 * 2) = 17">true</valueOf>
+      <valueOf select="(7 - 3 + 1) = 5">true</valueOf>
+      <valueOf select="(8 - 4 + 5 - 6) = 3">true</valueOf>
+      <!-- left-assoc tests, comments show WRONG evaluation -->
+      <!-- 3 - 2 - 1 != 2 -->
+      <valueOf select="3 - 2 - 1">0</valueOf>
+      <!-- 8 div 4 div 2 != 4 -->
+      <valueOf select="8 div 4 div 2">1</valueOf>
+      <!-- 3 mod 5 mod 7 != 1 -->
+      <valueOf select="3 mod 7 mod 5">3</valueOf>
+        <!-- 1=(2=2) is true-->
+      <valueOf select="1 = 2 = 2">false</valueOf>
+        <!--  2!=(3!=1) => 2!=1 => true, (2!=3)!=1 => 1!=1 => false -->
+      <valueOf select="2 != 3 != 1">false</valueOf>
+        <!-- 3 > (2 > 1) is true -->
+      <valueOf select="3 > 2 > 1">false</valueOf>
+        <!-- 3 >= (2 >= 2) is true -->
+      <valueOf select="3 >= 2 >= 2">false</valueOf>
+        <!-- 1 < (2 < 3) is false -->
+      <valueOf select="1 < 2 < 3">true</valueOf>
+        <!-- 0 <= (2 <= 3) is true -->
+      <valueOf select="2 <= 2 <= 3">true</valueOf>
+    </context>
+  </document>
+
+  <!-- test cases for preceding axis with different node types -->
+  <document url="xml/pi2.xml">
+    <context select="/a/c">
+      <test select="//processing-instruction()" count="1"/>
+      <test select="preceding-sibling::*" count="1"/>
+      <test select="preceding-sibling::node()" count="5"/>
+      <test select="preceding-sibling::*[1]" count="1"/>
+      <test select="preceding-sibling::processing-instruction()" count="1"/>
+      <valueOf select="preceding-sibling::processing-instruction()">order-by="x"</valueOf>
+      <valueOf select="preceding-sibling::*[1]">foo</valueOf>
+      <valueOf select="preceding-sibling::node()[2]">order-by="x"</valueOf>
+    </context>
+  </document>
+
+  <document url="xml/id.xml">
+    <context select="/"
+	     var:foobar="foobar"
+	     var:foo="foo">
+      <valueOf select="$foobar">foobar</valueOf>
+      <test select="/foo[@id=$foobar]" count="1"/>
+      <test select="/foo[@id='$foobar']" count="0"/>
+      <test select="/foo[concat($foo, 'bar')=@id]" count="1"/>
+      <test select="CD_Library/artist[@name=$artist]" count="0"/>
+    </context>
+  </document>
+
+  <document url="xml/id.xml">
+    <context select="/">
+      <!-- attributes have a parent: their element -->
+      <test select="/foo/@id/parent::foo" count="1"/>
+    </context>
+    <!-- attributes can also be used as context nodes -->
+    <context select="/foo/@id">
+      <test select="parent::foo" count="1"/>
+    </context>
+  </document>
+
+  <document url="xml/pi.xml">
+    <context select="/">
+      <test select="//processing-instruction()" count="3"/>
+      <test select="//processing-instruction('cheese')" count="2"/>
+      <test select="//processing-instruction('toast')" count="1">
+	<valueOf select="string()">is tasty</valueOf>
+      </test>
+    </context>
+
+  </document>
+
+  <!-- test evaluate() extension function -->
+  <document url="xml/evaluate.xml">
+    <context select="/">
+      <test select="evaluate('//jumps/*')" count="3"/>
+      <test select="evaluate('//jumps/object/dog')" count="1"/>
+      <test select="evaluate('//jumps/object')/evaluate" count="0"/>
+      <test select="evaluate('//jumps/object')/dog" count="1"/>
+      <test select="evaluate('//jumps/*')/dog" count="1"/>
+      <test select="//metatest[ evaluate(@select) = . ]" count="1"/>
+    </context>
+  </document>
+  
+  <document url="xml/numbers.xml">
+    <context select="/numbers/set[1]">
+      <test select="*[-3 = .]" count="1"/>
+      <valueOf select="54 < *">true</valueOf>
+      <valueOf select="55 <= *">true</valueOf>
+      <valueOf select="69 < *">false</valueOf>
+      <valueOf select="-2 > *">true</valueOf>
+      <valueOf select="-3 >= *">true</valueOf>
+      <valueOf select="-4 >= *">false</valueOf>
+    </context>
+    <!-- TODO
+    This context should work, but needs a fixed version of saxpath to parse the right-hand side
+    of the greater-than expression.
+    <context select="/numbers/set[2]">
+      <valueOf select="1 > nr/@value">false</valueOf>
+      <valueOf select="55 > nr/@value">false</valueOf>
+      <valueOf select="55 >= nr/@value">true</valueOf>
+      <valueOf select="1000000 > nr/@value">true</valueOf>
+    </context>
+    -->
+  </document>
+
+
+  <!-- test sibling axes -->
+  <document url="xml/axis.xml">
+
+    <context select="/root">
+      <test select="preceding-sibling::*" count="0"/>
+    </context>
+
+    <context select="/root/a/a.3">
+      <test select="preceding::*" count="2"/>
+    </context>
+
+    <context select="/root/a/a.3">
+      <test select="preceding-sibling::*" count="2"/>
+    </context>
+
+    <context select="/">
+      <valueOf select="name(/root/a/a.3/preceding-sibling::*[1])">a.2</valueOf>
+      <valueOf select="name(/root/a/a.3/preceding-sibling::*[2])">a.1</valueOf>
+    </context>
+
+    <context select="/">
+      <valueOf select="name(/root/a/a.3/following-sibling::*[1])">a.4</valueOf>
+      <valueOf select="name(/root/a/a.3/following-sibling::*[2])">a.5</valueOf>
+    </context>
+
+  </document>
+
+
+  <document url="xml/web.xml">
+
+    <context select="/">
+      <valueOf select="/web-app/servlet[1]/servlet-name">snoop</valueOf>
+      <valueOf select="/web-app/servlet[1]/servlet-name/text()">snoop</valueOf>
+      <valueOf select="/web-app/servlet[2]/servlet-name">file</valueOf>
+      <valueOf select="/web-app/servlet[2]/servlet-name/text()">file</valueOf>
+    </context>
+
+    <context select="/web-app/servlet[1]">
+      <valueOf select="servlet-name">snoop</valueOf>
+      <valueOf select="servlet-name/text()">snoop</valueOf>
+    </context>
+    
+    <context select="/web-app/servlet[2]/servlet-name">
+      <test select="preceding::*" count="3"/>
+    </context>
+
+    <context select="/web-app/servlet[2]/servlet-name">
+      <test select="following::*" count="13"/>
+    </context>
+
+  </document>
+
+
+  <!-- test name -->
+
+  <document url="xml/web.xml">
+    <context select="/">
+      
+      <test select="*" count="1">
+	<valueOf select="name()">web-app</valueOf>
+      </test>
+
+      <!-- NOTE that the child::node() tests only work if the
+      XML document does not comments or PIs
+      -->
+      
+      <test select="./*" count="1">
+	<valueOf select="name()">web-app</valueOf>
+      </test>
+      <test select="child::*" count="1">
+	<valueOf select="name()">web-app</valueOf>
+      </test>
+      <test select="/*" count="1">
+	<valueOf select="name()">web-app</valueOf>
+      </test>
+      <test select="/child::node()" count="1">
+	<valueOf select="name(.)">web-app</valueOf>
+      </test>
+      <test select="child::node()" count="1">
+	<valueOf select="name(.)">web-app</valueOf>
+      </test>
+
+      <!-- empty names -->
+
+      <valueOf select="name()"></valueOf>
+      <valueOf select="name(.)"></valueOf>
+      <valueOf select="name(parent::*)"></valueOf>
+      <valueOf select="name(/)"></valueOf>
+      <valueOf select="name(/.)"></valueOf>
+      <valueOf select="name(/self::node())"></valueOf>
+
+      <!-- name of root elemet -->
+      <valueOf select="name(node())">web-app</valueOf>
+      <valueOf select="name(/node())">web-app</valueOf>
+      <valueOf select="name(/*)">web-app</valueOf>
+      <valueOf select="name(/child::*)">web-app</valueOf>
+      <valueOf select="name(/child::node())">web-app</valueOf>
+      <valueOf select="name(/child::node())">web-app</valueOf>
+      <valueOf select="name(child::node())">web-app</valueOf>
+      <valueOf select="name(./*)">web-app</valueOf>
+      <valueOf select="name(*)">web-app</valueOf>
+
+    </context>
+
+    <context select="/*">
+      <!-- empty names -->
+      <valueOf select="name(..)"></valueOf>
+      <valueOf select="name(parent::node())"></valueOf>
+      <valueOf select="name(parent::*)"></valueOf>
+
+      <!-- name of root elemet -->
+      <valueOf select="name()">web-app</valueOf>
+      <valueOf select="name(.)">web-app</valueOf>
+      <valueOf select="name(../*)">web-app</valueOf>
+      <valueOf select="name(../child::node())">web-app</valueOf>
+    </context>
+  </document>
+
+
+
+  <!-- test predicates -->
+
+  <document url="xml/nitf.xml">
+    <context select="/nitf/head/docdata">
+      <test select="doc-id[@regsrc='AP' and @id-string='D76UIMO80']" count="1"/>
+    </context>
+    <context select="/nitf/head">
+      <test select="meta[@name='ap-cycle']" count="1"/>
+      <test select="meta[@content='AP']" count="1"/>
+      <test select="meta[@name and @content]" count="8"/>
+      <test select="meta[@name='ap-cycle' and @content='AP']" count="1"/>
+      <test select="meta[@name != 'ap-cycle']" count="7"/>
+    </context>
+    <context select="/">
+      <test select="/nitf/head/meta[@name='ap-cycle']" count="1"/>
+      <test select="/nitf/head/meta[@content='AP']" count="1"/>
+      <test select="/nitf/head/meta[@name and @content]" count="8"/>
+      <test select="/nitf/head/meta[@name='ap-cycle' and @content='AP']" count="1"/>
+      <test select="/nitf/head/meta[@name != 'ap-cycle']" count="7"/>
+    </context>
+  </document>
+
+
+  <document url="xml/moreover.xml">
+    <context select="/">
+      <test select="/child::node()" count="1"/>
+      <test select="/*" count="1"/>
+
+      <test select="/*/article" count="20"/>
+      <test select="//*" count="221"/>
+      <test select="//*[local-name()='article']" count="20"/>
+      <test select="//article" count="20"/>
+      <test select="/*/*[@code]" count="20"/>
+
+      <test select="/moreovernews/article[@code='13563275']" count="1"/>
+
+      <test select="/moreovernews/article[@code='13563275']">
+	<valueOf select="url">http://c.moreover.com/click/here.pl?x13563273</valueOf>
+      </test>
+      <test select="/*/article[@code='13563275']">
+	<valueOf select="url">http://c.moreover.com/click/here.pl?x13563273</valueOf>
+      </test>
+      <test select="//article[@code='13563275']">
+	<valueOf select="url">http://c.moreover.com/click/here.pl?x13563273</valueOf>
+      </test>
+      <test select="//*[@code='13563275']">
+	<valueOf select="url">http://c.moreover.com/click/here.pl?x13563273</valueOf>
+      </test>
+      <test select="/child::node()/child::node()[@code='13563275']">
+	<valueOf select="url">http://c.moreover.com/click/here.pl?x13563273</valueOf>
+      </test>
+      <test select="/*/*[@code='13563275']">
+	<valueOf select="url">http://c.moreover.com/click/here.pl?x13563273</valueOf>
+      </test>
+    </context>
+  </document>
+
+
+
+  <!-- test other node types-->
+
+  <document url="xml/contents.xml">
+    <context select="/">
+      <test select="processing-instruction()" count="3"/>
+      <test select="/processing-instruction()" count="3"/>
+      <test select="/comment()" count="1"/>
+      <test select="comment()" count="1"/>
+      <test select="/child::node()/comment()" count="2"/>
+      <test select="/*/comment()" count="2"/>
+      <test select="//comment()" count="3"/>
+    </context>
+  </document>
+
+
+
+  <!-- test positioning -->
+
+  <document url="xml/fibo.xml">
+    <context select="/">
+      <test select="/*/fibonacci[position() < 10]" count="9"/>
+      <valueOf select="sum(//fibonacci)">196417</valueOf>
+      <valueOf select="sum(//fibonacci/@index)">325</valueOf>
+      <valueOf select="/*/fibonacci[2]">1</valueOf>
+      <valueOf select="/*/fibonacci[ count(/*/fibonacci) ]">75025</valueOf>
+      <valueOf select="/*/fibonacci[ count(/*/fibonacci) - 1 ]">46368</valueOf>
+    </context>
+  </document>
+
+
+  <!-- test number functions -->
+
+  <!-- test Axes -->
+
+  <document url="xml/web.xml">
+    <context select="/">
+      <test select="descendant-or-self::*" count="19"/>
+      <test select="descendant::*" count="19"/>
+      <test select="/descendant::*" count="19"/>
+      <test select="/descendant-or-self::*" count="19"/>
+      <test select="/descendant::servlet" count="2"/>
+      <test select="/descendant-or-self::servlet" count="2"/>
+      <test select="descendant-or-self::servlet" count="2"/>
+      <test select="descendant::servlet" count="2"/>
+      <test select="/*/servlet" count="2"/>
+      <valueOf select="count(/*/servlet)">2</valueOf>
+      <test select="//servlet" count="2"/>
+      <valueOf select="count(//servlet)">2</valueOf>
+    </context>
+    <context select="/web-app">
+      <test select="/descendant::servlet" count="2"/>
+      <test select="/descendant-or-self::servlet" count="2"/>
+      <test select="descendant-or-self::servlet" count="2"/>
+      <test select="descendant::servlet" count="2"/>
+    </context>
+  </document>
+
+  <document url="xml/much_ado.xml">
+    <context select="/">
+      <test select="/descendant::ACT" count="5"/>
+      <test select="descendant::ACT" count="5"/>
+      <valueOf select="/PLAY/TITLE">Much Ado about Nothing</valueOf>
+      <valueOf select="2+2">4</valueOf>
+      <valueOf select="5 * 4 + 1">21</valueOf>
+      <valueOf select="count(descendant::ACT)">5</valueOf>
+      <valueOf select="10 + count(descendant::ACT) * 5">35</valueOf>
+      <valueOf select="(10 + count(descendant::ACT)) * 5">75</valueOf>
+    </context>
+    <context select="/PLAY/ACT[2]/SCENE[1]">
+      <test select="/descendant::ACT" count="5"/>
+      <test select="../../descendant::ACT" count="5"/>
+      <test select="/PLAY/ACT[2]/SCENE[1]/descendant::SPEAKER" count="141"/>
+      <test select="descendant::SPEAKER" count="141"/>
+      <valueOf select="count(descendant::*)+1">646</valueOf>
+      <valueOf select="count(descendant::SPEAKER)+1">142</valueOf>
+      <valueOf select="count(ancestor::*)">2</valueOf>
+      <valueOf select="count(ancestor::PLAY)">1</valueOf>
+      <valueOf select="count(ancestor-or-self::*)">3</valueOf>
+      <valueOf select="count(ancestor-or-self::PLAY)">1</valueOf>
+      <valueOf select="5+count(ancestor::*)-1">6</valueOf>
+    </context>
+    <context select="/">
+      <!-- Test correct predicate application -->
+      <valueOf select="count(/PLAY/ACT/SCENE[1])">5</valueOf>
+    </context>
+  </document>
+
+  <!-- test axis node ordering -->
+  <document url="xml/web.xml">
+    <context select="/">
+      <!-- Reported as Jira issue JAXEN-24 -->
+      <test select="//servlet-mapping/preceding::*[1][name()='description']" count="1"/>
+      <test select="/web-app/servlet//description/following::*[1][name()='servlet-mapping']" count="1"/>
+      <test select="/web-app/servlet//description/following::*[2][name()='servlet-name']" count="1"/>
+    </context>
+  </document>
+  
+  <!-- test document function -->
+  <document url="xml/text.xml">
+    <context select="/">
+      <test select="document('xml/web.xml')" count="1">
+	<valueOf select="/web-app/servlet[1]/servlet-name">snoop</valueOf>
+	<valueOf select="/web-app/servlet[1]/servlet-name/text()">snoop</valueOf>
+      </test>
+      <valueOf select="document('xml/web.xml')/web-app/servlet[1]/servlet-name">snoop</valueOf>
+    </context>
+    <!-- Test to check if the context changes when an extension function is used.
+    First test is an example, second is the actual test.
+    -->
+    <context select="/foo/bar/cheese[1]">
+      <valueOf select="concat(./@id,'foo', at id)">3foo3</valueOf>
+      <valueOf select="concat(./@id,document('xml/web.xml')/web-app/servlet[1]/servlet-name,./@id)">3snoop3</valueOf>
+    </context>
+  </document>
+
+  <document url="xml/message.xml">
+    <context select="/">
+      <valueOf select="/message/body/data/items/item[name/text()='parentinfo']/value">Pruefgebiete</valueOf>
+      <valueOf select="document('xml/message.xml')/message/body/data/items/item[name/text()='parentinfo']/value">Pruefgebiete</valueOf>
+    </context>
+  </document>
+
+  <document url="xml/simple.xml">
+
+    <!-- test behaviour of AbsoluteLocationPath -->
+    <context select="/root/a">
+      <valueOf select="concat( ., /root/b )">ab</valueOf>
+      <valueOf select="concat( ../b, . )">ba</valueOf>
+      <valueOf select="concat( /root/b, . )">ba</valueOf>
+      <valueOf select="concat( /root/c/d, ../b )">db</valueOf>
+    </context>
+
+    <!-- test the translate() function -->
+    <context select="/">
+      <valueOf select="translate( '', '', '' )"></valueOf>
+      <valueOf select="translate( 'abcd', '', '' )">abcd</valueOf>
+      <valueOf select="translate( 'abcd', 'abcd', 'abcd' )">abcd</valueOf>
+      <valueOf select="translate( 'abcd', 'dcba', 'dcba' )">abcd</valueOf>
+      <valueOf select="translate( 'abcd', 'abcd', 'dcba' )">dcba</valueOf>
+      <valueOf select="translate( 'abcd', 'abcd', 'ab' )">ab</valueOf>
+      <valueOf select="translate( 'abcd', 'cdab', 'cd' )">cd</valueOf>
+      <valueOf select="translate( 'abcd', 'acbd', 'xy' )">xy</valueOf>
+      <valueOf select="translate( 'abcd', 'abcdb', 'abcdb' )">abcd</valueOf>
+      <valueOf select="translate( 'abcd', 'abcd', 'abcdb' )">abcd</valueOf>
+    </context>
+
+    <context select="/">
+      <valueOf select="substring('12345', 1.5, 2.6)">234</valueOf>
+      <valueOf select="substring('12345', 0, 3)">12</valueOf>
+      <valueOf select="substring('12345', 0 div 0, 3)"></valueOf>
+      <valueOf select="substring('12345', 1, 0 div 0)"></valueOf>
+      <valueOf select="substring('12345', -42, 1 div 0)">12345</valueOf>
+      <valueOf select="substring('12345', -1 div 0, 1 div 0)"></valueOf>
+      <valueOf select="substring('12345', 3)">345</valueOf>
+      <valueOf select="substring('12345',1,15)">12345</valueOf>
+    </context>
+
+	<!-- Some tests for the normalize-space() function -->
+	
+	<context select="/">
+	  <valueOf select="normalize-space('    abc    ')">abc</valueOf>
+	  <valueOf select="normalize-space(' a  b  c  ')">a b c</valueOf>
+	  <valueOf select="normalize-space(' a &#x0d; b &#x0a;  c  ')">a b c</valueOf>
+	  <!-- Next test case addresses issue JAXEN-22 -->
+	  <valueOf select="normalize-space(' ')"></valueOf>
+	  <!-- Next test case addresses issue JAXEN-29 -->
+	  <valueOf select="normalize-space('')"></valueOf>
+	</context>
+  </document>
+
+
+
+  <!-- test cases for String extension functions -->
+  <document url="xml/web.xml">
+    <context select="/web-app/servlet[1]">
+      <valueOf select="upper-case( servlet-class )">SNOOPSERVLET</valueOf>
+      <valueOf select="lower-case( servlet-class )">snoopservlet</valueOf>
+      <valueOf select="upper-case( servlet-class, 'fr' )">SNOOPSERVLET</valueOf>
+      <valueOf select="upper-case( servlet-class, 'fr-CA' )">SNOOPSERVLET</valueOf>
+      <valueOf select="upper-case( servlet-class, 'es-ES-Traditional_WIN' )">SNOOPSERVLET</valueOf>
+      <valueOf select="ends-with( servlet-class, 'Servlet' )">true</valueOf>
+      <valueOf select="ends-with( servlet-class, 'S' )">false</valueOf>
+    </context>
+  </document>
+
+  <!-- test cases for the lang() function -->
+  <document url="xml/lang.xml">
+    <context select="/">
+      <test select="/e1/e2[lang('hr')]" count="0"/>
+      <test select="/e1/e2/e3[lang('en')]" count="1"/>
+      <test select="/e1/e2/e3[lang('en-US')]" count="1"/>
+      <test select="/e1/e2/e3[lang('en-GB')]" count="0"/>
+      <test select="/e1/e2/e3[lang('hu')]" count="2"/>
+      <test select="/e1/e2/e3[lang('hu-HU')]" count="0"/>
+      <test select="/e1/e2/e3[lang('es')]" count="1"/>
+      <test select="/e1/e2/e3[lang('es-BR')]" count="0"/>
+    </context>
+  </document>
+
+  <!-- test namespace -->
+  <document url="xml/namespaces.xml">
+    <context select="/"
+	     xmlns:foo="http://fooNamespace/"
+	     xmlns:voo="http://fooNamespace/"
+	     xmlns:bar="http://barNamespace/"
+	     xmlns:alias="http://fooNamespace/">
+      <test select="/*" count="1"/>
+      <test select="/foo:a" count="1"/>
+      <test select="/foo:a/b" count="1"/>
+      <test select="/voo:a/b/c" count="1"/>
+      <test select="/voo:a/bar:f" count="1"/>
+      <test select="/*[namespace-uri()='http://fooNamespace/' and local-name()='a']" count="1"/>
+      <test select="/*[local-name()='a' and namespace-uri()='http://fooNamespace/']/*[local-name()='x' and namespace-uri()='http://fooNamespace/']" count="1"/>
+      <test select="/*[local-name()='a' and namespace-uri()='http://fooNamespace/']/*[local-name()='x' and namespace-uri()='http://fooNamespace/']/*[local-name()='y' and namespace-uri()='http://fooNamespace/']" count="1"/>
+    </context>
+    <!-- the prefix here and in the document have no relation; it's their
+    namespace-uri binding that counts -->
+    <context select="/" xmlns:foo="http://somethingElse/">
+      <test select="/foo:a/b/c" count="0"/>
+    </context>
+
+    <context select="/"
+	     xmlns:foo="http://fooNamespace/"
+	     xmlns:bar="http://barNamespace/"
+	     xmlns:alias="http://fooNamespace/">
+      <valueOf select="/foo:a/b/c">Hello</valueOf>
+      <valueOf select="/foo:a/foo:d/foo:e">Hey</valueOf>
+      <valueOf select="/foo:a/alias:x/alias:y">Hey3</valueOf>
+      <valueOf select="/foo:a/foo:x/foo:y">Hey3</valueOf>
+      <valueOf select="/*[local-name()='a' and namespace-uri()='http://fooNamespace/']/*[local-name()='x' and namespace-uri()='http://fooNamespace/']/*[local-name()='y' and namespace-uri()='http://fooNamespace/']">Hey3</valueOf>
+    </context>
+
+  </document>
+
+  <document url="xml/defaultNamespace.xml">
+    <context select="/">
+      <!-- NOTE: /a/b/c selects elements in no namespace only! -->
+      <test select="/a/b/c" count="0"/>
+      <!--
+        The following test uses an unbound prefix 'x' and should throw an exception.
+        Addresses issue JAXEN-18.
+        Turns out this isn't really tested as the test didn't fail when the exception wasn't thrown.
+      <test select="/x:a/x:b/x:c" count="0" exception="true"/>
+      -->
+    </context>
+    <context select="/"
+	     xmlns:dummy="http://dummyNamespace/">
+      <test select="/dummy:a/dummy:b/dummy:c" count="1"/>
+    </context>
+  </document>
+  <document url="xml/text.xml">
+    <context select="/">
+      <test select="/foo/bar/text()" count="3"/>
+      <valueOf select="normalize-space(/foo/bar/text())">baz</valueOf>
+    </context>
+  </document>
+
+  <document url="xml/testNamespaces.xml">
+    <context select="/">
+      <!-- the root is not an element, so no namespaces -->
+      <test select="namespace::*" count="0" debug="off"/>
+      <test select="/namespace::*" count="0" debug="off"/>
+      <!-- must count the default xml: prefix as well -->
+      <test select="/Template/Application1/namespace::*" count="3" debug="off"/>
+      <test select="/Template/Application2/namespace::*" count="3" debug="off"/>
+
+      <!-- every element has separate copies -->
+      <test select="//namespace::*" count="25" debug="off"/>
+    </context>
+
+    <context select="/Template/Application1">
+      <!-- must count the default xml: prefix as well -->
+      <test select="namespace::*" count="3" debug="off"/>
+      <test select="/namespace::*" count="0" debug="off"/>
+      <test select="/Template/Application1/namespace::*" count="3" debug="off"/>
+      <test select="/Template/Application2/namespace::*" count="3" debug="off"/>
+      <test select="//namespace::*" count="25" debug="off"/>
+      <test select="//namespace::xplt" count="8" debug="off"/>
+      <!-- the name test literally matches the prefix as given in the
+      document, and does not use the uri -->
+      <test xmlns:somethingelse="http://www.xxxx.com/"
+	    select="//namespace::somethingelse" count="0" debug="off"/>
+    </context>
+  </document>
+
+  <document url="xml/testNamespaces.xml">
+    <context select="/">
+      <!-- namespace nodes have their element as their parent -->
+      <test select="/Template/namespace::xml/parent::Template" count="1"/>
+    </context>
+    <!-- namespace nodes can also be used as context nodes -->
+    <context select="/Template/namespace::xml">
+      <test select="parent::Template" count="1"/>
+    </context>
+  </document>
+
+</tests>
diff --git a/libjaxen-java/xml/test/tests.xsl b/libjaxen-java/xml/test/tests.xsl
new file mode 100644
index 0000000..3ecd648
--- /dev/null
+++ b/libjaxen-java/xml/test/tests.xsl
@@ -0,0 +1,369 @@
+<stylesheet	xmlns="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:var="http://jaxen.org/test-harness/var">
+<!-- this is what I used to generate XPathTestBase. After generating I fixed the illegal strings (its quicker
+than fixing the xsl for that few errors) and reformatted the code. Its unlikely this code will be needed
+again, its just in cvs for completeness -->
+    <output method="text"/>
+    <template match="/">
+        <text>
+            /*
+ * $Header: /home/projects/jaxen/scm/jaxen/src/java/test/org/jaxen/XPathTestBase.java,v 1.32 2005/06/15 23:52:40 bewins Exp $
+ * $Revision: 1.32 $
+ * $Date: 2005/06/15 23:52:40 $
+ *
+ * ====================================================================
+ *
+ * Copyright (C) 2000-2002 bob mcwhirter & James Strachan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions, and the disclaimer that follows
+ *    these conditions in the documentation and/or other materials
+ *    provided with the distribution.
+ *
+ * 3. The name "Jaxen" must not be used to endorse or promote products
+ *    derived from this software without prior written permission.  For
+ *    written permission, please contact license at jaxen.org.
+ *
+ * 4. Products derived from this software may not be called "Jaxen", nor
+ *    may "Jaxen" appear in their name, without prior written permission
+ *    from the Jaxen Project Management (pm at jaxen.org).
+ *
+ * In addition, we request (but do not require) that you include in the
+ * end-user documentation provided with the redistribution and/or in the
+ * software itself an acknowledgement equivalent to the following:
+ *     "This product includes software developed by the
+ *      Jaxen Project (http://www.jaxen.org/)."
+ * Alternatively, the acknowledgment may be graphical using the logos
+ * available at http://www.jaxen.org/
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE Jaxen AUTHORS OR THE PROJECT
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * ====================================================================
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Jaxen Project and was originally
+ * created by bob mcwhirter <bob at werken.com> and
+ * James Strachan <jstrachan at apache.org>.  For more information on the
+ * Jaxen Project, please see <http://www.jaxen.org/>.
+ *
+ * $Id: XPathTestBase.java,v 1.32 2005/06/15 23:52:40 bewins Exp $
+ */
+
+
+package org.jaxen;
+
+import junit.framework.TestCase;
+import org.jaxen.function.StringFunction;
+import org.jaxen.saxpath.helpers.XPathReaderFactory;
+
+import javax.xml.parsers.ParserConfigurationException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+public abstract class XPathTestBase extends TestCase
+{
+    protected static String VAR_URI   = "http://jaxen.org/test-harness/var";
+    protected static String TESTS_XML = "xml/test/tests.xml";
+
+    protected static boolean verbose = true;
+    protected static boolean debug = true;
+    private ContextSupport  contextSupport;
+
+    public XPathTestBase(String name)
+    {
+        super( name );
+    }
+
+    public void setUp() throws ParserConfigurationException
+    {
+        this.contextSupport = null;
+        System.setProperty( XPathReaderFactory.DRIVER_PROPERTY,
+                            "" );
+        log( "-----------------------------" );
+    }
+
+    public void log(String text)
+    {
+        log( verbose,
+             text );
+    }
+
+    public void log(boolean actualVerbose,
+                    String text)
+    {
+        if ( ! actualVerbose )
+        {
+            return;
+        }
+
+        System.out.println( text );
+    }
+
+    protected void assertCountXPath(int expectedSize, Object context, String xpathStr) throws JaxenException {
+        try
+        {
+            assertCountXPath2(expectedSize, context, xpathStr);
+        }
+        catch (UnsupportedAxisException e)
+        {
+            log ( debug,
+                  "      ## SKIPPED -- Unsupported Axis" );
+        }
+    }
+
+    protected Object assertCountXPath2(int expectedSize, Object context, String xpathStr) throws JaxenException {
+        log ( debug,
+              "  Select :: " + xpathStr );
+        BaseXPath xpath = new BaseXPath( xpathStr );
+        List results = xpath.selectNodes( getContext( context ) );
+        log ( debug,
+              "    Expected Size :: " + expectedSize );
+        log ( debug,
+              "    Result Size   :: " + results.size() );
+
+        if ( expectedSize != results.size() )
+        {
+            log ( debug,
+                  "      ## FAILED" );
+            log ( debug,
+                  "      ## xpath: " + xpath + " = " + xpath.debug() );
+
+            Iterator resultIter = results.iterator();
+
+            while ( resultIter.hasNext() )
+            {
+                log ( debug,
+                      "      --> " + resultIter.next() );
+            }
+        }
+        assertEquals( xpathStr,
+                      expectedSize,
+                      results.size() );
+        if (expectedSize > 0) {
+            return results.get(0);
+        }
+        return null;
+    }
+
+    protected void assertInvalidXPath(Object context, String xpathStr) throws JaxenException {
+        try 
+        {
+            log ( debug,
+                  "  Select :: " + xpathStr );
+            BaseXPath xpath = new BaseXPath( xpathStr );
+            List results = xpath.selectNodes( getContext( context ) );
+            log ( debug,
+                  "    Result Size   :: " + results.size() );
+            fail("An exception was expected.");
+        }
+        catch (UnsupportedAxisException e)
+        {
+            log ( debug,
+                  "      ## SKIPPED -- Unsupported Axis" );
+        }
+        catch (JaxenException e) {
+            log (debug, "    Caught expected exception "+e.getMessage());
+        }
+    }
+
+    protected void assertValueOfXPath(String expected, Object context, String xpathStr) throws JaxenException {
+        try
+        {
+            BaseXPath xpath = new BaseXPath( xpathStr );
+            Object node = xpath.evaluate( getContext( context ) );
+            
+            String result = StringFunction.evaluate( node,
+                                                     getNavigator() );
+            
+            log ( debug,
+                  "  Select :: " + xpathStr );
+            log ( debug,
+                  "    Expected :: " + expected );
+            log ( debug,
+                  "    Result   :: " + result );
+            
+            if ( ! expected.equals( result ) )
+            {
+                log ( debug,
+                      "      ## FAILED" );
+                log ( debug,
+                      "      ## xpath: " + xpath + " = " + xpath.debug() );
+            }
+            
+            assertEquals( xpathStr,
+                          expected,
+                          result );
+        }
+        catch (UnsupportedAxisException e)
+        {
+            log ( debug,
+                  "      ## SKIPPED -- Unsupported Axis " );
+
+        }        
+    }
+    protected Context getContext(Object contextNode)
+    {
+        Context context = new Context( getContextSupport() );
+
+        List list = new ArrayList( 1 );
+        list.add( contextNode );
+        context.setNodeSet( list );
+
+        return context;
+    }
+
+    public ContextSupport getContextSupport()
+    {
+        if ( this.contextSupport == null )
+        {
+            this.contextSupport = new ContextSupport( new SimpleNamespaceContext(),
+                                                      XPathFunctionContext.getInstance(),
+                                                      new SimpleVariableContext(),
+                                                      getNavigator() );
+        }
+
+        return this.contextSupport;
+    }
+
+    public abstract Navigator getNavigator();
+
+    public abstract Object getDocument(String url) throws Exception;
+
+    public void testGetNodeType() throws FunctionCallException, UnsupportedAxisException
+    {
+        Navigator nav = getNavigator();
+        Object document = nav.getDocument("xml/testNamespaces.xml");
+        int count = 0;
+        Iterator descendantOrSelfAxisIterator = nav.getDescendantOrSelfAxisIterator(document);
+        while (descendantOrSelfAxisIterator.hasNext()) {
+            Object node = descendantOrSelfAxisIterator.next();
+            Iterator namespaceAxisIterator = nav.getNamespaceAxisIterator(node);
+            while (namespaceAxisIterator.hasNext()) {
+                count++;
+                assertEquals("Node type mismatch", Pattern.NAMESPACE_NODE, nav.getNodeType(namespaceAxisIterator.next()));
+            }
+        }
+        assertEquals(25, count);
+    }
+
+        </text>
+        <apply-templates select="node()|@*"/>
+        <text>
+}            
+        </text>
+    </template>
+    <template match="context">
+        <text>
+    public void test</text><value-of select="generate-id()"/><text>() throws JaxenException {
+        Navigator nav = getNavigator();
+        String url = "</text><value-of select="../@url"/><text>";
+        log( "Document [" + url + "]" );
+        Object document = nav.getDocument(url);
+
+        XPath contextpath = new BaseXPath("</text><value-of select="@select"/><text>", nav);
+        log( "Initial Context :: " + contextpath );
+        List list = contextpath.selectNodes(document);
+        </text>
+        <if test="count(namespace::*) > count(../namespace::*)">
+        <text>
+        SimpleNamespaceContext nsContext = new SimpleNamespaceContext();</text>
+            <for-each select="namespace::*[local-name() != 'var' and local-name() != 'xml']">
+                <text>
+        nsContext.addNamespace( "</text><value-of select="local-name()"/><text>", "</text><value-of select="."/><text>" );</text>
+           </for-each>
+            <text>
+        getContextSupport().setNamespaceContext( nsContext );</text>
+        </if>
+        <if test="@*[namespace-uri() = 'http://jaxen.org/test-harness/var']">
+        <text>
+        SimpleVariableContext varContext = new SimpleVariableContext();</text>
+            <for-each select="@*[namespace-uri() = 'http://jaxen.org/test-harness/var']">
+                <text>
+        varContext.setVariableValue(null, "</text><value-of select="local-name()"/><text>", "</text><value-of select="."/><text>" );</text>
+           </for-each>
+            <text>
+        getContextSupport().setVariableContext( varContext );</text>
+        </if>
+        <text>
+        Iterator iter = list.iterator();
+        while (iter.hasNext()) {
+            Object context = iter.next();</text>
+            <apply-templates select="node()|@*"/>
+        <text>
+        }
+    }</text>
+    </template>
+    <template match="test[@exception]">
+        <text>
+            assertInvalidXPath(context, "</text><value-of select='@select'/><text>");</text>
+    </template>
+    <template match="test[valueOf]">
+        <choose>
+            <when test="@count">
+                <text>
+            try
+            {
+                Object result = assertCountXPath2(</text><value-of select="@count"/><text>, context, "</text><value-of select="@select"/><text>");</text>
+        <for-each select="valueOf">
+            <text>
+                assertValueOfXPath("</text><value-of select="."/><text>", result, "</text><value-of select="@select"/><text>");</text>
+        </for-each>
+        <text>
+            }
+            catch (UnsupportedAxisException e)
+            {
+                log ( debug, "      ## SKIPPED -- Unsupported Axis" );
+            }</text>
+            </when>
+            <otherwise>
+                <text>
+            try
+            {
+                BaseXPath xpath = new BaseXPath( "</text><value-of select="@select"/><text>" );
+                List results = xpath.selectNodes( getContext( context ) );
+                Object result = results.get(0);</text>
+        <for-each select="valueOf">
+            <text>
+                assertValueOfXPath("</text><value-of select="."/><text>", result, "</text><value-of select="@select"/><text>");</text>
+        </for-each>
+        <text>
+            }
+            catch (UnsupportedAxisException e)
+            {
+                log ( debug, "      ## SKIPPED -- Unsupported Axis" );
+            }</text>
+            </otherwise>
+        </choose>
+    </template>
+    <template match="test">
+        <text>
+            assertCountXPath(</text><value-of select="@count"/><text>, context, "</text><value-of select="@select"/><text>");</text>
+    </template>
+    <template match="valueOf">
+        <text>
+            assertValueOfXPath("</text><value-of select="."/>", context, "<value-of select="@select"/><text>");</text>
+    </template>
+    <template match="comment()"><text>
+    /*</text><value-of select="."/><text>
+    */</text>
+    </template>
+    <template match="node()|@*"><apply-templates select="node()|@*"/></template>    
+</stylesheet>
\ No newline at end of file
diff --git a/libjaxen-java/xml/testNamespaces.xml b/libjaxen-java/xml/testNamespaces.xml
new file mode 100644
index 0000000..50f7c93
--- /dev/null
+++ b/libjaxen-java/xml/testNamespaces.xml
@@ -0,0 +1,22 @@
+<Template> 
+  <Application1 xmlns:xplt="http://www.xxxx.com/"
+                xmlns:xpl="http://www.xxxx.com/"
+                version="3.0"
+                randomAttribute="foo"
+  >
+    <xpl:insertText/> 
+    <xplt:anyElement> 
+      <Name/> 
+    </xplt:anyElement> 
+  </Application1> 
+
+  <Application2 xmlns:xplt="http://www.xxxx.com/"
+                xmlns:xpl="http://www.xxxx.com/"
+                version="3.0"
+  > 
+    <xpl:insertText/> 
+    <xplt:anyElement> 
+      <Name/> 
+    </xplt:anyElement> 
+  </Application2> 
+</Template>
diff --git a/libjaxen-java/xml/text.xml b/libjaxen-java/xml/text.xml
new file mode 100644
index 0000000..e1865c7
--- /dev/null
+++ b/libjaxen-java/xml/text.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0"?>
+<foo>
+	<bar>
+		baz
+		<cheese id="3"/>
+		baz
+		<cheese/>
+		baz
+	</bar>
+</foo>
diff --git a/libjaxen-java/xml/underscore.xml b/libjaxen-java/xml/underscore.xml
new file mode 100644
index 0000000..111446f
--- /dev/null
+++ b/libjaxen-java/xml/underscore.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" ?>
+<root a="1" _a="2">
+  <b>1</b>
+  <_b>2</_b>
+</root>
+  
diff --git a/libjaxen-java/xml/web.xml b/libjaxen-java/xml/web.xml
new file mode 100644
index 0000000..972cf5d
--- /dev/null
+++ b/libjaxen-java/xml/web.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<web-app>
+  <servlet>
+    <servlet-name>snoop</servlet-name>
+    <servlet-class>SnoopServlet</servlet-class>
+  </servlet>
+  <servlet>
+    <servlet-name>file</servlet-name>
+    <servlet-class>ViewFile</servlet-class>
+    <init-param>
+      <param-name>initial</param-name>
+      <param-value>
+        1000
+      </param-value>
+      <description>
+        The initial value for the counter  <!-- optional -->
+      </description>
+    </init-param>
+  </servlet>
+  <servlet-mapping>
+    <servlet-name>
+      mv
+    </servlet-name>
+    <url-pattern>
+      *.wm
+    </url-pattern>
+  </servlet-mapping>
+
+  <distributed/>
+
+  <security-role>
+    <role-name>
+     manager
+    </role-name>
+    <role-name>
+     director
+    </role-name>
+    <role-name>
+     president
+    </role-name>
+  </security-role>
+</web-app>
diff --git a/libjaxen-java/xml/web2.xml b/libjaxen-java/xml/web2.xml
new file mode 100644
index 0000000..7d479d3
--- /dev/null
+++ b/libjaxen-java/xml/web2.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<root>
+  <b>
+    <d />
+  </b>
+  <c />
+</root>

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-java/libjaxen-java.git



More information about the pkg-java-commits mailing list