public void handleMessage(Message message) {
    try {
      NSStack nsStack = new NSStack();
      nsStack.push();

      BindingOperationInfo operation =
          (BindingOperationInfo) message.getExchange().get(BindingOperationInfo.class.getName());

      assert operation.getName() != null;

      XMLStreamWriter xmlWriter = getXMLStreamWriter(message);

      List<MessagePartInfo> parts = null;

      if (!isRequestor(message)) {
        parts = operation.getOutput().getMessageParts();
        addOperationNode(nsStack, message, xmlWriter, true, operation);
      } else {
        parts = operation.getInput().getMessageParts();
        addOperationNode(nsStack, message, xmlWriter, false, operation);
      }

      MessageContentsList objs = MessageContentsList.getContentsList(message);
      if (objs == null) {
        return;
      }

      for (MessagePartInfo part : parts) {
        if (objs.hasValue(part)) {
          Object o = objs.get(part);
          if (o == null) {
            // WSI-BP R2211 - RPC/Lit parts are not allowed to be xsi:nil
            throw new Fault(
                new org.apache.cxf.common.i18n.Message(
                    "BP_2211_RPCLIT_CANNOT_BE_NULL", LOG, part.getConcreteName()));
          }
          // WSI-BP R2737  -RPC/LIG part name space is empty
          // part.setConcreteName(new QName("", part.getConcreteName().getLocalPart()));
        }
      }
      writeParts(message, message.getExchange(), operation, objs, parts);

      // Finishing the writing.
      xmlWriter.writeEndElement();
    } catch (XMLStreamException e) {
      throw new Fault(e);
    }
  }
  @Override
  protected void writeParts(
      Message message,
      Exchange exchange,
      BindingOperationInfo operation,
      MessageContentsList objs,
      List<MessagePartInfo> parts) {
    // TODO Auto-generated method stub
    OutputStream out = message.getContent(OutputStream.class);
    XMLStreamWriter origXmlWriter = message.getContent(XMLStreamWriter.class);
    Service service = exchange.getService();
    XMLStreamWriter xmlWriter = origXmlWriter;
    CachingXmlEventWriter cache = null;

    Object en = message.getContextualProperty(OUT_BUFFERING);
    boolean allowBuffer = true;
    boolean buffer = false;
    if (en != null) {
      buffer = Boolean.TRUE.equals(en) || "true".equals(en);
      allowBuffer = !(Boolean.FALSE.equals(en) || "false".equals(en));
    }
    // need to cache the events in case validation fails or buffering is enabled
    if (buffer || (allowBuffer && shouldValidate(message) && !isRequestor(message))) {
      cache = new CachingXmlEventWriter();
      try {
        cache.setNamespaceContext(origXmlWriter.getNamespaceContext());
      } catch (XMLStreamException e) {
        // ignorable, will just get extra namespace decls
      }
      xmlWriter = cache;
      out = null;
    }

    if (out != null
        && writeToOutputStream(message, operation.getBinding(), service)
        && !MessageUtils.isTrue(message.getContextualProperty(DISABLE_OUTPUTSTREAM_OPTIMIZATION))) {
      if (xmlWriter != null) {
        try {
          xmlWriter.writeCharacters("");
          xmlWriter.flush();
        } catch (XMLStreamException e) {
          throw new Fault(e);
        }
      }

      DataWriter<OutputStream> osWriter = getDataWriter(message, service, OutputStream.class);

      for (MessagePartInfo part : parts) {
        if (objs.hasValue(part)) {
          Object o = objs.get(part);
          osWriter.write(o, part, out);
        }
      }
    } else {
      DataWriter<XMLStreamWriter> dataWriter = new CustomDataWriter(prismContext);

      for (MessagePartInfo part : parts) {
        if (objs.hasValue(part)) {
          Object o = objs.get(part);
          dataWriter.write(o, part, xmlWriter);
        }
      }
    }
    if (cache != null) {
      try {
        for (XMLEvent event : cache.getEvents()) {
          StaxUtils.writeEvent(event, origXmlWriter);
        }
      } catch (XMLStreamException e) {
        throw new Fault(e);
      }
    }
  }
  protected static List<Source> getPayloadBodyElements(Message message, Map<String, String> nsMap) {
    // take the namespace attribute from soap envelop
    Map<String, String> bodyNC = CastUtils.cast((Map<?, ?>) message.get("soap.body.ns.context"));
    if (bodyNC != null) {
      // if there is no Node and the addNamespaceContext option is enabled, this map is available
      nsMap.putAll(bodyNC);
    } else {
      Document soapEnv = (Document) message.getContent(Node.class);
      if (soapEnv != null) {
        NamedNodeMap attrs = soapEnv.getFirstChild().getAttributes();
        for (int i = 0; i < attrs.getLength(); i++) {
          Node node = attrs.item(i);
          if (!node.getNodeValue().equals(Soap11.SOAP_NAMESPACE)
              && !node.getNodeValue().equals(Soap12.SOAP_NAMESPACE)) {
            nsMap.put(node.getLocalName(), node.getNodeValue());
          }
        }
      }
    }
    MessageContentsList inObjects = MessageContentsList.getContentsList(message);
    if (inObjects == null) {
      return new ArrayList<Source>(0);
    }
    org.apache.cxf.message.Exchange exchange = message.getExchange();
    BindingOperationInfo boi = exchange.getBindingOperationInfo();

    OperationInfo op = boi.getOperationInfo();

    if (boi.isUnwrapped()) {
      op = boi.getWrappedOperation().getOperationInfo();
    }

    List<MessagePartInfo> partInfos = null;
    boolean client = Boolean.TRUE.equals(message.get(Message.REQUESTOR_ROLE));
    if (client) {
      // it is a response
      partInfos = op.getOutput().getMessageParts();

    } else {
      // it is a request
      partInfos = op.getInput().getMessageParts();
    }

    List<Source> answer = new ArrayList<Source>();

    for (MessagePartInfo partInfo : partInfos) {
      if (!inObjects.hasValue(partInfo)) {
        continue;
      }

      Object part = inObjects.get(partInfo);

      if (part instanceof Holder) {
        part = ((Holder<?>) part).value;
      }

      if (part instanceof Source) {
        Element element = null;
        if (part instanceof DOMSource) {
          element = getFirstElement(((DOMSource) part).getNode());
        }

        if (element != null) {
          addNamespace(element, nsMap);
          answer.add(new DOMSource(element));
        } else {
          answer.add((Source) part);
        }

        if (LOG.isTraceEnabled()) {
          LOG.trace("Extract body element {}", element == null ? "null" : getXMLString(element));
        }
      } else if (part instanceof Element) {
        addNamespace((Element) part, nsMap);
        answer.add(new DOMSource((Element) part));
      } else {
        if (LOG.isDebugEnabled()) {
          LOG.debug("Unhandled part type '{}'", part.getClass());
        }
      }
    }

    return answer;
  }