private static Data copyDerefData(Data dereferencedData) {
   if (dereferencedData instanceof ApacheData) {
     // need to make a copy of the Data
     ApacheData ad = (ApacheData) dereferencedData;
     XMLSignatureInput xsi = ad.getXMLSignatureInput();
     if (xsi.isNodeSet()) {
       try {
         final Set s = xsi.getNodeSet();
         return new NodeSetData() {
           public Iterator iterator() {
             return s.iterator();
           }
         };
       } catch (Exception e) {
         // log a warning
         log.log(Level.WARNING, "cannot cache dereferenced data: " + e);
         return null;
       }
     } else if (xsi.isElement()) {
       return new DOMSubTreeData(xsi.getSubNode(), xsi.isExcludeComments());
     } else if (xsi.isOctetStream() || xsi.isByteArray()) {
       try {
         return new OctetStreamData(xsi.getOctetStream(), xsi.getSourceURI(), xsi.getMIMEType());
       } catch (IOException ioe) {
         // log a warning
         log.log(Level.WARNING, "cannot cache dereferenced data: " + ioe);
         return null;
       }
     }
   }
   return dereferencedData;
 }
 private static Element obtainRefrenceElement(XMLSignatureInput resource)
     throws CanonicalizationException, ParserConfigurationException, IOException, SAXException,
         KeyResolverException {
   Element e;
   if (resource.isElement()) {
     e = (Element) resource.getSubNode();
   } else if (resource.isNodeSet()) {
     // Retrieved resource is a nodeSet
     e = getDocumentElement(resource.getNodeSet());
   } else {
     // Retrieved resource is an inputStream
     byte inputBytes[] = resource.getBytes();
     e = getDocFromBytes(inputBytes);
     // otherwise, we parse the resource, create an Element and delegate
     if (log.isLoggable(java.util.logging.Level.FINE))
       log.log(java.util.logging.Level.FINE, "we have to parse " + inputBytes.length + " bytes");
   }
   return e;
 }