public ClassDescriptor getReferenceDescriptor(DOMRecord xmlRecord) {
    ClassDescriptor returnDescriptor = referenceDescriptor;

    if (returnDescriptor == null) {
      // Try to find a descriptor based on the schema type
      String type =
          ((Element) xmlRecord.getDOM())
              .getAttributeNS(
                  javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI,
                  XMLConstants.SCHEMA_TYPE_ATTRIBUTE);

      if ((null != type) && type.length() > 0) {
        XPathFragment typeFragment = new XPathFragment(type);
        String namespaceURI = xmlRecord.resolveNamespacePrefix(typeFragment.getPrefix());
        typeFragment.setNamespaceURI(namespaceURI);

        returnDescriptor =
            xmlRecord.getUnmarshaller().getXMLContext().getDescriptorByGlobalType(typeFragment);

      } else {
        // try leaf element type
        QName leafType = ((XMLField) getField()).getLastXPathFragment().getLeafElementType();
        if (leafType != null) {
          XPathFragment frag = new XPathFragment();
          String xpath = leafType.getLocalPart();
          String uri = leafType.getNamespaceURI();
          if ((uri != null) && uri.length() > 0) {
            frag.setNamespaceURI(uri);
            String prefix =
                ((XMLDescriptor) getDescriptor())
                    .getNonNullNamespaceResolver()
                    .resolveNamespaceURI(uri);
            if ((prefix != null) && prefix.length() > 0) {
              xpath = prefix + XMLConstants.COLON + xpath;
            }
          }
          frag.setXPath(xpath);

          returnDescriptor =
              xmlRecord.getUnmarshaller().getXMLContext().getDescriptorByGlobalType(frag);
        }
      }
    }

    return returnDescriptor;
  }
  public Object getValueToWrite(
      Object value,
      Object parent,
      XMLRecord record,
      XMLField field,
      XMLField includeField,
      AbstractSession session) {
    XMLMarshaller marshaller = record.getMarshaller();
    Object element = value;
    boolean isAttribute = ((XMLField) getField()).getLastXPathFragment().isAttribute();
    if (getValueConverter() != null) {
      Converter converter = getValueConverter();
      if (converter instanceof XMLConverter) {
        element =
            ((XMLConverter) converter)
                .convertObjectValueToDataValue(element, session, record.getMarshaller());
      } else {
        element = converter.convertObjectValueToDataValue(element, session);
      }
    }

    if (isAttribute) {
      if (isSwaRef() && (marshaller.getAttachmentMarshaller() != null)) {
        // should be a DataHandler here
        try {
          String id =
              marshaller.getAttachmentMarshaller().addSwaRefAttachment((DataHandler) element);
          element = id;
        } catch (ClassCastException cce) {
          throw XMLMarshalException.invalidSwaRefAttribute(getAttributeClassification().getName());
        }
      } else {
        // inline case
        XMLBinaryDataHelper.EncodedData data =
            XMLBinaryDataHelper.getXMLBinaryDataHelper()
                .getBytesForBinaryValue(
                    element, record.getMarshaller(), mimeTypePolicy.getMimeType(parent));
        String base64Value =
            ((XMLConversionManager) session.getDatasourcePlatform().getConversionManager())
                .buildBase64StringFromBytes(data.getData());
        element = base64Value;
      }
    } else {
      if (record.isXOPPackage() && !isSwaRef() && !shouldInlineBinaryData()) {
        // write as attachment
        String c_id = XMLConstants.EMPTY_STRING;
        byte[] bytes = null;
        if ((getAttributeElementClass() == ClassConstants.ABYTE)
            || (getAttributeElementClass() == ClassConstants.APBYTE)) {
          if (getAttributeElementClass() == ClassConstants.ABYTE) {
            element =
                session
                    .getDatasourcePlatform()
                    .getConversionManager()
                    .convertObject(element, ClassConstants.APBYTE);
          }
          bytes = (byte[]) element;
          c_id =
              marshaller
                  .getAttachmentMarshaller()
                  .addMtomAttachment(
                      bytes,
                      0,
                      bytes.length,
                      this.mimeTypePolicy.getMimeType(parent),
                      field.getLastXPathFragment().getLocalName(),
                      field.getLastXPathFragment().getNamespaceURI());
        } else if (getAttributeElementClass()
            == XMLBinaryDataHelper.getXMLBinaryDataHelper().DATA_HANDLER) {
          c_id =
              marshaller
                  .getAttachmentMarshaller()
                  .addMtomAttachment(
                      (DataHandler) element,
                      field.getLastXPathFragment().getLocalName(),
                      field.getLastXPathFragment().getNamespaceURI());
          if (c_id == null) {
            XMLBinaryDataHelper.EncodedData data =
                XMLBinaryDataHelper.getXMLBinaryDataHelper()
                    .getBytesForBinaryValue(
                        element, marshaller, this.mimeTypePolicy.getMimeType(parent));
            bytes = data.getData();
          }
        } else {
          XMLBinaryDataHelper.EncodedData data =
              XMLBinaryDataHelper.getXMLBinaryDataHelper()
                  .getBytesForBinaryValue(
                      element, marshaller, this.mimeTypePolicy.getMimeType(parent));
          bytes = data.getData();
          c_id =
              marshaller
                  .getAttachmentMarshaller()
                  .addMtomAttachment(
                      bytes,
                      0,
                      bytes.length,
                      data.getMimeType(),
                      field.getLastXPathFragment().getLocalName(),
                      field.getLastXPathFragment().getNamespaceURI());
        }

        if (c_id == null) {
          element = bytes;
        } else {
          DOMRecord include = new DOMRecord(field.getLastXPathFragment().getLocalName());
          include.setSession(session);
          include.put(includeField, c_id);
          element = include;

          // Need to call setAttributeNS on the record, unless the xop prefix
          // is defined on the descriptor's resolver already
          NamespaceResolver resolver = ((XMLField) getField()).getNamespaceResolver();
          if (resolver == null || resolver.resolveNamespaceURI(XMLConstants.XOP_URL) == null) {
            resolver = new NamespaceResolver();
            resolver.put(XMLConstants.XOP_PREFIX, XMLConstants.XOP_URL);
            String xpath = XMLConstants.XOP_PREFIX + XMLConstants.COLON + INCLUDE;
            XMLField incField = new XMLField(xpath);
            incField.setNamespaceResolver(resolver);
            Object obj = include.getIndicatingNoEntry(incField);
            if (obj != null && obj instanceof DOMRecord) {
              if (((DOMRecord) obj).getDOM().getNodeType() == Node.ELEMENT_NODE) {
                ((Element) ((DOMRecord) obj).getDOM())
                    .setAttributeNS(
                        XMLConstants.XMLNS_URL,
                        XMLConstants.XMLNS + XMLConstants.COLON + XMLConstants.XOP_PREFIX,
                        XMLConstants.XOP_URL);
              }
            }
          }
        }
      } else if (isSwaRef() && (marshaller.getAttachmentMarshaller() != null)) {
        // element should be a data-handler
        try {
          String c_id =
              marshaller.getAttachmentMarshaller().addSwaRefAttachment((DataHandler) element);
          element = c_id;
        } catch (Exception ex) {
        }
      } else {
        // inline
        if (!((getAttributeElementClass() == ClassConstants.ABYTE)
            || (getAttributeElementClass() == ClassConstants.APBYTE))) {
          element =
              XMLBinaryDataHelper.getXMLBinaryDataHelper()
                  .getBytesForBinaryValue(
                      element, marshaller, this.mimeTypePolicy.getMimeType(parent))
                  .getData();
        }
      }
    }
    return element;
  }