8054196: XPath: support any type
authorjoehw
Tue, 27 Jan 2015 22:01:46 -0800
changeset 28695 427254b89b9e
parent 28694 b99e1eee0669
child 28696 dd8c7efde993
8054196: XPath: support any type Reviewed-by: alanb, lancea, dfuchs
jaxp/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/jaxp/XPathExpressionImpl.java
jaxp/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/jaxp/XPathImpl.java
jaxp/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/jaxp/XPathImplUtil.java
jaxp/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/jaxp/XPathNodesImpl.java
jaxp/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/jaxp/XPathResultImpl.java
jaxp/src/java.xml/share/classes/javax/xml/xpath/XPath.java
jaxp/src/java.xml/share/classes/javax/xml/xpath/XPathEvaluationResult.java
jaxp/src/java.xml/share/classes/javax/xml/xpath/XPathExpression.java
jaxp/src/java.xml/share/classes/javax/xml/xpath/XPathFactory.java
jaxp/src/java.xml/share/classes/javax/xml/xpath/XPathFactoryFinder.java
jaxp/src/java.xml/share/classes/javax/xml/xpath/XPathNodes.java
jaxp/src/java.xml/share/classes/javax/xml/xpath/package.html
jaxp/test/javax/xml/jaxp/unittest/javax/xml/xpath/XPathAnyTypeTest.java
jaxp/test/javax/xml/jaxp/unittest/javax/xml/xpath/XPathExpAnyTypeTest.java
jaxp/test/javax/xml/jaxp/unittest/javax/xml/xpath/XPathTestBase.java
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/jaxp/XPathExpressionImpl.java	Mon Jan 26 12:17:59 2015 +0300
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/jaxp/XPathExpressionImpl.java	Tue Jan 27 22:01:46 2015 -0800
@@ -1,15 +1,15 @@
 /*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
  */
 /*
- * Copyright 1999-2004 The Apache Software Foundation.
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
  *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -17,36 +17,21 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-// $Id: XPathExpressionImpl.java,v 1.3 2005/09/27 09:40:43 sunithareddy Exp $
 
 package com.sun.org.apache.xpath.internal.jaxp;
 
-import com.sun.org.apache.xpath.internal.*;
-import javax.xml.transform.TransformerException;
-
+import com.sun.org.apache.xalan.internal.utils.FeatureManager;
 import com.sun.org.apache.xpath.internal.objects.XObject;
-import com.sun.org.apache.xml.internal.dtm.DTM;
-import com.sun.org.apache.xml.internal.utils.PrefixResolver;
-import com.sun.org.apache.xpath.internal.res.XPATHErrorResources;
-import com.sun.org.apache.xalan.internal.res.XSLMessages;
-import com.sun.org.apache.xalan.internal.utils.FactoryImpl;
-import com.sun.org.apache.xalan.internal.utils.FeatureManager;
-
-import javax.xml.namespace.NamespaceContext;
 import javax.xml.namespace.QName;
+import javax.xml.transform.TransformerException;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathEvaluationResult;
+import javax.xml.xpath.XPathExpression;
 import javax.xml.xpath.XPathExpressionException;
-import javax.xml.xpath.XPathConstants;
 import javax.xml.xpath.XPathFunctionResolver;
 import javax.xml.xpath.XPathVariableResolver;
-import javax.xml.xpath.XPathConstants;
-
+import org.w3c.dom.Document;
 import org.w3c.dom.Node;
-import org.w3c.dom.Document;
-import org.w3c.dom.DOMImplementation;
-import org.w3c.dom.traversal.NodeIterator;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.DocumentBuilder;
-
 import org.xml.sax.InputSource;
 
 /**
@@ -54,21 +39,9 @@
  *
  * @author  Ramesh Mandava
  */
-public class XPathExpressionImpl  implements javax.xml.xpath.XPathExpression{
-
-    private XPathFunctionResolver functionResolver;
-    private XPathVariableResolver variableResolver;
-    private JAXPPrefixResolver prefixResolver;
-    private com.sun.org.apache.xpath.internal.XPath xpath;
+public class XPathExpressionImpl extends XPathImplUtil implements XPathExpression {
 
-    // By default Extension Functions are allowed in XPath Expressions. If
-    // Secure Processing Feature is set on XPathFactory then the invocation of
-    // extensions function need to throw XPathFunctionException
-    private boolean featureSecureProcessing = false;
-
-    private boolean useServicesMechanism = true;
-
-    private final FeatureManager featureManager;
+    private com.sun.org.apache.xpath.internal.XPath xpath;
 
     /** Protected constructor to prevent direct instantiation; use compile()
      * from the context.
@@ -81,7 +54,7 @@
     protected XPathExpressionImpl(com.sun.org.apache.xpath.internal.XPath xpath,
             JAXPPrefixResolver prefixResolver,
             XPathFunctionResolver functionResolver,
-            XPathVariableResolver variableResolver ) {
+            XPathVariableResolver variableResolver) {
         this(xpath, prefixResolver, functionResolver, variableResolver,
              false, true, new FeatureManager());
     };
@@ -89,291 +62,108 @@
     protected XPathExpressionImpl(com.sun.org.apache.xpath.internal.XPath xpath,
             JAXPPrefixResolver prefixResolver,XPathFunctionResolver functionResolver,
             XPathVariableResolver variableResolver, boolean featureSecureProcessing,
-            boolean useServicesMechanism, FeatureManager featureManager ) {
+            boolean useServiceMechanism, FeatureManager featureManager) {
         this.xpath = xpath;
         this.prefixResolver = prefixResolver;
         this.functionResolver = functionResolver;
         this.variableResolver = variableResolver;
         this.featureSecureProcessing = featureSecureProcessing;
-        this.useServicesMechanism = useServicesMechanism;
+        this.useServiceMechanism = useServiceMechanism;
         this.featureManager = featureManager;
     };
 
-    public void setXPath (com.sun.org.apache.xpath.internal.XPath xpath ) {
+    public void setXPath (com.sun.org.apache.xpath.internal.XPath xpath) {
         this.xpath = xpath;
     }
 
     public Object eval(Object item, QName returnType)
             throws javax.xml.transform.TransformerException {
-        XObject resultObject = eval ( item );
-        return getResultAsType( resultObject, returnType );
-    }
-
-    private XObject eval ( Object contextItem )
-            throws javax.xml.transform.TransformerException {
-        com.sun.org.apache.xpath.internal.XPathContext xpathSupport = null;
-        if ( functionResolver != null ) {
-            JAXPExtensionsProvider jep = new JAXPExtensionsProvider(
-                    functionResolver, featureSecureProcessing, featureManager );
-            xpathSupport = new com.sun.org.apache.xpath.internal.XPathContext( jep );
-        } else {
-            xpathSupport = new com.sun.org.apache.xpath.internal.XPathContext();
-        }
-
-        xpathSupport.setVarStack(new JAXPVariableStack(variableResolver));
-        XObject xobj = null;
-
-        Node contextNode = (Node)contextItem;
-        // We always need to have a ContextNode with Xalan XPath implementation
-        // To allow simple expression evaluation like 1+1 we are setting
-        // dummy Document as Context Node
-
-        if ( contextNode == null )
-            xobj = xpath.execute(xpathSupport, DTM.NULL, prefixResolver);
-        else
-            xobj = xpath.execute(xpathSupport, contextNode, prefixResolver);
-
-        return xobj;
+        XObject resultObject = eval(item, xpath);
+        return getResultAsType(resultObject, returnType);
     }
 
-
-    /**
-     * <p>Evaluate the compiled XPath expression in the specified context and
-     *  return the result as the specified type.</p>
-     *
-     * <p>See "Evaluation of XPath Expressions" section of JAXP 1.3 spec
-     * for context item evaluation,
-     * variable, function and QName resolution and return type conversion.</p>
-     *
-     * <p>If <code>returnType</code> is not one of the types defined
-     * in {@link XPathConstants},
-     * then an <code>IllegalArgumentException</code> is thrown.</p>
-     *
-     * <p>If a <code>null</code> value is provided for
-     * <code>item</code>, an empty document will be used for the
-     * context.
-     * If <code>returnType</code> is <code>null</code>, then a
-     * <code>NullPointerException</code> is thrown.</p>
-     *
-     * @param item The starting context (node or node list, for example).
-     * @param returnType The desired return type.
-     *
-     * @return The <code>Object</code> that is the result of evaluating the
-     * expression and converting the result to
-     *   <code>returnType</code>.
-     *
-     * @throws XPathExpressionException If the expression cannot be evaluated.
-     * @throws IllegalArgumentException If <code>returnType</code> is not one
-     * of the types defined in {@link XPathConstants}.
-     * @throws NullPointerException If  <code>returnType</code> is
-     * <code>null</code>.
-     */
+    @Override
     public Object evaluate(Object item, QName returnType)
         throws XPathExpressionException {
-        //Validating parameters to enforce constraints defined by JAXP spec
-        if ( returnType == null ) {
-           //Throwing NullPointerException as defined in spec
-            String fmsg = XSLMessages.createXPATHMessage(
-                    XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
-                    new Object[] {"returnType"} );
-            throw new NullPointerException( fmsg );
-        }
-        // Checking if requested returnType is supported. returnType need to be
-        // defined in XPathConstants
-        if ( !isSupported ( returnType ) ) {
-            String fmsg = XSLMessages.createXPATHMessage(
-                    XPATHErrorResources.ER_UNSUPPORTED_RETURN_TYPE,
-                    new Object[] { returnType.toString() } );
-            throw new IllegalArgumentException ( fmsg );
-        }
+        isSupported(returnType);
         try {
-            return eval( item, returnType);
-        } catch ( java.lang.NullPointerException npe ) {
+            return eval(item, returnType);
+        } catch (java.lang.NullPointerException npe) {
             // If VariableResolver returns null Or if we get
             // NullPointerException at this stage for some other reason
             // then we have to reurn XPathException
-            throw new XPathExpressionException ( npe );
-        } catch ( javax.xml.transform.TransformerException te ) {
+            throw new XPathExpressionException (npe);
+        } catch (javax.xml.transform.TransformerException te) {
             Throwable nestedException = te.getException();
-            if ( nestedException instanceof javax.xml.xpath.XPathFunctionException ) {
+            if (nestedException instanceof javax.xml.xpath.XPathFunctionException) {
                 throw (javax.xml.xpath.XPathFunctionException)nestedException;
             } else {
                 // For any other exceptions we need to throw
-                // XPathExpressionException ( as per spec )
-                throw new XPathExpressionException( te);
+                // XPathExpressionException (as per spec)
+                throw new XPathExpressionException(te);
             }
         }
-
-    }
-
-    /**
-     * <p>Evaluate the compiled XPath expression in the specified context and
-     * return the result as a <code>String</code>.</p>
-     *
-     * <p>This method calls {@link #evaluate(Object item, QName returnType)}
-     * with a <code>returnType</code> of
-     * {@link XPathConstants#STRING}.</p>
-     *
-     * <p>See "Evaluation of XPath Expressions" section of JAXP 1.3 spec
-     *  for context item evaluation,
-     * variable, function and QName resolution and return type conversion.</p>
-     *
-     * <p>If a <code>null</code> value is provided for
-     * <code>item</code>, an empty document will be used for the
-     * context.
-     *
-     * @param item The starting context (node or node list, for example).
-     *
-     * @return The <code>String</code> that is the result of evaluating the
-     * expression and converting the result to a
-     *   <code>String</code>.
-     *
-     * @throws XPathExpressionException If the expression cannot be evaluated.
-     */
-    public String evaluate(Object item)
-        throws XPathExpressionException {
-        return (String)this.evaluate( item, XPathConstants.STRING );
     }
 
 
-
-    static DocumentBuilderFactory dbf = null;
-    static DocumentBuilder db = null;
-    static Document d = null;
+    @Override
+    public String evaluate(Object item)
+        throws XPathExpressionException {
+        return (String)this.evaluate(item, XPathConstants.STRING);
+    }
 
-    /**
-     * <p>Evaluate the compiled XPath expression in the context of the
-     * specified <code>InputSource</code> and return the result as the
-     *  specified type.</p>
-     *
-     * <p>This method builds a data model for the {@link InputSource} and calls
-     * {@link #evaluate(Object item, QName returnType)} on the resulting
-     * document object.</p>
-     *
-     * <p>See "Evaluation of XPath Expressions" section of JAXP 1.3 spec
-     *  for context item evaluation,
-     * variable, function and QName resolution and return type conversion.</p>
-     *
-     * <p>If <code>returnType</code> is not one of the types defined in
-     * {@link XPathConstants},
-     * then an <code>IllegalArgumentException</code> is thrown.</p>
-     *
-     *<p>If <code>source</code> or <code>returnType</code> is <code>null</code>,
-     * then a <code>NullPointerException</code> is thrown.</p>
-     *
-     * @param source The <code>InputSource</code> of the document to evaluate
-     * over.
-     * @param returnType The desired return type.
-     *
-     * @return The <code>Object</code> that is the result of evaluating the
-     * expression and converting the result to
-     *   <code>returnType</code>.
-     *
-     * @throws XPathExpressionException If the expression cannot be evaluated.
-     * @throws IllegalArgumentException If <code>returnType</code> is not one
-     * of the types defined in {@link XPathConstants}.
-     * @throws NullPointerException If  <code>source</code> or
-     * <code>returnType</code> is <code>null</code>.
-     */
+    @Override
     public Object evaluate(InputSource source, QName returnType)
         throws XPathExpressionException {
-        if ( ( source == null ) || ( returnType == null ) ) {
-            String fmsg = XSLMessages.createXPATHMessage(
-                    XPATHErrorResources.ER_SOURCE_RETURN_TYPE_CANNOT_BE_NULL,
-                    null );
-            throw new NullPointerException ( fmsg );
-        }
-        // Checking if requested returnType is supported. returnType need to be
-        // defined in XPathConstants
-        if ( !isSupported ( returnType ) ) {
-            String fmsg = XSLMessages.createXPATHMessage(
-                    XPATHErrorResources.ER_UNSUPPORTED_RETURN_TYPE,
-                    new Object[] { returnType.toString() } );
-            throw new IllegalArgumentException ( fmsg );
-        }
+        isSupported (returnType);
         try {
-            if ( dbf == null ) {
-                dbf = FactoryImpl.getDOMFactory(useServicesMechanism);
-                dbf.setNamespaceAware( true );
-                dbf.setValidating( false );
-            }
-            db = dbf.newDocumentBuilder();
-            Document document = db.parse( source );
-            return eval(  document, returnType );
-        } catch ( Exception e ) {
-            throw new XPathExpressionException ( e );
+            Document document = getDocument(source);
+            return eval(document, returnType);
+        } catch (TransformerException e) {
+            throw new XPathExpressionException(e);
         }
     }
 
-    /**
-     * <p>Evaluate the compiled XPath expression in the context of the specified <code>InputSource</code> and return the result as a
-     * <code>String</code>.</p>
-     *
-     * <p>This method calls {@link #evaluate(InputSource source, QName returnType)} with a <code>returnType</code> of
-     * {@link XPathConstants#STRING}.</p>
-     *
-     * <p>See "Evaluation of XPath Expressions" section of JAXP 1.3 spec
-     * for context item evaluation,
-     * variable, function and QName resolution and return type conversion.</p>
-     *
-     * <p>If <code>source</code> is <code>null</code>, then a <code>NullPointerException</code> is thrown.</p>
-     *
-     * @param source The <code>InputSource</code> of the document to evaluate over.
-     *
-     * @return The <code>String</code> that is the result of evaluating the expression and converting the result to a
-     *   <code>String</code>.
-     *
-     * @throws XPathExpressionException If the expression cannot be evaluated.
-     * @throws NullPointerException If  <code>source</code> is <code>null</code>.
-     */
+    @Override
     public String evaluate(InputSource source)
         throws XPathExpressionException {
-        return (String)this.evaluate( source, XPathConstants.STRING );
+        return (String)this.evaluate(source, XPathConstants.STRING);
     }
 
-    private boolean isSupported( QName returnType ) {
-        // XPathConstants.STRING
-        if ( ( returnType.equals( XPathConstants.STRING ) ) ||
-             ( returnType.equals( XPathConstants.NUMBER ) ) ||
-             ( returnType.equals( XPathConstants.BOOLEAN ) ) ||
-             ( returnType.equals( XPathConstants.NODE ) ) ||
-             ( returnType.equals( XPathConstants.NODESET ) )  ) {
+    @Override
+    public <T>T evaluateExpression(Object item, Class<T> type)
+        throws XPathExpressionException {
+        isSupportedClassType(type);
 
-            return true;
-        }
-        return false;
-     }
+        try {
+            XObject resultObject = eval(item, xpath);
+            if (type.isAssignableFrom(XPathEvaluationResult.class)) {
+                return getXPathResult(resultObject, type);
+            } else {
+                return XPathResultImpl.getValue(resultObject, type);
+            }
 
-     private Object getResultAsType( XObject resultObject, QName returnType )
-        throws javax.xml.transform.TransformerException {
-        // XPathConstants.STRING
-        if ( returnType.equals( XPathConstants.STRING ) ) {
-            return resultObject.str();
+        } catch (javax.xml.transform.TransformerException te) {
+            throw new XPathExpressionException(te);
         }
-        // XPathConstants.NUMBER
-        if ( returnType.equals( XPathConstants.NUMBER ) ) {
-            return new Double ( resultObject.num());
-        }
-        // XPathConstants.BOOLEAN
-        if ( returnType.equals( XPathConstants.BOOLEAN ) ) {
-            return new Boolean( resultObject.bool());
-        }
-        // XPathConstants.NODESET ---ORdered, UNOrdered???
-        if ( returnType.equals( XPathConstants.NODESET ) ) {
-            return resultObject.nodelist();
-        }
-        // XPathConstants.NODE
-        if ( returnType.equals( XPathConstants.NODE ) ) {
-            NodeIterator ni = resultObject.nodeset();
-            //Return the first node, or null
-            return ni.nextNode();
-        }
-        // If isSupported check is already done then the execution path
-        // shouldn't come here. Being defensive
-        String fmsg = XSLMessages.createXPATHMessage(
-                XPATHErrorResources.ER_UNSUPPORTED_RETURN_TYPE,
-                new Object[] { returnType.toString()});
-        throw new IllegalArgumentException ( fmsg );
     }
 
+    @Override
+    public XPathEvaluationResult<?> evaluateExpression(Object item)
+        throws XPathExpressionException {
+        return evaluateExpression(item, XPathEvaluationResult.class);
+    }
+
+    @Override
+    public <T>T  evaluateExpression(InputSource source, Class<T> type)
+            throws XPathExpressionException {
+        Document document = getDocument(source);
+        return evaluateExpression(document, type);
+    }
+
+    @Override
+    public XPathEvaluationResult<?> evaluateExpression(InputSource source)
+        throws XPathExpressionException {
+        return evaluateExpression(source, XPathEvaluationResult.class);
+    }
  }
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/jaxp/XPathImpl.java	Mon Jan 26 12:17:59 2015 +0300
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/jaxp/XPathImpl.java	Tue Jan 27 22:01:46 2015 -0800
@@ -1,6 +1,5 @@
 /*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Copyright 1999-2004 The Apache Software Foundation.
@@ -28,55 +27,37 @@
 import javax.xml.xpath.XPathFunctionResolver;
 import javax.xml.xpath.XPathVariableResolver;
 import javax.xml.xpath.XPathExpression;
-
-import com.sun.org.apache.xml.internal.dtm.DTM;
 import com.sun.org.apache.xpath.internal.*;
 import com.sun.org.apache.xpath.internal.objects.XObject;
-import com.sun.org.apache.xpath.internal.res.XPATHErrorResources;
-import com.sun.org.apache.xalan.internal.res.XSLMessages;
-import com.sun.org.apache.xalan.internal.utils.FactoryImpl;
 import com.sun.org.apache.xalan.internal.utils.FeatureManager;
-
-import org.w3c.dom.Node;
 import org.w3c.dom.Document;
-import org.w3c.dom.traversal.NodeIterator;
-
 import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
-
-import javax.xml.parsers.*;
-
-import java.io.IOException;
+import javax.xml.transform.TransformerException;
+import javax.xml.xpath.XPathEvaluationResult;
 
 /**
  * The XPathImpl class provides implementation for the methods defined  in
- * javax.xml.xpath.XPath interface. This provide simple access to the results
+ * javax.xml.xpath.XPath interface. This provides simple access to the results
  * of an XPath expression.
  *
- *
  * @author  Ramesh Mandava
+ *
+ * Updated 12/04/2014:
+ * New methods: evaluateExpression
+ * Refactored to share code with XPathExpressionImpl.
  */
-public class XPathImpl implements javax.xml.xpath.XPath {
+public class XPathImpl extends XPathImplUtil implements javax.xml.xpath.XPath {
 
     // Private variables
-    private XPathVariableResolver variableResolver;
-    private XPathFunctionResolver functionResolver;
     private XPathVariableResolver origVariableResolver;
     private XPathFunctionResolver origFunctionResolver;
     private NamespaceContext namespaceContext=null;
-    private JAXPPrefixResolver prefixResolver;
-    // By default Extension Functions are allowed in XPath Expressions. If
-    // Secure Processing Feature is set on XPathFactory then the invocation of
-    // extensions function need to throw XPathFunctionException
-    private boolean featureSecureProcessing = false;
-    private boolean useServiceMechanism = true;
-    private final FeatureManager featureManager;
 
-    XPathImpl( XPathVariableResolver vr, XPathFunctionResolver fr ) {
+    XPathImpl(XPathVariableResolver vr, XPathFunctionResolver fr) {
         this(vr, fr, false, true, new FeatureManager());
     }
 
-    XPathImpl( XPathVariableResolver vr, XPathFunctionResolver fr,
+    XPathImpl(XPathVariableResolver vr, XPathFunctionResolver fr,
             boolean featureSecureProcessing, boolean useServiceMechanism,
             FeatureManager featureManager) {
         this.origVariableResolver = this.variableResolver = vr;
@@ -86,451 +67,173 @@
         this.featureManager = featureManager;
     }
 
-    /**
-     * <p>Establishes a variable resolver.</p>
-     *
-     * @param resolver Variable Resolver
-     */
+
+    //-Override-
     public void setXPathVariableResolver(XPathVariableResolver resolver) {
-        if ( resolver == null ) {
-            String fmsg = XSLMessages.createXPATHMessage(
-                    XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
-                    new Object[] {"XPathVariableResolver"} );
-            throw new NullPointerException( fmsg );
-        }
+        requireNonNull(resolver, "XPathVariableResolver");
         this.variableResolver = resolver;
     }
 
-    /**
-     * <p>Returns the current variable resolver.</p>
-     *
-     * @return Current variable resolver
-     */
+    //-Override-
     public XPathVariableResolver getXPathVariableResolver() {
         return variableResolver;
     }
 
-    /**
-     * <p>Establishes a function resolver.</p>
-     *
-     * @param resolver XPath function resolver
-     */
+    //-Override-
     public void setXPathFunctionResolver(XPathFunctionResolver resolver) {
-        if ( resolver == null ) {
-            String fmsg = XSLMessages.createXPATHMessage(
-                    XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
-                    new Object[] {"XPathFunctionResolver"} );
-            throw new NullPointerException( fmsg );
-        }
+        requireNonNull(resolver, "XPathFunctionResolver");
         this.functionResolver = resolver;
     }
 
-    /**
-     * <p>Returns the current function resolver.</p>
-     *
-     * @return Current function resolver
-     */
+    //-Override-
     public XPathFunctionResolver getXPathFunctionResolver() {
         return functionResolver;
     }
 
-    /**
-     * <p>Establishes a namespace context.</p>
-     *
-     * @param nsContext Namespace context to use
-     */
+    //-Override-
     public void setNamespaceContext(NamespaceContext nsContext) {
-        if ( nsContext == null ) {
-            String fmsg = XSLMessages.createXPATHMessage(
-                    XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
-                    new Object[] {"NamespaceContext"} );
-            throw new NullPointerException( fmsg );
-        }
+        requireNonNull(nsContext, "NamespaceContext");
         this.namespaceContext = nsContext;
-        this.prefixResolver = new JAXPPrefixResolver ( nsContext );
+        this.prefixResolver = new JAXPPrefixResolver (nsContext);
     }
 
-    /**
-     * <p>Returns the current namespace context.</p>
-     *
-     * @return Current Namespace context
-     */
+    //-Override-
     public NamespaceContext getNamespaceContext() {
         return namespaceContext;
     }
 
-    private static Document d = null;
-
-    private DocumentBuilder getParser() {
-        try {
-            // we'd really like to cache those DocumentBuilders, but we can't because:
-            // 1. thread safety. parsers are not thread-safe, so at least
-            //    we need one instance per a thread.
-            // 2. parsers are non-reentrant, so now we are looking at having a
-            // pool of parsers.
-            // 3. then the class loading issue. The look-up procedure of
-            //    DocumentBuilderFactory.newInstance() depends on context class loader
-            //    and system properties, which may change during the execution of JVM.
-            //
-            // so we really have to create a fresh DocumentBuilder every time we need one
-            // - KK
-            DocumentBuilderFactory dbf = FactoryImpl.getDOMFactory(useServiceMechanism);
-            dbf.setNamespaceAware( true );
-            dbf.setValidating( false );
-            return dbf.newDocumentBuilder();
-        } catch (ParserConfigurationException e) {
-            // this should never happen with a well-behaving JAXP implementation.
-            throw new Error(e);
-        }
-    }
-
+    /**
+     * Evaluate an {@code XPath} expression in the specified context.
+     * @param expression The XPath expression.
+     * @param contextItem The starting context.
+     * @return an XObject as the result of evaluating the expression
+     * @throws TransformerException if evaluating fails
+     */
+    private XObject eval(String expression, Object contextItem)
+        throws TransformerException {
+        requireNonNull(expression, "XPath expression");
+        com.sun.org.apache.xpath.internal.XPath xpath = new com.sun.org.apache.xpath.internal.XPath(expression,
+            null, prefixResolver, com.sun.org.apache.xpath.internal.XPath.SELECT);
 
-    private XObject eval(String expression, Object contextItem)
-        throws javax.xml.transform.TransformerException {
-        com.sun.org.apache.xpath.internal.XPath xpath = new com.sun.org.apache.xpath.internal.XPath( expression,
-            null, prefixResolver, com.sun.org.apache.xpath.internal.XPath.SELECT );
-        com.sun.org.apache.xpath.internal.XPathContext xpathSupport = null;
-        if ( functionResolver != null ) {
-            JAXPExtensionsProvider jep = new JAXPExtensionsProvider(
-                    functionResolver, featureSecureProcessing, featureManager );
-            xpathSupport = new com.sun.org.apache.xpath.internal.XPathContext( jep );
-        } else {
-            xpathSupport = new com.sun.org.apache.xpath.internal.XPathContext();
-        }
-
-        XObject xobj = null;
-
-        xpathSupport.setVarStack(new JAXPVariableStack(variableResolver));
-
-        // If item is null, then we will create a a Dummy contextNode
-        if ( contextItem instanceof Node ) {
-            xobj = xpath.execute (xpathSupport, (Node)contextItem,
-                    prefixResolver );
-        } else {
-            xobj = xpath.execute ( xpathSupport, DTM.NULL, prefixResolver );
-        }
-
-        return xobj;
+        return eval(contextItem, xpath);
     }
 
-    /**
-     * <p>Evaluate an <code>XPath</code> expression in the specified context and return the result as the specified type.</p>
-     *
-     * <p>See "Evaluation of XPath Expressions" section of JAXP 1.3 spec
-     * for context item evaluation,
-     * variable, function and <code>QName</code> resolution and return type conversion.</p>
-     *
-     * <p>If <code>returnType</code> is not one of the types defined in {@link XPathConstants} (
-     * {@link XPathConstants#NUMBER NUMBER},
-     * {@link XPathConstants#STRING STRING},
-     * {@link XPathConstants#BOOLEAN BOOLEAN},
-     * {@link XPathConstants#NODE NODE} or
-     * {@link XPathConstants#NODESET NODESET})
-     * then an <code>IllegalArgumentException</code> is thrown.</p>
-     *
-     * <p>If a <code>null</code> value is provided for
-     * <code>item</code>, an empty document will be used for the
-     * context.
-     * If <code>expression</code> or <code>returnType</code> is <code>null</code>, then a
-     * <code>NullPointerException</code> is thrown.</p>
-     *
-     * @param expression The XPath expression.
-     * @param item The starting context (node or node list, for example).
-     * @param returnType The desired return type.
-     *
-     * @return Result of evaluating an XPath expression as an <code>Object</code> of <code>returnType</code>.
-     *
-     * @throws XPathExpressionException If <code>expression</code> cannot be evaluated.
-     * @throws IllegalArgumentException If <code>returnType</code> is not one of the types defined in {@link XPathConstants}.
-     * @throws NullPointerException If <code>expression</code> or <code>returnType</code> is <code>null</code>.
-     */
+    //-Override-
     public Object evaluate(String expression, Object item, QName returnType)
             throws XPathExpressionException {
-        if ( expression == null ) {
-            String fmsg = XSLMessages.createXPATHMessage(
-                    XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
-                    new Object[] {"XPath expression"} );
-            throw new NullPointerException ( fmsg );
-        }
-        if ( returnType == null ) {
-            String fmsg = XSLMessages.createXPATHMessage(
-                    XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
-                    new Object[] {"returnType"} );
-            throw new NullPointerException ( fmsg );
-        }
-        // Checking if requested returnType is supported. returnType need to
-        // be defined in XPathConstants
-        if ( !isSupported ( returnType ) ) {
-            String fmsg = XSLMessages.createXPATHMessage(
-                    XPATHErrorResources.ER_UNSUPPORTED_RETURN_TYPE,
-                    new Object[] { returnType.toString() } );
-            throw new IllegalArgumentException ( fmsg );
-        }
+        //this check is necessary before calling eval to maintain binary compatibility
+        requireNonNull(expression, "XPath expression");
+        isSupported(returnType);
 
         try {
 
-            XObject resultObject = eval( expression, item );
-            return getResultAsType( resultObject, returnType );
-        } catch ( java.lang.NullPointerException npe ) {
+            XObject resultObject = eval(expression, item);
+            return getResultAsType(resultObject, returnType);
+        } catch (java.lang.NullPointerException npe) {
             // If VariableResolver returns null Or if we get
             // NullPointerException at this stage for some other reason
             // then we have to reurn XPathException
-            throw new XPathExpressionException ( npe );
-        } catch ( javax.xml.transform.TransformerException te ) {
+            throw new XPathExpressionException (npe);
+        } catch (TransformerException te) {
             Throwable nestedException = te.getException();
-            if ( nestedException instanceof javax.xml.xpath.XPathFunctionException ) {
+            if (nestedException instanceof javax.xml.xpath.XPathFunctionException) {
                 throw (javax.xml.xpath.XPathFunctionException)nestedException;
             } else {
                 // For any other exceptions we need to throw
-                // XPathExpressionException ( as per spec )
-                throw new XPathExpressionException ( te );
+                // XPathExpressionException (as per spec)
+                throw new XPathExpressionException (te);
             }
         }
 
     }
 
-    private boolean isSupported( QName returnType ) {
-        if ( ( returnType.equals( XPathConstants.STRING ) ) ||
-             ( returnType.equals( XPathConstants.NUMBER ) ) ||
-             ( returnType.equals( XPathConstants.BOOLEAN ) ) ||
-             ( returnType.equals( XPathConstants.NODE ) ) ||
-             ( returnType.equals( XPathConstants.NODESET ) )  ) {
-
-            return true;
-        }
-        return false;
-     }
-
-    private Object getResultAsType( XObject resultObject, QName returnType )
-        throws javax.xml.transform.TransformerException {
-        // XPathConstants.STRING
-        if ( returnType.equals( XPathConstants.STRING ) ) {
-            return resultObject.str();
-        }
-        // XPathConstants.NUMBER
-        if ( returnType.equals( XPathConstants.NUMBER ) ) {
-            return new Double ( resultObject.num());
-        }
-        // XPathConstants.BOOLEAN
-        if ( returnType.equals( XPathConstants.BOOLEAN ) ) {
-            return new Boolean( resultObject.bool());
-        }
-        // XPathConstants.NODESET ---ORdered, UNOrdered???
-        if ( returnType.equals( XPathConstants.NODESET ) ) {
-            return resultObject.nodelist();
-        }
-        // XPathConstants.NODE
-        if ( returnType.equals( XPathConstants.NODE ) ) {
-            NodeIterator ni = resultObject.nodeset();
-            //Return the first node, or null
-            return ni.nextNode();
-        }
-        String fmsg = XSLMessages.createXPATHMessage(
-                XPATHErrorResources.ER_UNSUPPORTED_RETURN_TYPE,
-                new Object[] { returnType.toString()});
-        throw new IllegalArgumentException( fmsg );
+    //-Override-
+    public String evaluate(String expression, Object item)
+        throws XPathExpressionException {
+        return (String)this.evaluate(expression, item, XPathConstants.STRING);
     }
 
-
-
-    /**
-     * <p>Evaluate an XPath expression in the specified context and return the result as a <code>String</code>.</p>
-     *
-     * <p>This method calls {@link #evaluate(String expression, Object item, QName returnType)} with a <code>returnType</code> of
-     * {@link XPathConstants#STRING}.</p>
-     *
-     * <p>See "Evaluation of XPath Expressions" of JAXP 1.3 spec
-     * for context item evaluation,
-     * variable, function and QName resolution and return type conversion.</p>
-     *
-     * <p>If a <code>null</code> value is provided for
-     * <code>item</code>, an empty document will be used for the
-     * context.
-     * If <code>expression</code> is <code>null</code>, then a <code>NullPointerException</code> is thrown.</p>
-     *
-     * @param expression The XPath expression.
-     * @param item The starting context (node or node list, for example).
-     *
-     * @return The <code>String</code> that is the result of evaluating the expression and
-     *   converting the result to a <code>String</code>.
-     *
-     * @throws XPathExpressionException If <code>expression</code> cannot be evaluated.
-     * @throws NullPointerException If <code>expression</code> is <code>null</code>.
-     */
-    public String evaluate(String expression, Object item)
-        throws XPathExpressionException {
-        return (String)this.evaluate( expression, item, XPathConstants.STRING );
-    }
-
-    /**
-     * <p>Compile an XPath expression for later evaluation.</p>
-     *
-     * <p>If <code>expression</code> contains any {@link XPathFunction}s,
-     * they must be available via the {@link XPathFunctionResolver}.
-     * An {@link XPathExpressionException} will be thrown if the <code>XPathFunction</code>
-     * cannot be resovled with the <code>XPathFunctionResolver</code>.</p>
-     *
-     * <p>If <code>expression</code> is <code>null</code>, a <code>NullPointerException</code> is thrown.</p>
-     *
-     * @param expression The XPath expression.
-     *
-     * @return Compiled XPath expression.
-
-     * @throws XPathExpressionException If <code>expression</code> cannot be compiled.
-     * @throws NullPointerException If <code>expression</code> is <code>null</code>.
-     */
+    //-Override-
     public XPathExpression compile(String expression)
         throws XPathExpressionException {
-        if ( expression == null ) {
-            String fmsg = XSLMessages.createXPATHMessage(
-                    XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
-                    new Object[] {"XPath expression"} );
-            throw new NullPointerException ( fmsg );
-        }
+        requireNonNull(expression, "XPath expression");
         try {
             com.sun.org.apache.xpath.internal.XPath xpath = new XPath (expression, null,
-                    prefixResolver, com.sun.org.apache.xpath.internal.XPath.SELECT );
+                    prefixResolver, com.sun.org.apache.xpath.internal.XPath.SELECT);
             // Can have errorListener
             XPathExpressionImpl ximpl = new XPathExpressionImpl (xpath,
                     prefixResolver, functionResolver, variableResolver,
-                    featureSecureProcessing, useServiceMechanism, featureManager );
+                    featureSecureProcessing, useServiceMechanism, featureManager);
             return ximpl;
-        } catch ( javax.xml.transform.TransformerException te ) {
-            throw new XPathExpressionException ( te ) ;
+        } catch (TransformerException te) {
+            throw new XPathExpressionException (te) ;
         }
     }
 
-
-    /**
-     * <p>Evaluate an XPath expression in the context of the specified <code>InputSource</code>
-     * and return the result as the specified type.</p>
-     *
-     * <p>This method builds a data model for the {@link InputSource} and calls
-     * {@link #evaluate(String expression, Object item, QName returnType)} on the resulting document object.</p>
-     *
-     * <p>See "Evaluation of XPath Expressions" section of JAXP 1.3 spec
-     * for context item evaluation,
-     * variable, function and QName resolution and return type conversion.</p>
-     *
-     * <p>If <code>returnType</code> is not one of the types defined in {@link XPathConstants},
-     * then an <code>IllegalArgumentException</code> is thrown.</p>
-     *
-     * <p>If <code>expression</code>, <code>source</code> or <code>returnType</code> is <code>null</code>,
-     * then a <code>NullPointerException</code> is thrown.</p>
-     *
-     * @param expression The XPath expression.
-     * @param source The input source of the document to evaluate over.
-     * @param returnType The desired return type.
-     *
-     * @return The <code>Object</code> that encapsulates the result of evaluating the expression.
-     *
-     * @throws XPathExpressionException If expression cannot be evaluated.
-     * @throws IllegalArgumentException If <code>returnType</code> is not one of the types defined in {@link XPathConstants}.
-     * @throws NullPointerException If <code>expression</code>, <code>source</code> or <code>returnType</code>
-     *   is <code>null</code>.
-     */
+    //-Override-
     public Object evaluate(String expression, InputSource source,
             QName returnType) throws XPathExpressionException {
-        // Checking validity of different parameters
-        if( source== null ) {
-            String fmsg = XSLMessages.createXPATHMessage(
-                    XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
-                    new Object[] {"source"} );
-            throw new NullPointerException ( fmsg );
-        }
-        if ( expression == null ) {
-            String fmsg = XSLMessages.createXPATHMessage(
-                    XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
-                    new Object[] {"XPath expression"} );
-            throw new NullPointerException ( fmsg );
-        }
-        if ( returnType == null ) {
-            String fmsg = XSLMessages.createXPATHMessage(
-                    XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
-                    new Object[] {"returnType"} );
-            throw new NullPointerException ( fmsg );
-        }
-
-        //Checking if requested returnType is supported.
-        //returnType need to be defined in XPathConstants
-        if ( !isSupported ( returnType ) ) {
-            String fmsg = XSLMessages.createXPATHMessage(
-                    XPATHErrorResources.ER_UNSUPPORTED_RETURN_TYPE,
-                    new Object[] { returnType.toString() } );
-            throw new IllegalArgumentException ( fmsg );
-        }
+        isSupported(returnType);
 
         try {
-
-            Document document = getParser().parse( source );
-
-            XObject resultObject = eval( expression, document );
-            return getResultAsType( resultObject, returnType );
-        } catch ( SAXException e ) {
-            throw new XPathExpressionException ( e );
-        } catch( IOException e ) {
-            throw new XPathExpressionException ( e );
-        } catch ( javax.xml.transform.TransformerException te ) {
+            Document document = getDocument(source);
+            XObject resultObject = eval(expression, document);
+            return getResultAsType(resultObject, returnType);
+        } catch (TransformerException te) {
             Throwable nestedException = te.getException();
-            if ( nestedException instanceof javax.xml.xpath.XPathFunctionException ) {
+            if (nestedException instanceof javax.xml.xpath.XPathFunctionException) {
                 throw (javax.xml.xpath.XPathFunctionException)nestedException;
             } else {
-                throw new XPathExpressionException ( te );
+                throw new XPathExpressionException (te);
             }
         }
-
     }
 
-
-
-
-    /**
-     * <p>Evaluate an XPath expression in the context of the specified <code>InputSource</code>
-     * and return the result as a <code>String</code>.</p>
-     *
-     * <p>This method calls {@link #evaluate(String expression, InputSource source, QName returnType)} with a
-     * <code>returnType</code> of {@link XPathConstants#STRING}.</p>
-     *
-     * <p>See "Evaluation of XPath Expressions" section of JAXP 1.3 spec
-     * for context item evaluation,
-     * variable, function and QName resolution and return type conversion.</p>
-     *
-     * <p>If <code>expression</code> or <code>source</code> is <code>null</code>,
-     * then a <code>NullPointerException</code> is thrown.</p>
-     *
-     * @param expression The XPath expression.
-     * @param source The <code>InputSource</code> of the document to evaluate over.
-     *
-     * @return The <code>String</code> that is the result of evaluating the expression and
-     *   converting the result to a <code>String</code>.
-     *
-     * @throws XPathExpressionException If expression cannot be evaluated.
-     * @throws NullPointerException If <code>expression</code> or <code>source</code> is <code>null</code>.
-     */
+    //-Override-
     public String evaluate(String expression, InputSource source)
         throws XPathExpressionException {
-        return (String)this.evaluate( expression, source, XPathConstants.STRING );
+        return (String)this.evaluate(expression, source, XPathConstants.STRING);
     }
 
-    /**
-     * <p>Reset this <code>XPath</code> to its original configuration.</p>
-     *
-     * <p><code>XPath</code> is reset to the same state as when it was created with
-     * {@link XPathFactory#newXPath()}.
-     * <code>reset()</code> is designed to allow the reuse of existing <code>XPath</code>s
-     * thus saving resources associated with the creation of new <code>XPath</code>s.</p>
-     *
-     * <p>The reset <code>XPath</code> is not guaranteed to have the same
-     * {@link XPathFunctionResolver}, {@link XPathVariableResolver}
-     * or {@link NamespaceContext} <code>Object</code>s, e.g. {@link Object#equals(Object obj)}.
-     * It is guaranteed to have a functionally equal <code>XPathFunctionResolver</code>,
-     * <code>XPathVariableResolver</code>
-     * and <code>NamespaceContext</code>.</p>
-     */
+    //-Override-
     public void reset() {
         this.variableResolver = this.origVariableResolver;
         this.functionResolver = this.origFunctionResolver;
         this.namespaceContext = null;
     }
 
+    //-Override-
+    public <T> T evaluateExpression(String expression, Object item, Class<T> type)
+            throws XPathExpressionException {
+        isSupportedClassType(type);
+        try {
+            XObject resultObject = eval(expression, item);
+            if (type.isAssignableFrom(XPathEvaluationResult.class)) {
+                return getXPathResult(resultObject, type);
+            } else {
+                return XPathResultImpl.getValue(resultObject, type);
+            }
+        } catch (TransformerException te) {
+            throw new XPathExpressionException (te);
+        }
+    }
+
+    //-Override-
+    public XPathEvaluationResult<?> evaluateExpression(String expression, Object item)
+            throws XPathExpressionException {
+        return evaluateExpression(expression, item, XPathEvaluationResult.class);
+    }
+
+    //-Override-
+    public <T> T evaluateExpression(String expression, InputSource source, Class<T> type)
+            throws XPathExpressionException {
+        Document document = getDocument(source);
+        return evaluateExpression(expression, document, type);
+    }
+
+    //-Override-
+    public XPathEvaluationResult<?> evaluateExpression(String expression, InputSource source)
+            throws XPathExpressionException {
+        return evaluateExpression(expression, source, XPathEvaluationResult.class);
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/jaxp/XPathImplUtil.java	Tue Jan 27 22:01:46 2015 -0800
@@ -0,0 +1,262 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.org.apache.xpath.internal.jaxp;
+
+import com.sun.org.apache.xalan.internal.res.XSLMessages;
+import com.sun.org.apache.xalan.internal.utils.FactoryImpl;
+import com.sun.org.apache.xalan.internal.utils.FeatureManager;
+import com.sun.org.apache.xml.internal.dtm.DTM;
+import com.sun.org.apache.xpath.internal.objects.XObject;
+import com.sun.org.apache.xpath.internal.res.XPATHErrorResources;
+import java.io.IOException;
+import javax.xml.namespace.QName;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathEvaluationResult;
+import javax.xml.xpath.XPathExpressionException;
+import javax.xml.xpath.XPathFunctionResolver;
+import javax.xml.xpath.XPathNodes;
+import javax.xml.xpath.XPathVariableResolver;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.traversal.NodeIterator;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+/**
+ * This class contains several utility methods used by XPathImpl and
+ * XPathExpressionImpl
+ */
+class XPathImplUtil {
+    XPathFunctionResolver functionResolver;
+    XPathVariableResolver variableResolver;
+    JAXPPrefixResolver prefixResolver;
+    boolean useServiceMechanism = true;
+    // By default Extension Functions are allowed in XPath Expressions. If
+    // Secure Processing Feature is set on XPathFactory then the invocation of
+    // extensions function need to throw XPathFunctionException
+    boolean featureSecureProcessing = false;
+    FeatureManager featureManager;
+
+    /**
+     * Evaluate an XPath context using the internal XPath engine
+     * @param contextItem The XPath context
+     * @param xpath The internal XPath engine
+     * @return an XObject
+     * @throws javax.xml.transform.TransformerException If the expression cannot be evaluated.
+     */
+    XObject eval(Object contextItem, com.sun.org.apache.xpath.internal.XPath xpath)
+            throws javax.xml.transform.TransformerException {
+        com.sun.org.apache.xpath.internal.XPathContext xpathSupport;
+        if (functionResolver != null) {
+            JAXPExtensionsProvider jep = new JAXPExtensionsProvider(
+                    functionResolver, featureSecureProcessing, featureManager);
+            xpathSupport = new com.sun.org.apache.xpath.internal.XPathContext(jep);
+        } else {
+            xpathSupport = new com.sun.org.apache.xpath.internal.XPathContext();
+        }
+
+        xpathSupport.setVarStack(new JAXPVariableStack(variableResolver));
+        XObject xobj;
+
+        Node contextNode = (Node)contextItem;
+        // We always need to have a ContextNode with Xalan XPath implementation
+        // To allow simple expression evaluation like 1+1 we are setting
+        // dummy Document as Context Node
+        if (contextNode == null) {
+            xobj = xpath.execute(xpathSupport, DTM.NULL, prefixResolver);
+        } else {
+            xobj = xpath.execute(xpathSupport, contextNode, prefixResolver);
+        }
+
+        return xobj;
+    }
+
+    /**
+     * Parse the input source and return a Document.
+     * @param source The {@code InputSource} of the document
+     * @return a DOM Document
+     * @throws XPathExpressionException if there is an error parsing the source.
+     */
+    Document getDocument(InputSource source)
+        throws XPathExpressionException {
+        requireNonNull(source, "Source");
+        try {
+            // we'd really like to cache those DocumentBuilders, but we can't because:
+            // 1. thread safety. parsers are not thread-safe, so at least
+            //    we need one instance per a thread.
+            // 2. parsers are non-reentrant, so now we are looking at having a
+            // pool of parsers.
+            // 3. then the class loading issue. The look-up procedure of
+            //    DocumentBuilderFactory.newInstance() depends on context class loader
+            //    and system properties, which may change during the execution of JVM.
+            //
+            // so we really have to create a fresh DocumentBuilder every time we need one
+            // - KK
+            DocumentBuilderFactory dbf = FactoryImpl.getDOMFactory(useServiceMechanism);
+            dbf.setNamespaceAware(true);
+            dbf.setValidating(false);
+            return dbf.newDocumentBuilder().parse(source);
+        } catch (ParserConfigurationException | SAXException | IOException e) {
+            throw new XPathExpressionException (e);
+        }
+    }
+
+    /**
+     * Get result depending on the QName type defined in XPathConstants
+     * @param resultObject the result of an evaluation
+     * @param returnType the return type
+     * @return result per the return type
+     * @throws TransformerException if the result can not be converted to
+     * the specified return type.
+     */
+    Object getResultAsType(XObject resultObject, QName returnType)
+        throws TransformerException {
+        // XPathConstants.STRING
+        if (returnType.equals(XPathConstants.STRING)) {
+            return resultObject.str();
+        }
+        // XPathConstants.NUMBER
+        if (returnType.equals(XPathConstants.NUMBER)) {
+            return resultObject.num();
+        }
+        // XPathConstants.BOOLEAN
+        if (returnType.equals(XPathConstants.BOOLEAN)) {
+            return resultObject.bool();
+        }
+        // XPathConstants.NODESET ---ORdered, UNOrdered???
+        if (returnType.equals(XPathConstants.NODESET)) {
+            return resultObject.nodelist();
+        }
+        // XPathConstants.NODE
+        if (returnType.equals(XPathConstants.NODE)) {
+            NodeIterator ni = resultObject.nodeset();
+            //Return the first node, or null
+            return ni.nextNode();
+        }
+        // If isSupported check is already done then the execution path
+        // shouldn't come here. Being defensive
+        String fmsg = XSLMessages.createXPATHMessage(
+                XPATHErrorResources.ER_UNSUPPORTED_RETURN_TYPE,
+                new Object[] { returnType.toString()});
+        throw new IllegalArgumentException (fmsg);
+    }
+
+    /**
+     * Construct an XPathExpressionResult object based on the result of the
+     * evaluation and cast to the specified class type.
+     * @param <T> The class type
+     * @param resultObject the result of an evaluation
+     * @param type The class type expected to be returned by the XPath expression.
+     * @return an instance of the specified type or null if the XObject returned
+     * an UNKNOWN object type.
+     * @throws TransformerException if there is an error converting the result
+     * to the specified type. It's unlikely to happen. This is mostly needed
+     * by the internal XPath engine.
+     */
+    <T> T getXPathResult(XObject resultObject, Class<T> type)
+            throws TransformerException {
+        int resultType = resultObject.getType();
+
+        switch (resultType) {
+            case XObject.CLASS_BOOLEAN :
+                return type.cast(new XPathResultImpl<>(resultObject, Boolean.class));
+            case XObject.CLASS_NUMBER :
+                return type.cast(new XPathResultImpl<>(resultObject, Double.class));
+            case XObject.CLASS_STRING :
+                return type.cast(new XPathResultImpl<>(resultObject, String.class));
+            case XObject.CLASS_NODESET :
+                return type.cast(new XPathResultImpl<>(resultObject, XPathNodes.class));
+            case XObject.CLASS_RTREEFRAG :  //NODE
+                return type.cast(new XPathResultImpl<>(resultObject, Node.class));
+        }
+
+        return null;
+    }
+
+    /**
+     * Check whether or not the specified type is supported
+     * @param <T> The class type
+     * @param type The type to be checked
+     * @throws IllegalArgumentException if the type is not supported
+     */
+    <T> void isSupportedClassType(Class<T> type) {
+        requireNonNull(type, "The class type");
+        if (type.isAssignableFrom(Boolean.class) ||
+                type.isAssignableFrom(Double.class) ||
+                type.isAssignableFrom(Integer.class) ||
+                type.isAssignableFrom(Long.class) ||
+                type.isAssignableFrom(String.class) ||
+                type.isAssignableFrom(XPathNodes.class) ||
+                type.isAssignableFrom(Node.class) ||
+                type.isAssignableFrom(XPathEvaluationResult.class)) {
+            return;
+        }
+        String fmsg = XSLMessages.createXPATHMessage(
+                XPATHErrorResources.ER_UNSUPPORTED_RETURN_TYPE,
+                new Object[] { type.toString() });
+        throw new IllegalArgumentException (fmsg);
+    }
+
+    /**
+     * Check if the requested returnType is supported.
+     * @param returnType the return type
+     * @throws IllegalArgumentException if the return type is not supported
+     */
+    void isSupported(QName returnType) {
+        requireNonNull(returnType, "returnType");
+        if (returnType.equals(XPathConstants.STRING) ||
+                returnType.equals(XPathConstants.NUMBER) ||
+                returnType.equals(XPathConstants.BOOLEAN) ||
+                returnType.equals(XPathConstants.NODE) ||
+                returnType.equals(XPathConstants.NODESET)) {
+            return;
+        }
+        String fmsg = XSLMessages.createXPATHMessage(
+                XPATHErrorResources.ER_UNSUPPORTED_RETURN_TYPE,
+                new Object[] { returnType.toString() });
+        throw new IllegalArgumentException (fmsg);
+     }
+
+    /**
+     * Checks that the specified parameter is not {@code null}.
+     *
+     * @param <T> the type of the reference
+     * @param param the parameter to check for nullity
+     * @param paramName the parameter name
+     * @throws NullPointerException if {@code param} is {@code null}
+     */
+    <T> void requireNonNull(T param, String paramName) {
+        if (param == null) {
+            String fmsg = XSLMessages.createXPATHMessage(
+                    XPATHErrorResources.ER_ARG_CANNOT_BE_NULL,
+                    new Object[] {paramName});
+            throw new NullPointerException (fmsg);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/jaxp/XPathNodesImpl.java	Tue Jan 27 22:01:46 2015 -0800
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.org.apache.xpath.internal.jaxp;
+
+import java.util.Iterator;
+import javax.xml.xpath.XPathException;
+import javax.xml.xpath.XPathNodes;
+import javax.xml.xpath.XPathEvaluationResult.XPathResultType;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * This class implements XPathNodes that represents a set of nodes selected by
+ * evaluating an expression.
+ */
+public class XPathNodesImpl implements XPathNodes {
+    Class<Node> elementType;
+    NodeList nodeList = null;
+
+    public XPathNodesImpl(NodeList nodeList, Class<Node> elementType) {
+        this.nodeList = nodeList;
+        this.elementType = elementType;
+    }
+
+    @Override
+    public Iterator<Node> iterator() {
+        return new NodeSetIterator<>(elementType);
+    }
+
+    class NodeSetIterator<E> implements Iterator<E> {
+        int currentIndex;
+        Class<E> elementType;
+        NodeSetIterator(Class<E> elementType) {
+            this.elementType = elementType;
+        }
+        public boolean hasNext() {
+            if (nodeList != null) {
+                return currentIndex < nodeList.getLength();
+            }
+
+            return false;
+        }
+
+        public E next() {
+            if (nodeList != null && nodeList.getLength() > 0) {
+                return elementType.cast(nodeList.item(currentIndex++));
+            }
+            return null;
+        }
+    }
+
+    @Override
+    public int size() {
+        if (nodeList != null) {
+            return nodeList.getLength();
+        }
+        return 0;
+    }
+
+    @Override
+    public Node get(int index) throws XPathException {
+        if (index <0 || index >= size()) {
+            throw new IndexOutOfBoundsException("Index " + index + " is out of bounds");
+        }
+        if (nodeList != null) {
+            return nodeList.item(index);
+        }
+        return null;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/jaxp/XPathResultImpl.java	Tue Jan 27 22:01:46 2015 -0800
@@ -0,0 +1,201 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.org.apache.xpath.internal.jaxp;
+
+import com.sun.org.apache.xpath.internal.objects.XObject;
+import java.util.Objects;
+import javax.xml.transform.TransformerException;
+import javax.xml.xpath.XPathNodes;
+import javax.xml.xpath.XPathEvaluationResult;
+import javax.xml.xpath.XPathEvaluationResult.XPathResultType;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.traversal.NodeIterator;
+
+
+/**
+ * This is the implementation of XPathEvaluationResult that represents the
+ * result of the evaluation of an XPath expression within the context of a
+ * particular node.
+ */
+class XPathResultImpl<T> implements XPathEvaluationResult<T> {
+
+    XObject resultObject;
+    int resultType;
+    Class<T> type;
+    XPathResultType mapToType;
+    NodeList nodeList = null;
+    int currentIndex;
+    Node currentNode;
+
+    boolean boolValue = false;
+    Node node = null;
+    double numValue;
+    String strValue;
+
+    /**
+     * Construct an XPathEvaluationResult object.
+     *
+     * @param resultObject internal XPath result object
+     * @param type class type
+     * @throws TransformerException if there is an error reading the XPath
+     * result.
+     */
+    public XPathResultImpl(XObject resultObject, Class<T> type)
+            throws TransformerException {
+        this.resultObject = resultObject;
+        resultType = resultObject.getType();
+        this.type = type;
+        getResult(resultObject);
+    }
+
+    /**
+     * Return the result type as an enum specified by {@code XPathResultType}
+     * @return the result type
+     */
+    @Override
+    public XPathResultType type() {
+        return mapToType;
+    }
+
+    /**
+     * Returns the value of the result as the type &lt;T&gt; specified for the class.
+     *
+     * @return The value of the result.
+     */
+    @Override
+    public T value() {
+        Objects.requireNonNull(type);
+        try {
+            return getValue(resultObject, type);
+        } catch (TransformerException ex) {
+            throw new RuntimeException(ex);
+        }
+    }
+
+    /**
+     * Read the XObject and set values in accordance with the result type
+     * @param resultObject  internal XPath result object
+     * @throws TransformerException  if there is an error reading the XPath
+     * result.
+     */
+    private void getResult(XObject resultObject) throws TransformerException {
+        switch (resultType) {
+            case XObject.CLASS_BOOLEAN:
+                boolValue = resultObject.bool();
+                mapToType = XPathResultType.BOOLEAN;
+                break;
+            case XObject.CLASS_NUMBER:
+                numValue = resultObject.num();
+                mapToType = XPathResultType.NUMBER;
+                break;
+            case XObject.CLASS_STRING:
+                strValue = resultObject.str();
+                mapToType = XPathResultType.STRING;
+                break;
+            case XObject.CLASS_NODESET:
+                mapToType = XPathResultType.NODESET;
+                nodeList = resultObject.nodelist();
+                break;
+            case XObject.CLASS_RTREEFRAG:  //NODE
+                mapToType = XPathResultType.NODE;
+                NodeIterator ni = resultObject.nodeset();
+                //Return the first node, or null
+                node = ni.nextNode();
+                break;
+        }
+    }
+
+    /**
+     * Read the internal result object and return the value in accordance with
+     * the type specified.
+     *
+     * @param <T> The expected class type.
+     * @param resultObject internal XPath result object
+     * @param type the class type
+     * @return The value of the result, null in case of unexpected type.
+     * @throws TransformerException  if there is an error reading the XPath
+     * result.
+     */
+    static <T> T getValue(XObject resultObject, Class<T> type) throws TransformerException {
+        Objects.requireNonNull(type);
+        if (type.isAssignableFrom(XPathEvaluationResult.class)) {
+            return type.cast(new XPathResultImpl<T>(resultObject, type));
+        }
+        int resultType = classToInternalType(type);
+        switch (resultType) {
+            case XObject.CLASS_BOOLEAN:
+                return type.cast(resultObject.bool());
+            case XObject.CLASS_NUMBER:
+                if (Double.class.isAssignableFrom(type)) {
+                    return type.cast(resultObject.num());
+                } else if (Integer.class.isAssignableFrom(type)) {
+                    return type.cast((int)resultObject.num());
+                } else if (Long.class.isAssignableFrom(type)) {
+                    return type.cast((long)resultObject.num());
+                }
+                /*
+                  This is to suppress warnings. By the current specification,
+                among numeric types, only Double, Integer and Long are supported.
+                */
+                break;
+            case XObject.CLASS_STRING:
+                return type.cast(resultObject.str());
+            case XObject.CLASS_NODESET:
+                XPathNodes nodeSet = new XPathNodesImpl(resultObject.nodelist(),
+                        Node.class);
+                return type.cast(nodeSet);
+            case XObject.CLASS_RTREEFRAG:  //NODE
+                NodeIterator ni = resultObject.nodeset();
+                //Return the first node, or null
+                return type.cast(ni.nextNode());
+        }
+
+        return null;
+    }
+
+    /**
+     * Map the specified class type to the internal result type
+     *
+     * @param <T> The expected class type.
+     * @param type the class type
+     * @return the internal XObject type.
+     */
+    static <T> int classToInternalType(Class<T> type) {
+        if (type.isAssignableFrom(Boolean.class)) {
+            return XObject.CLASS_BOOLEAN;
+        } else if (Number.class.isAssignableFrom(type)) {
+            return XObject.CLASS_NUMBER;
+        } else if (type.isAssignableFrom(String.class)) {
+            return XObject.CLASS_STRING;
+        } else if (type.isAssignableFrom(XPathNodes.class)) {
+            return XObject.CLASS_NODESET;
+        } else if (type.isAssignableFrom(Node.class)) {
+            return XObject.CLASS_RTREEFRAG;
+        }
+        return XObject.CLASS_NULL;
+    }
+}
--- a/jaxp/src/java.xml/share/classes/javax/xml/xpath/XPath.java	Mon Jan 26 12:17:59 2015 +0300
+++ b/jaxp/src/java.xml/share/classes/javax/xml/xpath/XPath.java	Tue Jan 27 22:01:46 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,12 +25,12 @@
 
 package javax.xml.xpath;
 
-import org.xml.sax.InputSource;
+import javax.xml.namespace.NamespaceContext;
 import javax.xml.namespace.QName;
-import javax.xml.namespace.NamespaceContext;
+import org.xml.sax.InputSource;
 
 /**
- * <p><code>XPath</code> provides access to the XPath evaluation environment and expressions.</p>
+ * {@code XPath} provides access to the XPath evaluation environment and expressions.
  *
  * <a name="XPath-evaluation"/>
  * <table border="1" cellpadding="2">
@@ -39,7 +39,6 @@
  *       <th colspan="2">Evaluation of XPath Expressions.</th>
  *     </tr>
  *   </thead>
- *   <tbody>
  *     <tr>
  *       <td>context</td>
  *       <td>
@@ -55,8 +54,8 @@
  *        If the expression contains a variable reference, its value will be found through the {@link XPathVariableResolver}
  *        set with {@link #setXPathVariableResolver(XPathVariableResolver resolver)}.
  *        An {@link XPathExpressionException} is raised if the variable resolver is undefined or
- *        the resolver returns <code>null</code> for the variable.
- *        The value of a variable must be immutable through the course of any single evaluation.</p>
+ *        the resolver returns {@code null} for the variable.
+ *        The value of a variable must be immutable through the course of any single evaluation.
  *      </td>
  *    </tr>
  *    <tr>
@@ -65,7 +64,7 @@
  *        If the expression contains a function reference, the function will be found through the {@link XPathFunctionResolver}
  *        set with {@link #setXPathFunctionResolver(XPathFunctionResolver resolver)}.
  *        An {@link XPathExpressionException} is raised if the function resolver is undefined or
- *        the function resolver returns <code>null</code> for the function.</p>
+ *        the function resolver returns {@code null} for the function.
  *      </td>
  *    </tr>
  *    <tr>
@@ -80,7 +79,7 @@
  *      <td>
  *        This result of evaluating an expression is converted to an instance of the desired return type.
  *        Valid return types are defined in {@link XPathConstants}.
- *        Conversion to the return type follows XPath conversion rules.</p>
+ *        Conversion to the return type follows XPath conversion rules.
  *      </td>
  *    </tr>
  * </table>
@@ -88,9 +87,9 @@
  * <p>An XPath object is not thread-safe and not reentrant.
  * In other words, it is the application's responsibility to make
  * sure that one {@link XPath} object is not used from
- * more than one thread at any given time, and while the <code>evaluate</code>
+ * more than one thread at any given time, and while the {@code evaluate}
  * method is invoked, applications may not recursively call
- * the <code>evaluate</code> method.
+ * the {@code evaluate} method.
  * <p>
  *
  * @author  <a href="Norman.Walsh@Sun.com">Norman Walsh</a>
@@ -100,191 +99,189 @@
  */
 public interface XPath {
 
-        /**
-         * <p>Reset this <code>XPath</code> to its original configuration.</p>
-         *
-         * <p><code>XPath</code> is reset to the same state as when it was created with
-         * {@link XPathFactory#newXPath()}.
-         * <code>reset()</code> is designed to allow the reuse of existing <code>XPath</code>s
-         * thus saving resources associated with the creation of new <code>XPath</code>s.</p>
-         *
-         * <p>The reset <code>XPath</code> is not guaranteed to have the same {@link XPathFunctionResolver}, {@link XPathVariableResolver}
-         * or {@link NamespaceContext} <code>Object</code>s, e.g. {@link Object#equals(Object obj)}.
-         * It is guaranteed to have a functionally equal <code>XPathFunctionResolver</code>, <code>XPathVariableResolver</code>
-         * and <code>NamespaceContext</code>.</p>
-         */
-        public void reset();
 
     /**
-     * <p>Establish a variable resolver.</p>
+     * Reset this {@code XPath} to its original configuration.
+     *
+     * <p>{@code XPath} is reset to the same state as when it was created with
+     * {@link XPathFactory#newXPath()}.
+     * {@code reset()} is designed to allow the reuse of existing {@code XPath}s
+     * thus saving resources associated with the creation of new {@code XPath}s.
      *
-     * <p>A <code>NullPointerException</code> is thrown if <code>resolver</code> is <code>null</code>.</p>
+     * <p>The reset {@code XPath} is not guaranteed to have the same
+     * {@link XPathFunctionResolver}, {@link XPathVariableResolver}
+     * or {@link NamespaceContext} {@code Object}s, e.g. {@link Object#equals(Object obj)}.
+     * It is guaranteed to have a functionally equal {@code XPathFunctionResolver},
+     * {@code XPathVariableResolver} and {@code NamespaceContext}.
+     */
+    public void reset();
+
+    /**
+     * Establish a variable resolver.
+     *
+     * <p>A {@code NullPointerException} is thrown if {@code resolver} is {@code null}.
      *
      * @param resolver Variable resolver.
      *
-     *  @throws NullPointerException If <code>resolver</code> is <code>null</code>.
+     * @throws NullPointerException If {@code resolver} is {@code null}.
      */
     public void setXPathVariableResolver(XPathVariableResolver resolver);
 
     /**
-       * <p>Return the current variable resolver.</p>
+       * Return the current variable resolver.
        *
-       * <p><code>null</code> is returned in no variable resolver is in effect.</p>
+       * <p>{@code null} is returned in no variable resolver is in effect.
        *
        * @return Current variable resolver.
        */
     public XPathVariableResolver getXPathVariableResolver();
 
     /**
-       * <p>Establish a function resolver.</p>
+       * Establish a function resolver.
        *
-       * <p>A <code>NullPointerException</code> is thrown if <code>resolver</code> is <code>null</code>.</p>
+       * <p>A {@code NullPointerException} is thrown if {@code resolver} is {@code null}.
        *
        * @param resolver XPath function resolver.
        *
-       * @throws NullPointerException If <code>resolver</code> is <code>null</code>.
+       * @throws NullPointerException If {@code resolver} is {@code null}.
        */
     public void setXPathFunctionResolver(XPathFunctionResolver resolver);
 
     /**
-       * <p>Return the current function resolver.</p>
-       *
-       * <p><code>null</code> is returned in no function resolver is in effect.</p>
+       * Return the current function resolver.
+       * <p>
+       * {@code null} is returned in no function resolver is in effect.
        *
        * @return Current function resolver.
        */
     public XPathFunctionResolver getXPathFunctionResolver();
 
     /**
-       * <p>Establish a namespace context.</p>
+       * Establish a namespace context.
        *
-       * <p>A <code>NullPointerException</code> is thrown if <code>nsContext</code> is <code>null</code>.</p>
+       * <p>A {@code NullPointerException} is thrown if {@code nsContext} is {@code null}.
        *
        * @param nsContext Namespace context to use.
        *
-       * @throws NullPointerException If <code>nsContext</code> is <code>null</code>.
+       * @throws NullPointerException If {@code nsContext} is {@code null}.
        */
     public void setNamespaceContext(NamespaceContext nsContext);
 
     /**
-       * <p>Return the current namespace context.</p>
+       * Return the current namespace context.
        *
-       * <p><code>null</code> is returned in no namespace context is in effect.</p>
+       * <p>{@code null} is returned in no namespace context is in effect.
        *
        * @return Current Namespace context.
        */
     public NamespaceContext getNamespaceContext();
 
     /**
-       * <p>Compile an XPath expression for later evaluation.</p>
+       * Compile an XPath expression for later evaluation.
        *
-       * <p>If <code>expression</code> contains any {@link XPathFunction}s,
+       * <p>If {@code expression} contains any {@link XPathFunction}s,
        * they must be available via the {@link XPathFunctionResolver}.
        * An {@link XPathExpressionException} will be thrown if the
-       * <code>XPathFunction</code>
-       * cannot be resovled with the <code>XPathFunctionResolver</code>.</p>
+       * {@code XPathFunction}
+       * cannot be resovled with the {@code XPathFunctionResolver}.
        *
-       * <p>If <code>expression</code> contains any variables, the
+       * <p>If {@code expression} contains any variables, the
        * {@link XPathVariableResolver} in effect
-       * <strong>at compile time</strong> will be used to resolve them.</p>
-       *
-       * <p>If <code>expression</code> is <code>null</code>, a <code>NullPointerException</code> is thrown.</p>
+       * <strong>at compile time</strong> will be used to resolve them.
        *
        * @param expression The XPath expression.
        *
        * @return Compiled XPath expression.
 
-       * @throws XPathExpressionException If <code>expression</code> cannot be compiled.
-       * @throws NullPointerException If <code>expression</code> is <code>null</code>.
+       * @throws XPathExpressionException If {@code expression} cannot be compiled.
+       * @throws NullPointerException If {@code expression} is {@code null}.
        */
     public XPathExpression compile(String expression)
         throws XPathExpressionException;
 
     /**
-     * <p>Evaluate an <code>XPath</code> expression in the specified context and return the result as the specified type.</p>
+     * Evaluate an {@code XPath} expression in the specified context and
+     * return the result as the specified type.
      *
-     * <p>See <a href="#XPath-evaluation">Evaluation of XPath Expressions</a> for context item evaluation,
-     * variable, function and <code>QName</code> resolution and return type conversion.</p>
+     * <p>
+     * See <a href="#XPath-evaluation">Evaluation of XPath Expressions</a>
+     * for context item evaluation, variable, function and {@code QName} resolution
+     * and return type conversion.
+     * <p>
+     * The parameter {@code item} represents the context the XPath expression
+     * will be operated on. The type of the context is implementation-dependent.
+     * If the value is {@code null}, the operation must have no dependency on
+     * the context, otherwise an XPathExpressionException will be thrown.
      *
-     * <p>If <code>returnType</code> is not one of the types defined in {@link XPathConstants} (
+     * @implNote
+     * The type of the context is usually {@link org.w3c.dom.Node}.
+     *
+     * @param expression The XPath expression.
+     * @param item The context the XPath expression will be evaluated in.
+     * @param returnType The result type expected to be returned by the XPath expression.
+     *
+     * @return The result of evaluating an XPath expression as an {@code Object} of {@code returnType}.
+     *
+     * @throws XPathExpressionException If {@code expression} cannot be evaluated.
+     * @throws IllegalArgumentException If {@code returnType} is not one of the types defined in {@link XPathConstants} (
      * {@link XPathConstants#NUMBER NUMBER},
      * {@link XPathConstants#STRING STRING},
      * {@link XPathConstants#BOOLEAN BOOLEAN},
      * {@link XPathConstants#NODE NODE} or
-     * {@link XPathConstants#NODESET NODESET})
-     * then an <code>IllegalArgumentException</code> is thrown.</p>
-     *
-     * <p>If a <code>null</code> value is provided for
-     * <code>item</code>, an empty document will be used for the
-     * context.
-     * If <code>expression</code> or <code>returnType</code> is <code>null</code>, then a
-     * <code>NullPointerException</code> is thrown.</p>
-     *
-     * @param expression The XPath expression.
-     * @param item The starting context (a node, for example).
-     * @param returnType The desired return type.
-     *
-     * @return Result of evaluating an XPath expression as an <code>Object</code> of <code>returnType</code>.
-     *
-     * @throws XPathExpressionException If <code>expression</code> cannot be evaluated.
-     * @throws IllegalArgumentException If <code>returnType</code> is not one of the types defined in {@link XPathConstants}.
-     * @throws NullPointerException If <code>expression</code> or <code>returnType</code> is <code>null</code>.
+     * {@link XPathConstants#NODESET NODESET}).
+     * @throws NullPointerException If {@code expression or returnType} is {@code null}.
      */
     public Object evaluate(String expression, Object item, QName returnType)
         throws XPathExpressionException;
 
     /**
-     * <p>Evaluate an XPath expression in the specified context and return the result as a <code>String</code>.</p>
+     * Evaluate an XPath expression in the specified context and return the result as a {@code String}.
      *
-     * <p>This method calls {@link #evaluate(String expression, Object item, QName returnType)} with a <code>returnType</code> of
-     * {@link XPathConstants#STRING}.</p>
+     * <p>This method calls {@link #evaluate(String expression, Object item, QName returnType)} with a {@code returnType} of
+     * {@link XPathConstants#STRING}.
      *
      * <p>See <a href="#XPath-evaluation">Evaluation of XPath Expressions</a> for context item evaluation,
-     * variable, function and QName resolution and return type conversion.</p>
+     * variable, function and QName resolution and return type conversion.
      *
-     * <p>If a <code>null</code> value is provided for
-     * <code>item</code>, an empty document will be used for the
-     * context.
-     * If <code>expression</code> is <code>null</code>, then a <code>NullPointerException</code> is thrown.</p>
+     * <p>
+     * The parameter {@code item} represents the context the XPath expression
+     * will be operated on. The type of the context is implementation-dependent.
+     * If the value is {@code null}, the operation must have no dependency on
+     * the context, otherwise an XPathExpressionException will be thrown.
+     *
+     * @implNote
+     * The type of the context is usually {@link org.w3c.dom.Node}.
      *
      * @param expression The XPath expression.
-     * @param item The starting context (a node, for example).
+     * @param item The context the XPath expression will be evaluated in.
      *
-     * @return The <code>String</code> that is the result of evaluating the expression and
-     *   converting the result to a <code>String</code>.
+     * @return The result of evaluating an XPath expression as a {@code String}.
      *
-     * @throws XPathExpressionException If <code>expression</code> cannot be evaluated.
-     * @throws NullPointerException If <code>expression</code> is <code>null</code>.
+     * @throws XPathExpressionException If {@code expression} cannot be evaluated.
+     * @throws NullPointerException If {@code expression} is {@code null}.
      */
     public String evaluate(String expression, Object item)
         throws XPathExpressionException;
 
     /**
-     * <p>Evaluate an XPath expression in the context of the specified <code>InputSource</code>
-     * and return the result as the specified type.</p>
+     * Evaluate an XPath expression in the context of the specified {@code InputSource}
+     * and return the result as the specified type.
      *
      * <p>This method builds a data model for the {@link InputSource} and calls
-     * {@link #evaluate(String expression, Object item, QName returnType)} on the resulting document object.</p>
+     * {@link #evaluate(String expression, Object item, QName returnType)} on the resulting document object.
      *
      * <p>See <a href="#XPath-evaluation">Evaluation of XPath Expressions</a> for context item evaluation,
-     * variable, function and QName resolution and return type conversion.</p>
-     *
-     * <p>If <code>returnType</code> is not one of the types defined in {@link XPathConstants},
-     * then an <code>IllegalArgumentException</code> is thrown.</p>
-     *
-     * <p>If <code>expression</code>, <code>source</code> or <code>returnType</code> is <code>null</code>,
-     * then a <code>NullPointerException</code> is thrown.</p>
+     * variable, function and QName resolution and return type conversion.
      *
      * @param expression The XPath expression.
      * @param source The input source of the document to evaluate over.
      * @param returnType The desired return type.
      *
-     * @return The <code>Object</code> that encapsulates the result of evaluating the expression.
+     * @return The {@code Object} that encapsulates the result of evaluating the expression.
      *
      * @throws XPathExpressionException If expression cannot be evaluated.
-     * @throws IllegalArgumentException If <code>returnType</code> is not one of the types defined in {@link XPathConstants}.
-     * @throws NullPointerException If <code>expression</code>, <code>source</code> or <code>returnType</code>
-     *   is <code>null</code>.
+     * @throws IllegalArgumentException If {@code returnType} is not one of the types defined in {@link XPathConstants}.
+     * @throws NullPointerException If {@code expression, source or returnType} is {@code null}.
      */
     public Object evaluate(
         String expression,
@@ -293,27 +290,209 @@
         throws XPathExpressionException;
 
     /**
-     * <p>Evaluate an XPath expression in the context of the specified <code>InputSource</code>
-     * and return the result as a <code>String</code>.</p>
+     * Evaluate an XPath expression in the context of the specified {@code InputSource}
+     * and return the result as a {@code String}.
      *
      * <p>This method calls {@link #evaluate(String expression, InputSource source, QName returnType)} with a
-     * <code>returnType</code> of {@link XPathConstants#STRING}.</p>
+     * {@code returnType} of {@link XPathConstants#STRING}.
      *
      * <p>See <a href="#XPath-evaluation">Evaluation of XPath Expressions</a> for context item evaluation,
-     * variable, function and QName resolution and return type conversion.</p>
-     *
-     * <p>If <code>expression</code> or <code>source</code> is <code>null</code>,
-     * then a <code>NullPointerException</code> is thrown.</p>
+     * variable, function and QName resolution and return type conversion.
      *
      * @param expression The XPath expression.
-     * @param source The <code>InputSource</code> of the document to evaluate over.
+     * @param source The {@code InputSource} of the document to evaluate over.
      *
-     * @return The <code>String</code> that is the result of evaluating the expression and
-     *   converting the result to a <code>String</code>.
+     * @return The {@code String} that is the result of evaluating the expression and
+     *   converting the result to a {@code String}.
      *
      * @throws XPathExpressionException If expression cannot be evaluated.
-     * @throws NullPointerException If <code>expression</code> or <code>source</code> is <code>null</code>.
+     * @throws NullPointerException If {@code expression or source} is {@code null}.
      */
     public String evaluate(String expression, InputSource source)
         throws XPathExpressionException;
+
+    /**
+     * Evaluate an XPath expression in the specified context and return
+     * the result with the type specified through the {@code class type}
+     *
+     * <p>
+     * The parameter {@code item} represents the context the XPath expression
+     * will be operated on. The type of the context is implementation-dependent.
+     * If the value is {@code null}, the operation must have no dependency on
+     * the context, otherwise an XPathExpressionException will be thrown.
+     *
+     * @implNote
+     * The type of the context is usually {@link org.w3c.dom.Node}.
+     *
+     * @implSpec
+     * The default implementation in the XPath API is equivalent to:
+     * <pre> {@code
+     *     (T)evaluate(expression, item,
+     *           XPathEvaluationResult.XPathResultType.getQNameType(type));
+     * }</pre>
+     *
+     * Since the {@code evaluate} method does not support the
+     * {@link XPathEvaluationResult.XPathResultType#ANY ANY} type, specifying
+     * XPathEvaluationResult as the type will result in IllegalArgumentException.
+     * Any implementation supporting the
+     * {@link XPathEvaluationResult.XPathResultType#ANY ANY} type must override
+     * this method.
+     *
+     * @param <T> The class type that will be returned by the XPath expression.
+     * @param expression The XPath expression.
+     * @param item The context the XPath expression will be evaluated in.
+     * @param type The class type expected to be returned by the XPath expression.
+     *
+     * @return The result of evaluating the expression.
+     *
+     * @throws XPathExpressionException If the expression cannot be evaluated.
+     * @throws IllegalArgumentException If {@code type} is not of the types
+     * corresponding to the types defined in the {@link XPathEvaluationResult.XPathResultType},
+     * or XPathEvaluationResult is specified as the type but an implementation supporting the
+     * {@link XPathEvaluationResult.XPathResultType#ANY ANY} type is not available.
+     * @throws NullPointerException If {@code expression or type} is {@code null}.
+     *
+     * @since 1.9
+     */
+    default <T>T evaluateExpression(String expression, Object item, Class<T> type)
+        throws XPathExpressionException {
+        return type.cast(evaluate(expression, item,
+                XPathEvaluationResult.XPathResultType.getQNameType(type)));
+    }
+
+    /**
+     * Evaluate an XPath expression in the specified context. This is equivalent to
+     * calling {@link #evaluateExpression(String expression, Object item, Class type)}
+     * with type {@link XPathEvaluationResult}:
+     * <pre> {@code
+     *     evaluateExpression(expression, item, XPathEvaluationResult.class);
+     * }</pre>
+     * <p>
+     * The parameter {@code item} represents the context the XPath expression
+     * will be operated on. The type of the context is implementation-dependent.
+     * If the value is {@code null}, the operation must have no dependency on
+     * the context, otherwise an XPathExpressionException will be thrown.
+     *
+     * @implNote
+     * The type of the context is usually {@link org.w3c.dom.Node}.
+     *
+     * @implSpec
+     * The default implementation in the XPath API is equivalent to:
+     * <pre> {@code
+     *     evaluateExpression(expression, item, XPathEvaluationResult.class);
+     * }</pre>
+     *
+     * Since the {@code evaluate} method does not support the
+     * {@link XPathEvaluationResult.XPathResultType#ANY ANY}
+     * type, the default implementation of this method will always throw an
+     * IllegalArgumentException. Any implementation supporting the
+     * {@link XPathEvaluationResult.XPathResultType#ANY ANY} type must therefore
+     * override this method.
+     *
+     * @param expression The XPath expression.
+     * @param item The context the XPath expression will be evaluated in.
+     *
+     * @return The result of evaluating the expression.
+     *
+     * @throws XPathExpressionException If the expression cannot be evaluated.
+     * @throws IllegalArgumentException If the implementation of this method
+     * does not support the
+     * {@link XPathEvaluationResult.XPathResultType#ANY ANY} type.
+     * @throws NullPointerException If {@code expression} is {@code null}.
+     *
+     * @since 1.9
+     */
+    default XPathEvaluationResult<?> evaluateExpression(String expression, Object item)
+        throws XPathExpressionException
+    {
+        return evaluateExpression(expression, item, XPathEvaluationResult.class);
+    }
+
+    /**
+     * Evaluate an XPath expression in the context of the specified {@code source}
+     * and return the result as specified.
+     * <p>
+     * This method builds a data model for the {@link InputSource} and calls
+     * {@link #evaluateExpression(String expression, Object item, Class type)}
+     * on the resulting document object. The data model is usually
+     * {@link org.w3c.dom.Document}
+     *
+     * @implSpec
+     * The default implementation in the XPath API is equivalent to:
+     * <pre> {@code
+           (T)evaluate(expression, source,
+                XPathEvaluationResult.XPathResultType.getQNameType(type));
+     * }</pre>
+     *
+     * Since the {@code evaluate} method does not support the
+     * {@link XPathEvaluationResult.XPathResultType#ANY ANY} type, specifying
+     * XPathEvaluationResult as the type will result in IllegalArgumentException.
+     * Any implementation supporting the
+     * {@link XPathEvaluationResult.XPathResultType#ANY ANY} type must override
+     * this method.
+     *
+     * @param <T> The class type that will be returned by the XPath expression.
+     * @param expression The XPath expression.
+     * @param source The input source of the document to evaluate over.
+     * @param type The class type expected to be returned by the XPath expression.
+     *
+     * @return The result of evaluating the expression.
+     *
+     * @throws XPathExpressionException If the expression cannot be evaluated.
+     * @throws IllegalArgumentException If {@code type} is not of the types
+     * corresponding to the types defined in the {@link XPathEvaluationResult.XPathResultType
+     * XPathResultType}, or XPathEvaluationResult is specified as the type but an
+     * implementation supporting the
+     * {@link XPathEvaluationResult.XPathResultType#ANY ANY} type is not available.
+     * @throws NullPointerException If {@code expression, source or type}is {@code null}.
+     *
+     * @since 1.9
+     */
+    default <T>T evaluateExpression(String expression, InputSource source, Class<T> type)
+        throws XPathExpressionException
+    {
+        return type.cast(evaluate(expression, source,
+                XPathEvaluationResult.XPathResultType.getQNameType(type)));
+    }
+
+    /**
+     * Evaluate an XPath expression in the specified context. This is equivalent to
+     * calling {@link #evaluateExpression(String expression, Object item, Class type)}
+     * with type {@link XPathEvaluationResult}:
+     * <pre> {@code
+     *     evaluateExpression(expression, item, XPathEvaluationResult.class);
+     * }</pre>
+     * <p>
+     *
+     * @implSpec
+     * The default implementation in the XPath API is equivalent to:
+     * <pre> {@code
+     *     evaluateExpression(expression, source, XPathEvaluationResult.class);
+     * }</pre>
+     *
+     * Since the {@code evaluate} method does not support the
+     * {@link XPathEvaluationResult.XPathResultType#ANY ANY}
+     * type, the default implementation of this method will always throw an
+     * IllegalArgumentException. Any implementation supporting the
+     * {@link XPathEvaluationResult.XPathResultType#ANY ANY} type must therefore
+     * override this method.
+     *
+     * @param expression The XPath expression.
+     * @param source The input source of the document to evaluate over.
+     *
+     * @return The result of evaluating the expression.
+     *
+     * @throws XPathExpressionException If the expression cannot be evaluated.
+     * @throws IllegalArgumentException If the implementation of this method
+     * does not support the
+     * {@link XPathEvaluationResult.XPathResultType#ANY ANY} type.
+     * @throws NullPointerException If {@code expression or source} is {@code null}.
+     *
+     * @since 1.9
+     */
+    default XPathEvaluationResult<?> evaluateExpression(String expression, InputSource source)
+        throws XPathExpressionException
+    {
+        return evaluateExpression(expression, source, XPathEvaluationResult.class);
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/src/java.xml/share/classes/javax/xml/xpath/XPathEvaluationResult.java	Tue Jan 27 22:01:46 2015 -0800
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package javax.xml.xpath;
+
+import java.util.Objects;
+import javax.xml.namespace.QName;
+import org.w3c.dom.Node;
+/**
+ * The {@code XPathEvaluationResult} interface represents the result of the
+ * evaluation of an XPath expression within the context of a particular node.
+ * The evaluation of an XPath expression can result in various result types as
+ * defined in XML Path Language (XPath) Version 1.0.
+ * <p>
+ *
+ * @param <T> the object type returned by the XPath evaluation.
+ * @see <a href="http://www.w3.org/TR/xpath">XML Path Language (XPath) Version
+ * 1.0</a>
+ *
+ * @since 1.9
+ */
+public interface XPathEvaluationResult<T> {
+
+    /**
+     * XPathResultType represents possible return types of an XPath evaluation.
+     * Provided as an enum type, it allows the use of switch statement. At the
+     * same time, a mapping is provided between the original QName types in
+     * {@link XPathConstants} and class types used in the generic methods.
+     */
+    public static enum XPathResultType {
+        /**
+         * Any type that represents any of the 5 other types listed below.
+         * Maps to {@link XPathEvaluationResult}.
+         */
+        ANY(new QName("http://www.w3.org/1999/XSL/Transform", "any"), XPathEvaluationResult.class),
+        /**
+         * The XPath 1.0 boolean data type. Maps to Java {@link Boolean}.
+         */
+        BOOLEAN(XPathConstants.BOOLEAN, Boolean.class),
+        /**
+         * The XPath 1.0 Number data type. Maps to Java {@link Number}. Of the
+         * subtypes of Number, only Double, Integer and Long are required.
+         */
+        NUMBER(XPathConstants.NUMBER, Number.class),
+        /**
+         * The XPath 1.0 String data type. Maps to Java {@link String}.
+         */
+        STRING(XPathConstants.STRING, String.class),
+        /**
+         * The XPath 1.0 NodeSet data type. Maps to {@link org.w3c.dom.NodeList}.
+         */
+        NODESET(XPathConstants.NODESET, XPathNodes.class),
+        /**
+         * The XPath 1.0 NodeSet data type. Maps to {@link org.w3c.dom.Node}.
+         */
+        NODE(XPathConstants.NODE, Node.class);
+
+        final QName qnameType;
+        final Class<?> clsType;
+        XPathResultType(QName qnameType, Class<?> clsType) {
+            this.qnameType = qnameType;
+            this.clsType = clsType;
+        }
+
+        /**
+         * Compares this type to the specified class type.
+         * @param clsType class type
+         * @return true if the argument is not null and is a class type that
+         * matches that this type represents, false otherwise.
+         */
+        private boolean equalsClassType(Class<?> clsType) {
+            Objects.nonNull(clsType);
+            if (clsType.isAssignableFrom(this.clsType)) {
+                return true;
+            }
+            return false;
+        }
+
+        /**
+         * Returns the QName type as specified in {@link XPathConstants} that
+         * corresponds to the specified class type.
+         * @param clsType a class type that the enum type supports
+         * @return the QName type that matches with the specified class type,
+         * null if there is no match
+         */
+        static public QName getQNameType(Class<?> clsType) {
+            for (XPathResultType type : XPathResultType.values()) {
+                if (type.equalsClassType(clsType)) {
+                    return type.qnameType;
+                }
+            }
+            return null;
+        }
+    }
+
+    /**
+     * Return the result type as an enum specified by {@code XPathResultType}
+     * @return the result type
+     */
+    public XPathResultType type();
+
+    /**
+     * Returns the value of the result as the type &lt;T&gt; specified for the class.
+     *
+     * @return The value of the result.
+     */
+    public T value();
+
+}
--- a/jaxp/src/java.xml/share/classes/javax/xml/xpath/XPathExpression.java	Mon Jan 26 12:17:59 2015 +0300
+++ b/jaxp/src/java.xml/share/classes/javax/xml/xpath/XPathExpression.java	Tue Jan 27 22:01:46 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,11 +25,11 @@
 
 package javax.xml.xpath;
 
+import javax.xml.namespace.QName;
 import org.xml.sax.InputSource;
-import javax.xml.namespace.QName;
 
 /**
- * <p><code>XPathExpression</code> provides access to compiled XPath expressions.</p>
+ * <p>{@code XPathExpression} provides access to compiled XPath expressions.</p>
  *
  * <a name="XPathExpression-evaluation"/>
  * <table border="1" cellpadding="2">
@@ -53,7 +53,7 @@
  *      <td>
  *        If the expression contains a variable reference, its value will be found through the {@link XPathVariableResolver}.
  *        An {@link XPathExpressionException} is raised if the variable resolver is undefined or
- *        the resolver returns <code>null</code> for the variable.
+ *        the resolver returns {@code null} for the variable.
  *        The value of a variable must be immutable through the course of any single evaluation.</p>
  *      </td>
  *    </tr>
@@ -62,7 +62,7 @@
  *      <td>
  *        If the expression contains a function reference, the function will be found through the {@link XPathFunctionResolver}.
  *        An {@link XPathExpressionException} is raised if the function resolver is undefined or
- *        the function resolver returns <code>null</code> for the function.</p>
+ *        the function resolver returns {@code null} for the function.</p>
  *      </td>
  *    </tr>
  *    <tr>
@@ -84,9 +84,9 @@
  * <p>An XPath expression is not thread-safe and not reentrant.
  * In other words, it is the application's responsibility to make
  * sure that one {@link XPathExpression} object is not used from
- * more than one thread at any given time, and while the <code>evaluate</code>
+ * more than one thread at any given time, and while the {@code evaluate}
  * method is invoked, applications may not recursively call
- * the <code>evaluate</code> method.
+ * the {@code evaluate} method.
  * <p>
  *
  * @author  <a href="mailto:Norman.Walsh@Sun.com">Norman Walsh</a>
@@ -96,50 +96,56 @@
  */
 public interface XPathExpression {
 
+
     /**
      * <p>Evaluate the compiled XPath expression in the specified context and return the result as the specified type.</p>
      *
      * <p>See <a href="#XPathExpression-evaluation">Evaluation of XPath Expressions</a> for context item evaluation,
      * variable, function and QName resolution and return type conversion.</p>
      *
-     * <p>If <code>returnType</code> is not one of the types defined in {@link XPathConstants},
-     * then an <code>IllegalArgumentException</code> is thrown.</p>
+     * <p>
+     * The parameter {@code item} represents the context the XPath expression
+     * will be operated on. The type of the context is implementation-dependent.
+     * If the value is {@code null}, the operation must have no dependency on
+     * the context, otherwise an XPathExpressionException will be thrown.
      *
-     * <p>If a <code>null</code> value is provided for
-     * <code>item</code>, an empty document will be used for the
-     * context.
-     * If <code>returnType</code> is <code>null</code>, then a <code>NullPointerException</code> is thrown.</p>
+     * @implNote
+     * The type of the context is usually {@link org.w3c.dom.Node}.
      *
-     * @param item The starting context (a node, for example).
-     * @param returnType The desired return type.
+     * @param item The context the XPath expression will be evaluated in.
+     * @param returnType The result type expected to be returned by the XPath expression.
      *
-     * @return The <code>Object</code> that is the result of evaluating the expression and converting the result to
-     *   <code>returnType</code>.
+     * @return The {@code Object} that is the result of evaluating the expression and converting the result to
+     *   {@code returnType}.
      *
      * @throws XPathExpressionException If the expression cannot be evaluated.
-     * @throws IllegalArgumentException If <code>returnType</code> is not one of the types defined in {@link XPathConstants}.
-     * @throws NullPointerException If  <code>returnType</code> is <code>null</code>.
+     * @throws IllegalArgumentException If {@code returnType} is not one of the types defined in {@link XPathConstants}.
+     * @throws NullPointerException If {@code returnType} is {@code null}.
      */
     public Object evaluate(Object item, QName returnType)
         throws XPathExpressionException;
 
     /**
-     * <p>Evaluate the compiled XPath expression in the specified context and return the result as a <code>String</code>.</p>
+     * <p>Evaluate the compiled XPath expression in the specified context and return the result as a {@code String}.</p>
      *
-     * <p>This method calls {@link #evaluate(Object item, QName returnType)} with a <code>returnType</code> of
+     * <p>This method calls {@link #evaluate(Object item, QName returnType)} with a {@code returnType} of
      * {@link XPathConstants#STRING}.</p>
      *
      * <p>See <a href="#XPathExpression-evaluation">Evaluation of XPath Expressions</a> for context item evaluation,
      * variable, function and QName resolution and return type conversion.</p>
      *
-     * <p>If a <code>null</code> value is provided for
-     * <code>item</code>, an empty document will be used for the
-     * context.
+     * <p>
+     * The parameter {@code item} represents the context the XPath expression
+     * will be operated on. The type of the context is implementation-dependent.
+     * If the value is {@code null}, the operation must have no dependency on
+     * the context, otherwise an XPathExpressionException will be thrown.
      *
-     * @param item The starting context (a node, for example).
+     * @implNote
+     * The type of the context is usually {@link org.w3c.dom.Node}.
      *
-     * @return The <code>String</code> that is the result of evaluating the expression and converting the result to a
-     *   <code>String</code>.
+     * @param item The context the XPath expression will be evaluated in.
+     *
+     * @return The result of evaluating an XPath expression as a {@code String}.
      *
      * @throws XPathExpressionException If the expression cannot be evaluated.
      */
@@ -147,7 +153,7 @@
         throws XPathExpressionException;
 
     /**
-     * <p>Evaluate the compiled XPath expression in the context of the specified <code>InputSource</code> and return the result as the
+     * <p>Evaluate the compiled XPath expression in the context of the specified {@code InputSource} and return the result as the
      * specified type.</p>
      *
      * <p>This method builds a data model for the {@link InputSource} and calls
@@ -156,45 +162,225 @@
      * <p>See <a href="#XPathExpression-evaluation">Evaluation of XPath Expressions</a> for context item evaluation,
      * variable, function and QName resolution and return type conversion.</p>
      *
-     * <p>If <code>returnType</code> is not one of the types defined in {@link XPathConstants},
-     * then an <code>IllegalArgumentException</code> is thrown.</p>
+     * <p>If {@code returnType} is not one of the types defined in {@link XPathConstants},
+     * then an {@code IllegalArgumentException} is thrown.</p>
      *
-     * <p>If <code>source</code> or <code>returnType</code> is <code>null</code>,
-     * then a <code>NullPointerException</code> is thrown.</p>
+     * <p>If {@code source} or {@code returnType} is {@code null},
+     * then a {@code NullPointerException} is thrown.</p>
      *
-     * @param source The <code>InputSource</code> of the document to evaluate over.
+     * @param source The {@code InputSource} of the document to evaluate over.
      * @param returnType The desired return type.
      *
-     * @return The <code>Object</code> that is the result of evaluating the expression and converting the result to
-     *   <code>returnType</code>.
+     * @return The {@code Object} that is the result of evaluating the expression and converting the result to
+     *   {@code returnType}.
      *
      * @throws XPathExpressionException If the expression cannot be evaluated.
-     * @throws IllegalArgumentException If <code>returnType</code> is not one of the types defined in {@link XPathConstants}.
-     * @throws NullPointerException If  <code>source</code> or <code>returnType</code> is <code>null</code>.
+     * @throws IllegalArgumentException If {@code returnType} is not one of the types defined in {@link XPathConstants}.
+     * @throws NullPointerException If {@code source or returnType} is {@code null}.
      */
     public Object evaluate(InputSource source, QName returnType)
         throws XPathExpressionException;
 
     /**
-     * <p>Evaluate the compiled XPath expression in the context of the specified <code>InputSource</code> and return the result as a
-     * <code>String</code>.</p>
+     * <p>Evaluate the compiled XPath expression in the context of the specified {@code InputSource} and return the result as a
+     * {@code String}.</p>
      *
-     * <p>This method calls {@link #evaluate(InputSource source, QName returnType)} with a <code>returnType</code> of
+     * <p>This method calls {@link #evaluate(InputSource source, QName returnType)} with a {@code returnType} of
      * {@link XPathConstants#STRING}.</p>
      *
      * <p>See <a href="#XPathExpression-evaluation">Evaluation of XPath Expressions</a> for context item evaluation,
      * variable, function and QName resolution and return type conversion.</p>
      *
-     * <p>If <code>source</code> is <code>null</code>, then a <code>NullPointerException</code> is thrown.</p>
+     * <p>If {@code source} is {@code null}, then a {@code NullPointerException} is thrown.</p>
      *
-     * @param source The <code>InputSource</code> of the document to evaluate over.
+     * @param source The {@code InputSource} of the document to evaluate over.
      *
-     * @return The <code>String</code> that is the result of evaluating the expression and converting the result to a
-     *   <code>String</code>.
+     * @return The {@code String} that is the result of evaluating the expression and converting the result to a
+     *   {@code String}.
      *
      * @throws XPathExpressionException If the expression cannot be evaluated.
-     * @throws NullPointerException If  <code>source</code> is <code>null</code>.
+     * @throws NullPointerException If {@code source} is {@code null}.
      */
     public String evaluate(InputSource source)
         throws XPathExpressionException;
+
+    /**
+     * Evaluate the compiled XPath expression in the specified context, and return
+     * the result with the type specified through the {@code class type}.
+     *
+     * <p>
+     * The parameter {@code item} represents the context the XPath expression
+     * will be operated on. The type of the context is implementation-dependent.
+     * If the value is {@code null}, the operation must have no dependency on
+     * the context, otherwise an XPathExpressionException will be thrown.
+     *
+     * @implNote
+     * The type of the context is usually {@link org.w3c.dom.Node}.
+     *
+     * @implSpec
+     * The default implementation in the XPath API is equivalent to:
+     * <pre> {@code
+     *     (T)evaluate(item, XPathEvaluationResult.XPathResultType.getQNameType(type));
+     * }</pre>
+     *
+     * Since the {@code evaluate} method does not support the
+     * {@link XPathEvaluationResult.XPathResultType#ANY ANY} type, specifying
+     * XPathEvaluationResult as the type will result in IllegalArgumentException.
+     * Any implementation supporting the
+     * {@link XPathEvaluationResult.XPathResultType#ANY ANY} type must override
+     * this method.
+     *
+     * @param <T> The class type that will be returned by the XPath expression.
+     * @param item The context the XPath expression will be evaluated in.
+     * @param type The class type expected to be returned by the XPath expression.
+     *
+     * @return The result of evaluating the expression.
+     *
+     * @throws XPathExpressionException If the expression cannot be evaluated.
+     * @throws IllegalArgumentException If {@code type} is not of the types
+     * corresponding to the types defined in the {@link XPathEvaluationResult.XPathResultType
+     * XPathResultType}, or XPathEvaluationResult is specified as the type but an
+     * implementation supporting the
+     * {@link XPathEvaluationResult.XPathResultType#ANY ANY} type is not available.
+     * @throws NullPointerException If {@code type} is {@code null}.
+     *
+     * @since 1.9
+     */
+    default <T>T evaluateExpression(Object item, Class<T> type)
+        throws XPathExpressionException
+    {
+        return type.cast(evaluate(item, XPathEvaluationResult.XPathResultType.getQNameType(type)));
+    }
+
+    /**
+     * Evaluate the compiled XPath expression in the specified context. This is
+     * equivalent to calling {@link #evaluateExpression(Object item, Class type)}
+     * with type {@link XPathEvaluationResult}:
+     * <pre> {@code
+     *     evaluateExpression(item, XPathEvaluationResult.class);
+     * }</pre>
+     * <p>
+     * The parameter {@code item} represents the context the XPath expression
+     * will be operated on. The type of the context is implementation-dependent.
+     * If the value is {@code null}, the operation must have no dependency on
+     * the context, otherwise an XPathExpressionException will be thrown.
+     *
+     * @implNote
+     * The type of the context is usually {@link org.w3c.dom.Node}.
+     *
+     * @implSpec
+     * The default implementation in the XPath API is equivalent to:
+     * <pre> {@code
+     *     evaluateExpression(item, XPathEvaluationResult.class);
+     * }</pre>
+     *
+     * Since the {@code evaluate} method does not support the
+     * {@link XPathEvaluationResult.XPathResultType#ANY ANY}
+     * type, the default implementation of this method will always throw an
+     * IllegalArgumentException. Any implementation supporting the
+     * {@link XPathEvaluationResult.XPathResultType#ANY ANY} type must therefore
+     * override this method.
+     *
+     * @param item The context the XPath expression will be evaluated in.
+     *
+     * @return The result of evaluating the expression.
+     *
+     * @throws XPathExpressionException If the expression cannot be evaluated.
+     * @throws IllegalArgumentException If the implementation of this method
+     * does not support the
+     * {@link XPathEvaluationResult.XPathResultType#ANY ANY} type.
+     *
+     * @since 1.9
+     */
+    default XPathEvaluationResult<?> evaluateExpression(Object item)
+        throws XPathExpressionException
+    {
+        return evaluateExpression(item, XPathEvaluationResult.class);
+    }
+
+    /**
+     * Evaluate the compiled XPath expression in the specified context,
+     * and return the result with the type specified through the {@code class type}
+     * <p>
+     * This method builds a data model for the {@link InputSource} and calls
+     * {@link #evaluateExpression(Object item, Class type)} on the resulting
+     * document object.
+     * <P>
+     * By default, the JDK's data model is {@link org.w3c.dom.Document}.
+     *
+     * @implSpec
+     * The default implementation in the XPath API is equivalent to:
+     * <pre> {@code
+           (T)evaluate(source, XPathEvaluationResult.XPathResultType.getQNameType(type));
+     * }</pre>
+     *
+     * Since the {@code evaluate} method does not support the
+     * {@link XPathEvaluationResult.XPathResultType#ANY ANY} type, specifying
+     * XPathEvaluationResult as the type will result in IllegalArgumentException.
+     * Any implementation supporting the
+     * {@link XPathEvaluationResult.XPathResultType#ANY ANY} type must override
+     * this method.
+     *
+     * @param <T> The class type that will be returned by the XPath expression.
+     * @param source The {@code InputSource} of the document to evaluate over.
+     * @param type The class type expected to be returned by the XPath expression.
+     *
+     * @return The result of evaluating the expression.
+     *
+     * @throws XPathExpressionException If the expression cannot be evaluated.
+     * @throws IllegalArgumentException If {@code type} is not of the types
+     * corresponding to the types defined in the {@link XPathEvaluationResult.XPathResultType
+     * XPathResultType}, or XPathEvaluationResult is specified as the type but an
+     * implementation supporting the
+     * {@link XPathEvaluationResult.XPathResultType#ANY ANY} type
+     * is not available.
+     * @throws NullPointerException If {@code source or type} is {@code null}.
+     *
+     * @since 1.9
+     */
+    default <T>T evaluateExpression(InputSource source, Class<T> type)
+        throws XPathExpressionException
+    {
+        return type.cast(evaluate(source, XPathEvaluationResult.XPathResultType.getQNameType(type)));
+    }
+
+    /**
+     * Evaluate the compiled XPath expression in the specified context. This is
+     * equivalent to calling {@link #evaluateExpression(InputSource source, Class type)}
+     * with type {@link XPathEvaluationResult}:
+     * <pre> {@code
+     *     evaluateExpression(source, XPathEvaluationResult.class);
+     * }</pre>
+     * <p>
+     *
+     * @implSpec
+     * The default implementation in the XPath API is equivalent to:
+     * <pre> {@code
+     *     (XPathEvaluationResult)evaluateExpression(source, XPathEvaluationResult.class);
+     * }</pre>
+     *
+     * Since the {@code evaluate} method does not support the
+     * {@link XPathEvaluationResult.XPathResultType#ANY ANY}
+     * type, the default implementation of this method will always throw an
+     * IllegalArgumentException. Any implementation supporting the
+     * {@link XPathEvaluationResult.XPathResultType#ANY ANY} type must therefore
+     * override this method.
+     *
+     * @param source The {@code InputSource} of the document to evaluate over.
+     *
+     * @return The result of evaluating the expression.
+     *
+     * @throws XPathExpressionException If the expression cannot be evaluated.
+     * @throws IllegalArgumentException If the implementation of this method
+     * does not support the
+     * {@link XPathEvaluationResult.XPathResultType#ANY ANY} type.
+     * @throws NullPointerException If {@code source} is {@code null}.
+     *
+     * @since 1.9
+     */
+    default XPathEvaluationResult<?> evaluateExpression(InputSource source)
+        throws XPathExpressionException
+    {
+        return evaluateExpression(source, XPathEvaluationResult.class);
+    }
 }
--- a/jaxp/src/java.xml/share/classes/javax/xml/xpath/XPathFactory.java	Mon Jan 26 12:17:59 2015 +0300
+++ b/jaxp/src/java.xml/share/classes/javax/xml/xpath/XPathFactory.java	Tue Jan 27 22:01:46 2015 -0800
@@ -117,7 +117,7 @@
     *     and returns it if it is successfully created.
     *   </li>
     *   <li>
-    *     ${java.home}/conf/jaxp.properties is read and the value associated with the key being the system property above is looked for.
+    *     ${java.home}/lib/jaxp.properties is read and the value associated with the key being the system property above is looked for.
     *     If present, the value is processed just like above.
     *   </li>
     *   <li>
--- a/jaxp/src/java.xml/share/classes/javax/xml/xpath/XPathFactoryFinder.java	Mon Jan 26 12:17:59 2015 +0300
+++ b/jaxp/src/java.xml/share/classes/javax/xml/xpath/XPathFactoryFinder.java	Tue Jan 27 22:01:46 2015 -0800
@@ -176,9 +176,9 @@
 
         String javah = ss.getSystemProperty( "java.home" );
         String configFile = javah + File.separator +
-        "conf" + File.separator + "jaxp.properties";
+        "lib" + File.separator + "jaxp.properties";
 
-        // try to read from $java.home/conf/jaxp.properties
+        // try to read from $java.home/lib/jaxp.properties
         try {
             if(firstTime){
                 synchronized(cacheProps){
@@ -193,7 +193,7 @@
                 }
             }
             final String factoryClassName = cacheProps.getProperty(propertyName);
-            debugPrintln("found " + factoryClassName + " in $java.home/conf/jaxp.properties");
+            debugPrintln("found " + factoryClassName + " in $java.home/jaxp.properties");
 
             if (factoryClassName != null) {
                 xpathFactory = createInstance(factoryClassName, true);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/src/java.xml/share/classes/javax/xml/xpath/XPathNodes.java	Tue Jan 27 22:01:46 2015 -0800
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package javax.xml.xpath;
+
+import java.util.Iterator;
+import org.w3c.dom.Node;
+
+/**
+ * XPathNodes represents a set of nodes selected by a location path as specified
+ * in <a href="http://www.w3.org/TR/xpath/#node-sets">XML Path Language (XPath)
+ * Version 1.0, 3.3 Node-sets</a>.
+ *
+ * @since 1.9
+ */
+public interface XPathNodes extends Iterable<Node> {
+
+    /**
+     * Returns an iterator of the Nodes.
+     *
+     * @return an Iterator.
+     */
+    @Override
+    public abstract Iterator<Node> iterator();
+
+    /**
+     * Returns the number of items in the result
+     *
+     * @return The number of items in the result
+     */
+    public abstract int size();
+
+    /**
+     * Returns a Node at the specified position
+     *
+     * @param index Index of the element to return.
+     * @return The Node at the specified position.
+     * @throws javax.xml.xpath.XPathException If the index is out of range
+     * (index &lt; 0 || index &gt;= size())
+     */
+    public abstract Node get(int index)
+            throws XPathException;
+}
--- a/jaxp/src/java.xml/share/classes/javax/xml/xpath/package.html	Mon Jan 26 12:17:59 2015 +0300
+++ b/jaxp/src/java.xml/share/classes/javax/xml/xpath/package.html	Tue Jan 27 22:01:46 2015 -0800
@@ -1,6 +1,8 @@
-<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
 <!--
-Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
+Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
 DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 
 This code is free software; you can redistribute it and/or modify it
@@ -23,35 +25,35 @@
 or visit www.oracle.com if you need additional information or have any
 questions. 
 -->
+</head>
+<body bgcolor="white">
 
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
-                      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-<title>javax.xml.xpath</title>
-<meta name="@author" content="mailto:Ben@galbraiths.org" />
-<meta name="@author" content="mailto:Norman.Walsh@Sun.com" />
-<meta name="@author" content="mailto:Jeff.Suttor@Sun.com" />
-<meta name="@see" content="http://www.w3.org/TR/xpath" />
-<meta name="@since" content="1.5" />
-</head>
-
-<body>
-
-<p>This package provides an <em>object-model neutral</em> API for the
+This package provides an <em>object-model neutral</em> API for the
 evaluation of XPath expressions and access to the evaluation
 environment.
-</p>
 
-<p>The following XML standards apply:</p>
-
-<ul>
-<li><a href="http://www.w3.org/TR/xpath">XML Path Language (XPath) Version 1.0</a></li>
-</ul>
+<p>
+The XPath API supports <a href="http://www.w3.org/TR/xpath">
+    XML Path Language (XPath) Version 1.0</a>
 
 <hr />
 
-<h2>XPath Overview</h2>
+<ul>
+    <li><a href='#XPath.Overview'>1. XPath Overview</a></li>
+    <li><a href='#XPath.Expressions'>2. XPath Expressions</a></li>
+    <li><a href='#XPath.Datatypes'>3. XPath Data Types</a>
+        <ul>
+            <li><a href='#XPath.Datatypes.QName'>3.1 QName Types</a>
+            <li><a href='#XPath.Datatypes.Class'>3.2 Class Types</a>
+            <li><a href='#XPath.Datatypes.Enum'>3.3 Enum Types</a>
+        </ul>    
+    </li>
+    <li><a href='#XPath.Context'>4. XPath Context</a></li>
+    <li><a href='#XPath.Use'>5. Using the XPath API</a></li>
+</ul>
+<p>
+<a name="XPath.Overview"></a>
+<h3>1. XPath Overview</h3>
 
 <p>The XPath language provides a simple, concise syntax for selecting
 nodes from an XML document. XPath also provides rules for converting a
@@ -67,7 +69,8 @@
 replace many lines of DOM API code.
 </p>
 
-<h3>XPath Expressions</h3>
+<a name="XPath.Expressions"></a>
+<h3>2. XPath Expressions</h3>
 
 <p>An XPath <em>expression</em> is composed of a <em>location
 path</em> and one or more optional <em>predicates</em>. Expressions
@@ -76,18 +79,22 @@
 
 <p>The following is an example of a simple XPath expression:</p>
 
+<blockquote>
 <pre>
 /foo/bar
 </pre>
+</blockquote>
 
 <p>This example would select the <code>&lt;bar&gt;</code> element in
 an XML document such as the following:</p>
 
+<blockquote>
 <pre>
 &lt;foo&gt;
-&lt;bar/&gt;
+    &lt;bar/&gt;
 &lt;/foo&gt;
 </pre>
+</blockquote>
 
 <p>The expression <code>/foo/bar</code> is an example of a location
 path. While XPath location paths resemble Unix-style file system
@@ -96,30 +103,36 @@
 <code>&lt;bar&gt;</code> elements in the following document would be
 selected by the <code>/foo/bar</code> expression:</p>
 
+<blockquote>
 <pre>
 &lt;foo&gt;
-&lt;bar/&gt;
-&lt;bar/&gt;
-&lt;bar/&gt;
+    &lt;bar/&gt;
+    &lt;bar/&gt;
+    &lt;bar/&gt;
 &lt;/foo&gt;
 </pre>
+</blockquote>
 
 <p>A special location path operator, <code>//</code>, selects nodes at
 any depth in an XML document. The following example selects all
 <code>&lt;bar&gt;</code> elements regardless of their location in a
 document:</p>
 
+<blockquote>
 <pre>
 //bar
 </pre>
+</blockquote>
 
 <p>A wildcard operator, *, causes all element nodes to be selected.
 The following example selects all children elements of a
-<code>&lt;foo&gt;</code> element:</p>
+<code>&lt;foo&gt;</code> element:
 
+<blockquote>
 <pre>
 /foo/*
 </pre>
+</blockquote>
 
 <p>In addition to element nodes, XPath location paths may also address
 attribute nodes, text nodes, comment nodes, and processing instruction
@@ -166,35 +179,27 @@
 <code>&lt;foo&gt;</code> elements that contain an <code>include</code>
 attribute with the value of <code>true</code>:</p>
 
+<blockquote>
 <pre>
 //foo[@include='true']
 </pre>
+</blockquote>
 
 <p>Predicates may be appended to each other to further refine an
 expression, such as:</p>
 
+<blockquote>
 <pre>
 //foo[@include='true'][@mode='bar']
 </pre>
-
-<h3>Using the XPath API</h3>
-
-<p>
-The following example demonstrates using the XPath API to select one
-or more nodes from an XML document:</p>
+</blockquote>
 
-<pre>
-XPath xpath = XPathFactory.newInstance().newXPath();
-String expression = "/widgets/widget";
-InputSource inputSource = new InputSource("widgets.xml");
-NodeList nodes = (NodeList) xpath.evaluate(expression, inputSource, XPathConstants.NODESET);
-</pre>
-
-<h3>XPath Expressions and Types</h3>
+<a name="XPath.Datatypes"></a>
+<h3>3. XPath Data Types</h3>
 
 <p>While XPath expressions select nodes in the XML document, the XPath
 API allows the selected nodes to be coalesced into one of the
-following other data types:</p>
+following data types:</p>
 
 <ul>
 <li><code>Boolean</code></li>
@@ -202,14 +207,10 @@
 <li><code>String</code></li>
 </ul>
 
-<p>The desired return type is specified by a {@link
-javax.xml.namespace.QName} parameter in method call used to evaluate
-the expression, which is either a call to
-<code>XPathExpression.evalute(...)</code> or to one of the
-<code>XPath.evaluate(...)</code> convenience methods. The allowed
-QName values are specified as constants in the {@link
-javax.xml.xpath.XPathConstants} class; they are:</p>
-
+<a name="XPath.Datatypes.QName"></a>
+<h3>3.1 QName types</h3>
+The XPath API defines the following {@link javax.xml.namespace.QName} types to 
+represent return types of an XPath evaluation:
 <ul>
 <li>{@link javax.xml.xpath.XPathConstants#NODESET}</li>
 <li>{@link javax.xml.xpath.XPathConstants#NODE}</li>
@@ -218,26 +219,71 @@
 <li>{@link javax.xml.xpath.XPathConstants#NUMBER}</li>
 </ul>
 
+<p>The return type is specified by a {@link javax.xml.namespace.QName} parameter 
+in method call used to evaluate the expression, which is either a call to
+<code>XPathExpression.evalute(...)</code> or <code>XPath.evaluate(...)</code> 
+methods. 
+
 <p>When a <code>Boolean</code> return type is requested,
 <code>Boolean.TRUE</code> is returned if one or more nodes were
-selected; otherwise, <code>Boolean.FALSE</code> is returned.</p>
+selected; otherwise, <code>Boolean.FALSE</code> is returned.
 
 <p>The <code>String</code> return type is a convenience for retrieving
 the character data from a text node, attribute node, comment node, or
 processing-instruction node. When used on an element node, the value
 of the child text nodes is returned.
-</p>
 
 <p>The <code>Number</code> return type attempts to coalesce the text
 of a node to a <code>double</code> data type.
-</p>
+
+<a name="XPath.Datatypes.Class"></a>
+<h3>3.2 Class types</h3>
+In addition to the QName types, the XPath API supports the use of Class types
+through the <code>XPathExpression.evaluteExpression(...)</code> or 
+<code>XPath.evaluateExpression(...)</code> methods. 
 
-<h3>XPath Context</h3>
+The XPath data types are mapped to Class types as follows:
+<ul>
+<li><code>Boolean</code> -- <code>Boolean.class</code></li>
+<li><code>Number</code> -- <code>Number.class</code></li>
+<li><code>String</code> -- <code>String.class</code></li>
+<li><code>Nodeset</code> -- <code>XPathNodes.class</code></li>
+<li><code>Node</code> -- <code>Node.class</code></li>
+</ul>
+
+<p>
+Of the subtypes of Number, only Double, Integer and Long are supported.
+         
+<a name="XPath.Datatypes.Enum"></a>
+<h3>3.3 Enum types</h3>
+Enum types are defined in {@link javax.xml.xpath.XPathEvaluationResult.XPathResultType} 
+that provide mappings between the QName and Class types above. The result of 
+evaluating an expression using the <code>XPathExpression.evaluteExpression(...)</code> 
+or <code>XPath.evaluateExpression(...)</code> methods will be of one of these types.
+
+<a name="XPath.Context"></a>
+<h3>4. XPath Context</h3>
 
 <p>XPath location paths may be relative to a particular node in the
-document, known as the <code>context</code>. Consider the following
-XML document:</p>
+document, known as the <code>context</code>. A context consists of:
+<ul>
+    <li>a node (the context node)</li>
+    <li>a pair of non-zero positive integers (the context position and the context size)</li>
+    <li>a set of variable bindings</li>
+    <li>a function library</li>
+    <li>the set of namespace declarations in scope for the expression</li>    
+</ul>
 
+<p>
+It is an XML document tree represented as a hierarchy of nodes, a 
+{@link org.w3c.dom.Node} for example, in the JDK implementation.
+
+<a name="XPath.Use"></a>
+<h3>5. Using the XPath API</h3>
+
+Consider the following XML document:
+<p>
+<blockquote>
 <pre>
 &lt;widgets&gt;
 &lt;widget&gt;
@@ -246,36 +292,88 @@
 &lt;/widget&gt;
 &lt;/widgets&gt;
 </pre>
+</blockquote>
 
-<p>The <code>&lt;widget&gt;</code> element can be selected with the
-following XPath API code:</p>
+<p>
+The <code>&lt;widget&gt;</code> element can be selected with the following process:
 
+<blockquote>
 <pre>
 // parse the XML as a W3C Document
 DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
 Document document = builder.parse(new File("/widgets.xml"));
 
+//Get an XPath object and evaluate the expression
 XPath xpath = XPathFactory.newInstance().newXPath();
 String expression = "/widgets/widget";
 Node widgetNode = (Node) xpath.evaluate(expression, document, XPathConstants.NODE);
+
+//or using the evaluateExpression method
+Node widgetNode = xpath.evaluateExpression(expression, document, Node.class);
 </pre>
+</blockquote>
 
 <p>With a reference to the <code>&lt;widget&gt;</code> element, a
-relative XPath expression can now written to select the
+relative XPath expression can be written to select the
 <code>&lt;manufacturer&gt;</code> child element:</p>
 
+<blockquote>
 <pre>
 XPath xpath = XPathFactory.newInstance().newXPath();
 <strong>String expression = "manufacturer";</strong>
 Node manufacturerNode = (Node) xpath.evaluate(expression, <strong>widgetNode</strong>, XPathConstants.NODE);
+
+//or using the evaluateExpression method
+Node manufacturerNode = xpath.evaluateExpression(expression, <strong>widgetNode</strong>, Node.class);
 </pre>
+</blockquote>
+
+<p>
+In the above example, the XML file is read into a DOM Document before being passed
+to the XPath API. The following code demonstrates the use of InputSource to 
+leave it to the XPath implementation to process it:
+
+<blockquote>
+<pre>
+XPath xpath = XPathFactory.newInstance().newXPath();
+String expression = "/widgets/widget";
+InputSource inputSource = new InputSource("widgets.xml");
+NodeList nodes = (NodeList) xpath.evaluate(expression, inputSource, XPathConstants.NODESET);
+
+//or using the evaluateExpression method
+XPathNodes nodes = xpath.evaluate(expression, inputSource, XPathNodes.class);
+</pre>
+</blockquote>
 
-<ul>
-<li>Author <a href="mailto:Ben@galbraiths.org">Ben Galbraith</a></li>
-<li>Author <a href="mailto:Norman.Walsh@Sun.com">Norman Walsh</a></li>
-<li>Author <a href="mailto:Jeff.Suttor@Sun.com">Jeff Suttor</a></li>
-<li>See <a href="http://www.w3.org/TR/xpath">XML Path Language (XPath) Version 1.0</a></li>
-<li>Since 1.5</li>
-</ul>		
+<p>
+In the above cases, the type of the expected results are known. In case where
+the result type is unknown or any type, the {@link javax.xml.xpath.XPathEvaluationResult}
+may be used to determine the return type. The following code demonstrates the usage:
+<blockquote>
+<pre>
+XPathEvaluationResult&lt;?&gt; result = xpath.evaluateExpression(expression, document);
+switch (result.type()) {
+    case NODESET:
+        XPathNodes nodes = (XPathNodes)result.value();
+        ...
+        break;
+}
+</pre>
+</blockquote>
+
+<p>
+The XPath 1.0 Number data type is defined as a double. However, the XPath 
+specification also provides functions that returns Integer type. To facilitate
+such operations, the XPath API allows Integer and Long to be used in 
+{@code evaluateExpression} method such as the following code: 
+<p>
+<blockquote>
+<pre>
+int count = xpath.evaluate("count(/widgets/widget)", document, Integer.class);
+</pre>
+</blockquote>
+
+@since 1.5
+
 </body>
 </html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/javax/xml/xpath/XPathAnyTypeTest.java	Tue Jan 27 22:01:46 2015 -0800
@@ -0,0 +1,190 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package javax.xml.xpath;
+
+import java.io.File;
+import javax.xml.xpath.*;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+import org.testng.annotations.Test;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+
+/*
+ * @bug 8054196
+ * @summary Test for the project XPath: support any type. This test covers the new
+ * evaluateExpression methods of XPath, as well as XPathNodes and XPathEvaluationResult.
+ */
+public class XPathAnyTypeTest extends XPathTestBase {
+    /*
+     Test for resolveFunction(QName functionName,int arity); evaluate throws
+     NPE if functionName  is null.
+     */
+
+    @Test(dataProvider = "xpath", expectedExceptions = NullPointerException.class)
+    public void testCheckXPathFunctionResolver02(XPath xpath) throws XPathExpressionException {
+        xpath.setXPathFunctionResolver((functionName, arity) -> null);
+        assertEquals(xpath.evaluate(null, "5"), "2");
+    }
+    /*
+     Check that NPE is thrown when expression is null.
+     */
+
+    @Test(dataProvider = "xpath", expectedExceptions = NullPointerException.class)
+    public void test01(XPath xpath) throws XPathExpressionException {
+        double result = xpath.evaluateExpression(null, (Object) null, Double.class);
+    }
+
+    /*
+     Check that NPE is thrown when the class type is null.
+     */
+    @Test(dataProvider = "xpath", expectedExceptions = NullPointerException.class)
+    public void test02(XPath xpath) throws XPathExpressionException {
+        double result = xpath.evaluateExpression("1+1", (Object) null, null);
+    }
+
+    /*
+     Parameter item can be null when the expression does not depends on the
+     context.
+     */
+    @Test(dataProvider = "xpath")
+    public void test03(XPath xpath) throws XPathExpressionException {
+        int result = xpath.evaluateExpression("1+1", (Object) null, Integer.class);
+        assertTrue(result == 2);
+    }
+
+    /*
+     * Test return type: boolean.
+     */
+    @Test(dataProvider = "document")
+    public void test04(XPath xpath, Document doc) throws XPathExpressionException {
+        boolean result1 = xpath.evaluateExpression("boolean(/Customers/Customer[@id=3])", doc, Boolean.class);
+        assertTrue(result1);
+    }
+
+    /*
+     * Test return type: numeric. Subtypes supported: Double, Integer and Long
+     */
+    @Test(dataProvider = "document")
+    public void test05(XPath xpath, Document doc) throws XPathExpressionException {
+        double result1 = xpath.evaluateExpression("count(/Customers/Customer)", doc, Double.class);
+        assertTrue(result1 == 3.0);
+        int result2 = xpath.evaluateExpression("count(/Customers/Customer)", doc, Integer.class);
+        assertTrue(result2 == 3);
+        long result3 = xpath.evaluateExpression("count(/Customers/Customer)", doc, Long.class);
+        assertTrue(result3 == 3);
+    }
+
+    /*
+     * Test return type: numeric.  Of the subtypes of Number, only Double,
+     * Integer and Long are required.
+     */
+    @Test(dataProvider = "invalidNumericTypes", expectedExceptions = IllegalArgumentException.class)
+    public void test06(XPath xpath, Class<Number> type) throws XPathExpressionException {
+        xpath.evaluateExpression("1+1", (Object) null, type);
+    }
+
+    /*
+     * Test return type: String.
+     */
+    @Test(dataProvider = "document")
+    public void test07(XPath xpath, Document doc) throws XPathExpressionException {
+        String result1 = xpath.evaluateExpression("string(/Customers/Customer[@id=3]/Phone/text())", doc, String.class);
+        assertTrue(result1.equals("3333333333"));
+    }
+
+    /*
+     * Test return type: NodeSet.
+     */
+    @Test(dataProvider = "document")
+    public void test08(XPath xpath, Document doc) throws XPathExpressionException {
+        XPathNodes nodes = xpath.evaluateExpression("/Customers/Customer", doc, XPathNodes.class);
+        assertTrue(nodes.size() == 3);
+        for (Node n : nodes) {
+            assertEquals(n.getLocalName(), "Customer");
+        }
+    }
+
+    /*
+     * Test return type: Node.
+     */
+    @Test(dataProvider = "document")
+    public void test09(XPath xpath, Document doc) throws XPathExpressionException {
+        Node n = xpath.evaluateExpression("/Customers/Customer[@id=3]", doc, Node.class);
+        assertEquals(n.getLocalName(), "Customer");
+    }
+
+    /*
+     * Test return type: Unsupported type.
+     */
+    @Test(dataProvider = "document", expectedExceptions = IllegalArgumentException.class)
+    public void test10(XPath xpath, Document doc) throws XPathExpressionException {
+        File n = xpath.evaluateExpression("/Customers/Customer[@id=3]", doc, File.class);
+    }
+
+    /*
+     * Test return type: Any::Boolean.
+     */
+    @Test(dataProvider = "document")
+    public void test11(XPath xpath, Document doc) throws XPathExpressionException {
+        XPathEvaluationResult<?> result = xpath.evaluateExpression("boolean(/Customers/Customer[@id=3])", doc);
+        verifyResult(result, true);
+    }
+
+    /*
+     * Test return type: Any::Number.
+     */
+    @Test(dataProvider = "document")
+    public void test12(XPath xpath, Document doc) throws XPathExpressionException {
+        XPathEvaluationResult<?> result = xpath.evaluateExpression("count(/Customers/Customer)", doc);
+        verifyResult(result, 3.0);
+    }
+
+    /*
+     * Test return type: Any::String.
+     */
+    @Test(dataProvider = "document")
+    public void test13(XPath xpath, Document doc) throws XPathExpressionException {
+        XPathEvaluationResult<?> result = xpath.evaluateExpression(
+                "string(/Customers/Customer[@id=3]/Phone/text())", doc, XPathEvaluationResult.class);
+        verifyResult(result, "3333333333");
+    }
+
+    /*
+     * Test return type: Any::Nodeset.
+     */
+    @Test(dataProvider = "document")
+    public void test14(XPath xpath, Document doc) throws XPathExpressionException {
+        XPathEvaluationResult<?> result = xpath.evaluateExpression("/Customers/Customer", doc);
+        verifyResult(result, "Customer");
+    }
+
+    /*
+     * Test return type: Any::Node.
+     */
+    @Test(dataProvider = "document")
+    public void test15(XPath xpath, Document doc) throws XPathExpressionException {
+        XPathEvaluationResult<?> result = xpath.evaluateExpression("/Customers/Customer[@id=3]", doc);
+        verifyResult(result, "Customer");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/javax/xml/xpath/XPathExpAnyTypeTest.java	Tue Jan 27 22:01:46 2015 -0800
@@ -0,0 +1,176 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package javax.xml.xpath;
+
+import java.io.File;
+import javax.xml.xpath.*;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+import org.testng.annotations.Test;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+
+/*
+ * @bug 8054196
+ * @summary Test for the project XPath: support any type. This test covers the new
+ * evaluateExpression methods of XPathExpression.
+ */
+public class XPathExpAnyTypeTest extends XPathTestBase {
+
+    /*
+     * Check that NPE is thrown when the class type is null.
+     */
+    @Test(dataProvider = "xpath", expectedExceptions = NullPointerException.class)
+    public void test02(XPath xpath) throws XPathExpressionException {
+        XPathExpression exp = xpath.compile("1+1");
+        double result = exp.evaluateExpression((Object)null, null);
+    }
+
+    /*
+     * Parameter item can be null when the expression does not depends on the
+     * context.
+     */
+    @Test(dataProvider = "xpath")
+    public void test03(XPath xpath) throws XPathExpressionException {
+        XPathExpression exp = xpath.compile("1+1");
+        int result = exp.evaluateExpression((Object)null, Integer.class);
+        assertTrue(result == 2);
+    }
+
+    /*
+     * Test return type: boolean.
+     */
+    @Test(dataProvider = "document")
+    public void test04(XPath xpath, Document doc) throws XPathExpressionException {
+        XPathExpression exp = xpath.compile("boolean(/Customers/Customer[@id=3])");
+        boolean result1 = exp.evaluateExpression(doc, Boolean.class);
+        assertTrue(result1);
+    }
+
+    /*
+     * Test return type: numeric.
+     */
+    @Test(dataProvider = "document")
+    public void test05(XPath xpath, Document doc) throws XPathExpressionException {
+        XPathExpression exp = xpath.compile("count(/Customers/Customer)");
+        double result1 = exp.evaluateExpression(doc, Double.class);
+        assertTrue(result1 == 3.0);
+
+        int result2 = exp.evaluateExpression(doc, Integer.class);
+        assertTrue(result2 == 3);
+    }
+
+    /*
+     * Test return type: String.
+     */
+    @Test(dataProvider = "document")
+    public void test06(XPath xpath, Document doc) throws XPathExpressionException {
+        XPathExpression exp = xpath.compile("string(/Customers/Customer[@id=3]/Phone/text())");
+        String result1 = exp.evaluateExpression(doc, String.class);
+        assertTrue(result1.equals("3333333333"));
+    }
+
+    /*
+     * Test return type: NodeSet.
+     */
+    @Test(dataProvider = "document")
+    public void test07(XPath xpath, Document doc) throws XPathExpressionException {
+        XPathExpression exp = xpath.compile("/Customers/Customer");
+        XPathNodes nodes = exp.evaluateExpression(doc, XPathNodes.class);
+        assertTrue(nodes.size() == 3);
+        for (Node n : nodes) {
+            assertEquals(n.getLocalName(), "Customer");
+        }
+    }
+
+    /*
+     * Test return type: Node.
+     */
+    @Test(dataProvider = "document")
+    public void test08(XPath xpath, Document doc) throws XPathExpressionException {
+        XPathExpression exp = xpath.compile("/Customers/Customer[@id=3]");
+        Node n = exp.evaluateExpression(doc, Node.class);
+        assertEquals(n.getLocalName(), "Customer");
+    }
+
+    /*
+     * Test return type: Unsupported type.
+     */
+    @Test(dataProvider = "document", expectedExceptions = IllegalArgumentException.class)
+    public void test09(XPath xpath, Document doc) throws XPathExpressionException {
+        XPathExpression exp = xpath.compile("/Customers/Customer[@id=3]");
+        File n = exp.evaluateExpression(doc, File.class);
+    }
+
+    /*
+     * Test return type: Any::Boolean.
+     */
+    @Test(dataProvider = "document")
+    public void test10(XPath xpath, Document doc) throws XPathExpressionException {
+        XPathExpression exp = xpath.compile("boolean(/Customers/Customer[@id=3])");
+        XPathEvaluationResult<?> result = exp.evaluateExpression(doc);
+        verifyResult(result, true);
+    }
+
+    /*
+     * Test return type: Any::Number.
+     */
+    @Test(dataProvider = "document")
+    public void test11(XPath xpath, Document doc) throws XPathExpressionException {
+        XPathExpression exp = xpath.compile("count(/Customers/Customer)");
+        XPathEvaluationResult<?> result = exp.evaluateExpression(doc);
+        verifyResult(result, 3.0);
+    }
+
+    /*
+     * Test return type: Any::String.
+     */
+    @Test(dataProvider = "document")
+    public void test12(XPath xpath, Document doc) throws XPathExpressionException {
+        XPathExpression exp = xpath.compile("string(/Customers/Customer[@id=3]/Phone/text())");
+        XPathEvaluationResult<?> result = exp.evaluateExpression(doc, XPathEvaluationResult.class);
+        verifyResult(result, "3333333333");
+    }
+
+    /*
+     * Test return type: Any::Nodeset.
+     */
+    @Test(dataProvider = "document")
+    public void test13(XPath xpath, Document doc) throws XPathExpressionException {
+        XPathExpression exp = xpath.compile("/Customers/Customer");
+        XPathEvaluationResult<?> result = exp.evaluateExpression(doc);
+        verifyResult(result, "Customer");
+    }
+
+    /*
+     * Test return type: Any::Node.
+     */
+    @Test(dataProvider = "document")
+    public void test14(XPath xpath, Document doc) throws XPathExpressionException {
+        XPathExpression exp = xpath.compile("/Customers/Customer[@id=3]");
+        XPathEvaluationResult<?> result = exp.evaluateExpression(doc);
+        verifyResult(result, "Customer");
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/javax/xml/xpath/XPathTestBase.java	Tue Jan 27 22:01:46 2015 -0800
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package javax.xml.xpath;
+
+import java.io.ByteArrayInputStream;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicLong;
+import javax.xml.parsers.DocumentBuilderFactory;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+import org.testng.annotations.DataProvider;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+
+/*
+ * Base class for XPath test
+ */
+class XPathTestBase {
+
+    static final String rawXML
+            = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"
+            + "<Customers>"
+            + "    <Customer id=\"1\">"
+            + "        <Name>name1</Name>"
+            + "        <Phone>1111111111</Phone>"
+            + "        <Email>123@xyz.com</Email>"
+            + "        <Address>"
+            + "            <Street>1111 111st ave</Street>"
+            + "            <City>The City</City>"
+            + "            <State>The State</State>"
+            + "        </Address>"
+            + "    </Customer>"
+            + "    <Customer id=\"2\">"
+            + "        <Name>name1</Name>"
+            + "        <Phone>2222222222</Phone>"
+            + "        <Email>123@xyz.com</Email>"
+            + "        <Address>"
+            + "            <Street>2222 222nd ave</Street>"
+            + "            <City>The City</City>"
+            + "            <State>The State</State>"
+            + "        </Address>"
+            + "    </Customer>"
+            + "    <Customer id=\"3\">"
+            + "        <Name>name1</Name>"
+            + "        <Phone>3333333333</Phone>"
+            + "        <Email>123@xyz.com</Email>"
+            + "        <Address>"
+            + "            <Street>3333 333rd ave</Street>"
+            + "            <City>The City</City>"
+            + "            <State>The State</State>"
+            + "        </Address>"
+            + "    </Customer>"
+            + "</Customers>";
+
+    void verifyResult(XPathEvaluationResult<?> result, Object expected) {
+        switch (result.type()) {
+            case BOOLEAN:
+                assertTrue(((Boolean) result.value()).equals(expected));
+                return;
+            case NUMBER:
+                assertTrue(((Double) result.value()).equals(expected));
+                return;
+            case STRING:
+                assertTrue(((String) result.value()).equals(expected));
+                return;
+            case NODESET:
+                XPathNodes nodes = (XPathNodes) result.value();
+                for (Node n : nodes) {
+                    assertEquals(n.getLocalName(), expected);
+                }
+                return;
+            case NODE:
+                assertTrue(((Node) result.value()).getLocalName().equals(expected));
+                return;
+        }
+        assertFalse(true, "Unsupported type");
+    }
+
+    /*
+     * DataProvider: XPath object
+     */
+    @DataProvider(name = "xpath")
+    Object[][] getXPath() {
+        return new Object[][]{{XPathFactory.newInstance().newXPath()}};
+    }
+
+    /*
+     * DataProvider: Numeric types not supported
+     */
+    @DataProvider(name = "invalidNumericTypes")
+    Object[][] getInvalidNumericTypes() {
+        XPath xpath = XPathFactory.newInstance().newXPath();
+        return new Object[][]{{xpath, AtomicInteger.class},
+            {xpath, AtomicInteger.class},
+            {xpath, AtomicLong.class},
+            {xpath, BigDecimal.class},
+            {xpath, BigInteger.class},
+            {xpath, Byte.class},
+            {xpath, Float.class},
+            {xpath, Short.class}
+        };
+    }
+
+    /*
+     * DataProvider: XPath and Document objects
+     */
+    @DataProvider(name = "document")
+    Object[][] getDocument() throws Exception {
+        DocumentBuilderFactory dBF = DocumentBuilderFactory.newInstance();
+        dBF.setValidating(false);
+        dBF.setNamespaceAware(true);
+        Document doc = dBF.newDocumentBuilder().parse(
+                new ByteArrayInputStream(rawXML.getBytes("UTF-8")));
+
+        return new Object[][]{{XPathFactory.newInstance().newXPath(), doc}};
+    }
+}