public YangInstanceIdentifier getInstanceIdentifierFromDocument(Document request)
     throws DocumentedException {
   XmlElement filterElement =
       XmlElement.fromDomDocument(request)
           .getOnlyChildElement(GET_CONFIG)
           .getOnlyChildElement(FILTER_NODE);
   return getInstanceIdentifierFromFilter(filterElement);
 }
  // FIXME move somewhere to util
  private static Map.Entry<Date, XmlElement> stripNotification(final NetconfMessage message) {
    final XmlElement xmlElement = XmlElement.fromDomDocument(message.getDocument());
    final List<XmlElement> childElements = xmlElement.getChildElements();
    Preconditions.checkArgument(
        childElements.size() == 2, "Unable to parse notification %s, unexpected format", message);

    final XmlElement eventTimeElement;
    final XmlElement notificationElement;

    if (childElements.get(0).getName().equals(EVENT_TIME)) {
      eventTimeElement = childElements.get(0);
      notificationElement = childElements.get(1);
    } else if (childElements.get(1).getName().equals(EVENT_TIME)) {
      eventTimeElement = childElements.get(1);
      notificationElement = childElements.get(0);
    } else {
      throw new IllegalArgumentException(
          "Notification payload does not contain " + EVENT_TIME + " " + message);
    }

    try {
      return new AbstractMap.SimpleEntry<>(
          EVENT_TIME_FORMAT.get().parse(eventTimeElement.getTextContent()), notificationElement);
    } catch (DocumentedException e) {
      throw new IllegalArgumentException(
          "Notification payload does not contain " + EVENT_TIME + " " + message);
    } catch (ParseException e) {
      LOG.warn(
          "Unable to parse event time from {}. Setting time to {}",
          eventTimeElement,
          NetconfNotification.UNKNOWN_EVENT_TIME,
          e);
      return new AbstractMap.SimpleEntry<>(
          NetconfNotification.UNKNOWN_EVENT_TIME, notificationElement);
    }
  }
  @Override
  public synchronized DOMRpcResult toRpcResult(final NetconfMessage message, final SchemaPath rpc) {
    final NormalizedNode<?, ?> normalizedNode;
    final QName rpcQName = rpc.getLastComponent();
    if (NetconfMessageTransformUtil.isDataRetrievalOperation(rpcQName)) {
      final Element xmlData = NetconfMessageTransformUtil.getDataSubtree(message.getDocument());
      final ContainerSchemaNode schemaForDataRead =
          NetconfMessageTransformUtil.createSchemaForDataRead(schemaContext);
      final ContainerNode dataNode;

      try {
        dataNode =
            parserFactory
                .getContainerNodeParser()
                .parse(Collections.singleton(xmlData), schemaForDataRead);
      } catch (IllegalArgumentException e) {
        throw new IllegalArgumentException(
            String.format("Failed to parse data response %s", xmlData), e);
      }

      normalizedNode =
          Builders.containerBuilder()
              .withNodeIdentifier(
                  new YangInstanceIdentifier.NodeIdentifier(
                      NetconfMessageTransformUtil.NETCONF_RPC_REPLY_QNAME))
              .withChild(dataNode)
              .build();
    } else {

      Map<QName, RpcDefinition> currentMappedRpcs = mappedRpcs;

      // Determine whether a base netconf operation is being invoked and also check if the device
      // exposed model for base netconf
      // If no, use pre built base netconf operations model
      final boolean needToUseBaseCtx = mappedRpcs.get(rpcQName) == null && isBaseRpc(rpcQName);
      if (needToUseBaseCtx) {
        currentMappedRpcs = MAPPED_BASE_RPCS;
      }

      final RpcDefinition rpcDefinition = currentMappedRpcs.get(rpcQName);
      Preconditions.checkArgument(
          rpcDefinition != null, "Unable to parse response of %s, the rpc is unknown", rpcQName);

      // In case no input for rpc is defined, we can simply construct the payload here
      if (rpcDefinition.getOutput() == null) {
        Preconditions.checkArgument(
            XmlElement.fromDomDocument(message.getDocument())
                .getOnlyChildElementWithSameNamespaceOptionally("ok")
                .isPresent(),
            "Unexpected content in response of rpc: %s, %s",
            rpcDefinition.getQName(),
            message);
        normalizedNode = null;
      } else {
        final Element element = message.getDocument().getDocumentElement();
        try {
          normalizedNode =
              parserFactory
                  .getContainerNodeParser()
                  .parse(Collections.singleton(element), rpcDefinition.getOutput());
        } catch (IllegalArgumentException e) {
          throw new IllegalArgumentException(
              String.format("Failed to parse RPC response %s", element), e);
        }
      }
    }
    return new DefaultDOMRpcResult(normalizedNode);
  }