Added test cases for each .proto file to ensure
[controller.git] / opendaylight / md-sal / sal-protocolbuffer-encoding / src / main / java / org / opendaylight / controller / cluster / datastore / node / NodeToNormalizedNodeBuilder.java
index b0ba487177b7d1004b08d5645661c8d76ac55614..03d632b61fb7070d568e360bcd7494ed40c59041 100644 (file)
@@ -1,3 +1,13 @@
+/*
+ *
+ *  Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ *  This program and the accompanying materials are made available under the
+ *  terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ *  and is available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ */
+
 package org.opendaylight.controller.cluster.datastore.node;
 
 import com.google.common.base.Preconditions;
@@ -8,14 +18,17 @@ import org.opendaylight.controller.cluster.datastore.node.utils.NodeIdentifierFa
 import org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages.Node;
 import org.opendaylight.yangtools.concepts.Identifiable;
 import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.AugmentationIdentifier;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifierWithPredicates;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeWithValue;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeWithValue;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode;
 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodeContainer;
 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
@@ -48,7 +61,7 @@ import static com.google.common.base.Preconditions.checkArgument;
 /**
  * NormalizedNodeBuilder is a builder that walks through a tree like structure and constructs a
  * NormalizedNode from it.
- *
+ * <p/>
  * A large part of this code has been copied over from a similar class in sal-common-impl which was
  * originally supposed to convert a CompositeNode to NormalizedNode
  *
@@ -57,694 +70,787 @@ import static com.google.common.base.Preconditions.checkArgument;
 public abstract class NodeToNormalizedNodeBuilder<T extends PathArgument>
     implements Identifiable<T> {
 
-  private final T identifier;
+    private final T identifier;
 
-  protected static final Logger logger = LoggerFactory
-      .getLogger(NodeToNormalizedNodeBuilder.class);
+    protected static final Logger logger = LoggerFactory
+        .getLogger(NodeToNormalizedNodeBuilder.class);
 
-  @Override
-  public T getIdentifier() {
-    return identifier;
-  };
+    @Override
+    public T getIdentifier() {
+        return identifier;
+    }
 
-  protected NodeToNormalizedNodeBuilder(final T identifier) {
-    super();
-    this.identifier = identifier;
+    ;
 
-  }
+    protected NodeToNormalizedNodeBuilder(final T identifier) {
+        super();
+        this.identifier = identifier;
 
-  /**
-   *
-   * @return Should return true if the node that this operation corresponds to is a mixin
-   */
-  public boolean isMixin() {
-    return false;
-  }
+    }
 
+    /**
+     * @return Should return true if the node that this operation corresponds to is a mixin
+     */
+    public boolean isMixin() {
+        return false;
+    }
 
-  /**
-   *
-   * @return Should return true if the node that this operation corresponds to has a 'key'
-   *         associated with it. This is typically true for a list-item or leaf-list entry in yang
-   */
-  public boolean isKeyedEntry() {
-    return false;
-  }
 
-  protected Set<QName> getQNameIdentifiers() {
-    return Collections.singleton(identifier.getNodeType());
-  }
+    /**
+     * @return Should return true if the node that this operation corresponds to has a 'key'
+     * associated with it. This is typically true for a list-item or leaf-list entry in yang
+     */
+    public boolean isKeyedEntry() {
+        return false;
+    }
 
-  public abstract NodeToNormalizedNodeBuilder<?> getChild(
-      final PathArgument child);
+    protected Set<QName> getQNameIdentifiers() {
+        return Collections.singleton(identifier.getNodeType());
+    }
 
-  public abstract NodeToNormalizedNodeBuilder<?> getChild(QName child);
+    public abstract NodeToNormalizedNodeBuilder<?> getChild(
+        final PathArgument child);
 
-  public abstract NormalizedNode<?, ?> normalize(QName nodeType, Node node);
+    public abstract NodeToNormalizedNodeBuilder<?> getChild(QName child);
 
+    public abstract NormalizedNode<?, ?> normalize(QName nodeType, Node node);
 
 
-  private static abstract class SimpleTypeNormalization<T extends PathArgument>
-      extends NodeToNormalizedNodeBuilder<T> {
 
-    protected SimpleTypeNormalization(final T identifier) {
-      super(identifier);
-    }
+    private static abstract class SimpleTypeNormalization<T extends PathArgument>
+        extends NodeToNormalizedNodeBuilder<T> {
 
-    @Override
-    public NormalizedNode<?, ?> normalize(final QName nodeType, final Node node) {
-      checkArgument(node != null);
-      return normalizeImpl(nodeType, node);
-    }
+        protected SimpleTypeNormalization(final T identifier) {
+            super(identifier);
+        }
 
-    protected abstract NormalizedNode<?, ?> normalizeImpl(QName nodeType,
-        Node node);
+        @Override
+        public NormalizedNode<?, ?> normalize(final QName nodeType,
+            final Node node) {
+            checkArgument(node != null);
+            return normalizeImpl(nodeType, node);
+        }
 
-    @Override
-    public NodeToNormalizedNodeBuilder<?> getChild(final PathArgument child) {
-      return null;
-    }
+        protected abstract NormalizedNode<?, ?> normalizeImpl(QName nodeType,
+            Node node);
 
-    @Override
-    public NodeToNormalizedNodeBuilder<?> getChild(final QName child) {
-      return null;
-    }
+        @Override
+        public NodeToNormalizedNodeBuilder<?> getChild(
+            final PathArgument child) {
+            return null;
+        }
+
+        @Override
+        public NodeToNormalizedNodeBuilder<?> getChild(final QName child) {
+            return null;
+        }
+
+        @Override
+        public NormalizedNode<?, ?> createDefault(
+            final PathArgument currentArg) {
+            // TODO Auto-generated method stub
+            return null;
+        }
 
-    @Override
-    public NormalizedNode<?, ?> createDefault(final PathArgument currentArg) {
-      // TODO Auto-generated method stub
-      return null;
     }
 
-  }
 
-  private static final class LeafNormalization extends
-      SimpleTypeNormalization<NodeIdentifier> {
+    private static final class LeafNormalization extends
+        SimpleTypeNormalization<NodeIdentifier> {
 
-    protected LeafNormalization(final NodeIdentifier identifier) {
-      super(identifier);
-    }
+        private final LeafSchemaNode schema;
 
-    @Override
-    protected NormalizedNode<?, ?> normalizeImpl(final QName nodeType,
-        final Node node) {
-      return ImmutableNodes.leafNode(nodeType, node.getValue());
+        protected LeafNormalization(final LeafSchemaNode schema, final NodeIdentifier identifier) {
+            super(identifier);
+            this.schema = schema;
+        }
+
+        @Override
+        protected NormalizedNode<?, ?> normalizeImpl(final QName nodeType,
+            final Node node) {
+            Object value = NodeValueCodec.toTypeSafeValue(this.schema, this.schema.getType(), node);
+            return ImmutableNodes.leafNode(nodeType, value);
+
+        }
 
     }
 
-  }
 
-  private static final class LeafListEntryNormalization extends
-      SimpleTypeNormalization<NodeWithValue> {
+    private static final class LeafListEntryNormalization extends
+        SimpleTypeNormalization<NodeWithValue> {
 
-    public LeafListEntryNormalization(final LeafListSchemaNode potential) {
-      super(new NodeWithValue(potential.getQName(), null));
-    }
+        private final LeafListSchemaNode schema;
 
-    @Override
-    protected NormalizedNode<?, ?> normalizeImpl(final QName nodeType,
-        final Node node) {
-      final Object data = node.getValue();
-      if (data == null) {
-        Preconditions.checkArgument(false,
-            "No data available in leaf list entry for " + nodeType);
-      }
-      NodeWithValue nodeId = new NodeWithValue(nodeType, data);
-      return Builders.leafSetEntryBuilder().withNodeIdentifier(nodeId)
-          .withValue(data).build();
-    }
+        public LeafListEntryNormalization(final LeafListSchemaNode potential) {
+            super(new NodeWithValue(potential.getQName(), null));
+            this.schema = potential;
+        }
 
+        @Override
+        protected NormalizedNode<?, ?> normalizeImpl(final QName nodeType,
+            final Node node) {
+            final Object data = node.getValue();
+            if (data == null) {
+                Preconditions.checkArgument(false,
+                    "No data available in leaf list entry for " + nodeType);
+            }
 
-    @Override
-    public boolean isKeyedEntry() {
-      return true;
-    }
-  }
+            Object value = NodeValueCodec.toTypeSafeValue(this.schema, this.schema.getType(), node);
 
-  private static abstract class NodeToNormalizationNodeOperation<T extends PathArgument>
-      extends NodeToNormalizedNodeBuilder<T> {
+            NodeWithValue nodeId = new NodeWithValue(nodeType, value);
+            return Builders.leafSetEntryBuilder().withNodeIdentifier(nodeId)
+                .withValue(value).build();
+        }
 
-    protected NodeToNormalizationNodeOperation(final T identifier) {
-      super(identifier);
-    }
 
-    @SuppressWarnings({"rawtypes", "unchecked"})
-    @Override
-    public final NormalizedNodeContainer<?, ?, ?> normalize(
-        final QName nodeType, final Node node) {
-      checkArgument(node != null);
-
-      if (!node.getType().equals(AugmentationNode.class.getSimpleName())&& !node.getType().equals(ContainerNode.class.getSimpleName())) {
-        checkArgument(nodeType != null);
-      }
-
-      NormalizedNodeContainerBuilder builder = createBuilder(node);
-
-      Set<NodeToNormalizedNodeBuilder<?>> usedMixins = new HashSet<>();
-
-      logNode(node);
-
-      if (node.getChildCount() == 0 && !node.getType().equals(ContainerNode.class.getSimpleName())) {
-        PathArgument childPathArgument =
-            NodeIdentifierFactory.getArgument(node.getPath());
-        NormalizedNode child = null;
-        if (childPathArgument instanceof NodeWithValue) {
-          final NodeWithValue nodeWithValue =
-              new NodeWithValue(childPathArgument.getNodeType(),
-                  node.getValue());
-          child =
-              Builders.leafSetEntryBuilder().withNodeIdentifier(nodeWithValue)
-                  .withValue(node.getValue()).build();
-        } else {
-          child =
-              ImmutableNodes.leafNode(childPathArgument.getNodeType(),
-                  node.getValue());
+        @Override
+        public boolean isKeyedEntry() {
+            return true;
         }
-        builder.addChild(child);
-      }
+    }
 
-      final List<Node> children = node.getChildList();
-      for (Node nodeChild : children) {
 
-        PathArgument childPathArgument =
-            NodeIdentifierFactory.getArgument(nodeChild.getPath());
+    private static abstract class NodeToNormalizationNodeOperation<T extends PathArgument>
+        extends NodeToNormalizedNodeBuilder<T> {
 
-        QName childNodeType = null;
-        NodeToNormalizedNodeBuilder childOp = null;
+        protected NodeToNormalizationNodeOperation(final T identifier) {
+            super(identifier);
+        }
 
+        @SuppressWarnings({"rawtypes", "unchecked"})
+        @Override
+        public final NormalizedNodeContainer<?, ?, ?> normalize(
+            final QName nodeType, final Node node) {
+            checkArgument(node != null);
+
+            if (!node.getType().equals(AugmentationNode.class.getSimpleName())
+                && !node.getType().equals(ContainerNode.class.getSimpleName())
+                && !node.getType().equals(MapNode.class.getSimpleName())) {
+                checkArgument(nodeType != null);
+            }
+
+            NormalizedNodeContainerBuilder builder = createBuilder(node);
+
+            Set<NodeToNormalizedNodeBuilder<?>> usedMixins = new HashSet<>();
+
+            logNode(node);
+
+            if (node.getChildCount() == 0 && (
+                node.getType().equals(LeafSetEntryNode.class.getSimpleName())
+                    || node.getType().equals(LeafNode.class.getSimpleName()))) {
+                PathArgument childPathArgument =
+                    NodeIdentifierFactory.getArgument(node.getPath());
+
+                final NormalizedNode child;
+                if (childPathArgument instanceof NodeWithValue) {
+                    final NodeWithValue nodeWithValue =
+                        new NodeWithValue(childPathArgument.getNodeType(),
+                            node.getValue());
+                    child =
+                        Builders.leafSetEntryBuilder()
+                            .withNodeIdentifier(nodeWithValue)
+                            .withValue(node.getValue()).build();
+                } else {
+                    child =
+                        ImmutableNodes.leafNode(childPathArgument.getNodeType(),
+                            node.getValue());
+                }
+                builder.addChild(child);
+            }
+
+            final List<Node> children = node.getChildList();
+            for (Node nodeChild : children) {
+
+                PathArgument childPathArgument =
+                    NodeIdentifierFactory.getArgument(nodeChild.getPath());
+
+                QName childNodeType = null;
+                NodeToNormalizedNodeBuilder childOp = null;
+
+                if (childPathArgument instanceof AugmentationIdentifier) {
+                    childOp = getChild(childPathArgument);
+                    checkArgument(childOp instanceof AugmentationNormalization, childPathArgument);
+                } else {
+                    childNodeType = childPathArgument.getNodeType();
+                    childOp = getChild(childNodeType);
+                }
+                // We skip unknown nodes if this node is mixin since
+                // it's nodes and parent nodes are interleaved
+                if (childOp == null && isMixin()) {
+                    continue;
+                } else if (childOp == null) {
+                    logger.error(
+                        "childOp is null and this operation is not a mixin : this = {}",
+                        this.toString());
+                }
+
+                checkArgument(childOp != null,
+                    "Node %s is not allowed inside %s",
+                    childNodeType, getIdentifier());
+
+                if (childOp.isMixin()) {
+                    if (usedMixins.contains(childOp)) {
+                        // We already run / processed that mixin, so to avoid
+                        // duplicate we are
+                        // skipping next nodes.
+                        continue;
+                    }
+                    // builder.addChild(childOp.normalize(nodeType, treeCacheNode));
+                    final NormalizedNode childNode =
+                        childOp.normalize(childNodeType, nodeChild);
+                    if (childNode != null)
+                        builder.addChild(childNode);
+                    usedMixins.add(childOp);
+                } else {
+                    final NormalizedNode childNode =
+                        childOp.normalize(childNodeType, nodeChild);
+                    if (childNode != null)
+                        builder.addChild(childNode);
+                }
+            }
+
+
+            try {
+                return (NormalizedNodeContainer<?, ?, ?>) builder.build();
+            } catch (Exception e) {
+                return null;
+            }
 
-        if (childPathArgument instanceof AugmentationIdentifier) {
-          childOp = getChild(childPathArgument);
-        } else {
-          childNodeType = childPathArgument.getNodeType();
-          childOp = getChild(childNodeType);
-        }
-        // We skip unknown nodes if this node is mixin since
-        // it's nodes and parent nodes are interleaved
-        if (childOp == null && isMixin()) {
-          continue;
-        } else if (childOp == null) {
-          logger.error(
-              "childOp is null and this operation is not a mixin : this = {}",
-              this.toString());
-        }
-
-        checkArgument(childOp != null, "Node %s is not allowed inside %s",
-            childNodeType, getIdentifier());
-        if (childOp.isMixin()) {
-          if (usedMixins.contains(childOp)) {
-            // We already run / processed that mixin, so to avoid
-            // duplicate we are
-            // skiping next nodes.
-            continue;
-          }
-          // builder.addChild(childOp.normalize(nodeType, treeCacheNode));
-          final NormalizedNode childNode =
-              childOp.normalize(childNodeType, nodeChild);
-          if (childNode != null)
-            builder.addChild(childNode);
-          usedMixins.add(childOp);
-        } else {
-          final NormalizedNode childNode =
-              childOp.normalize(childNodeType, nodeChild);
-          if (childNode != null)
-            builder.addChild(childNode);
         }
-      }
 
+        private void logNode(Node node) {
+            //let us find out the type of the node
+            logger.debug("We got a {} , with identifier {} with {} children",
+                node.getType(), node.getPath(),
+                node.getChildList());
+        }
 
-      try {
-        return (NormalizedNodeContainer<?, ?, ?>) builder.build();
-      } catch (Exception e) {
-        return null;
-      }
+        @SuppressWarnings("rawtypes")
+        protected abstract NormalizedNodeContainerBuilder createBuilder(
+            final Node node);
 
     }
 
-    private void logNode(Node node) {
-      //let us find out the type of the node
-      logger.debug("We got a {} , with identifier {} with {} children", node.getType(),node.getPath(),
-                   node.getChildList());
-    }
 
-    @SuppressWarnings("rawtypes")
-    protected abstract NormalizedNodeContainerBuilder createBuilder(
-        final Node node);
+    private static abstract class DataContainerNormalizationOperation<T extends PathArgument>
+        extends NodeToNormalizationNodeOperation<T> {
 
-  }
+        private final DataNodeContainer schema;
+        private final Map<QName, NodeToNormalizedNodeBuilder<?>> byQName;
+        private final Map<PathArgument, NodeToNormalizedNodeBuilder<?>> byArg;
 
-  private static abstract class DataContainerNormalizationOperation<T extends PathArgument>
-      extends NodeToNormalizationNodeOperation<T> {
+        protected DataContainerNormalizationOperation(final T identifier,
+            final DataNodeContainer schema) {
+            super(identifier);
+            this.schema = schema;
+            this.byArg = new ConcurrentHashMap<>();
+            this.byQName = new ConcurrentHashMap<>();
+        }
 
-    private final DataNodeContainer schema;
-    private final Map<QName, NodeToNormalizedNodeBuilder<?>> byQName;
-    private final Map<PathArgument, NodeToNormalizedNodeBuilder<?>> byArg;
+        @Override
+        public NodeToNormalizedNodeBuilder<?> getChild(
+            final PathArgument child) {
+            NodeToNormalizedNodeBuilder<?> potential = byArg.get(child);
+            if (potential != null) {
+                return potential;
+            }
+            potential = fromSchema(schema, child);
+            return register(potential);
+        }
 
-    protected DataContainerNormalizationOperation(final T identifier,
-        final DataNodeContainer schema) {
-      super(identifier);
-      this.schema = schema;
-      this.byArg = new ConcurrentHashMap<>();
-      this.byQName = new ConcurrentHashMap<>();
-    }
+        @Override
+        public NodeToNormalizedNodeBuilder<?> getChild(final QName child) {
+            if (child == null) {
+                return null;
+            }
+
+            NodeToNormalizedNodeBuilder<?> potential = byQName.get(child);
+            if (potential != null) {
+                return potential;
+            }
+            potential = fromSchemaAndPathArgument(schema, child);
+            return register(potential);
+        }
 
-    @Override
-    public NodeToNormalizedNodeBuilder<?> getChild(final PathArgument child) {
-      NodeToNormalizedNodeBuilder<?> potential = byArg.get(child);
-      if (potential != null) {
-        return potential;
-      }
-      potential = fromSchema(schema, child);
-      return register(potential);
-    }
+        private NodeToNormalizedNodeBuilder<?> register(
+            final NodeToNormalizedNodeBuilder<?> potential) {
+            if (potential != null) {
+                byArg.put(potential.getIdentifier(), potential);
+                for (QName qName : potential.getQNameIdentifiers()) {
+                    byQName.put(qName, potential);
+                }
+            }
+            return potential;
+        }
 
-    @Override
-    public NodeToNormalizedNodeBuilder<?> getChild(final QName child) {
-      if (child == null) {
-        return null;
-      }
-
-      NodeToNormalizedNodeBuilder<?> potential = byQName.get(child);
-      if (potential != null) {
-        return potential;
-      }
-      potential = fromSchemaAndPathArgument(schema, child);
-      return register(potential);
     }
 
-    private NodeToNormalizedNodeBuilder<?> register(
-        final NodeToNormalizedNodeBuilder<?> potential) {
-      if (potential != null) {
-        byArg.put(potential.getIdentifier(), potential);
-        for (QName qName : potential.getQNameIdentifiers()) {
-          byQName.put(qName, potential);
+
+    private static final class ListItemNormalization extends
+        DataContainerNormalizationOperation<NodeIdentifierWithPredicates> {
+
+        private final List<QName> keyDefinition;
+        private final ListSchemaNode schemaNode;
+
+        protected ListItemNormalization(
+            final NodeIdentifierWithPredicates identifier,
+            final ListSchemaNode schema) {
+            super(identifier, schema);
+            this.schemaNode = schema;
+            keyDefinition = schema.getKeyDefinition();
         }
-      }
-      return potential;
-    }
 
-  }
+        @Override
+        protected NormalizedNodeContainerBuilder createBuilder(
+            final Node node) {
+            NodeIdentifierWithPredicates nodeIdentifierWithPredicates =
+                (NodeIdentifierWithPredicates) NodeIdentifierFactory
+                    .createPathArgument(node
+                        .getPath(), schemaNode);
+            return Builders.mapEntryBuilder()
+                .withNodeIdentifier(
+                    nodeIdentifierWithPredicates
+            );
+        }
 
-  private static final class ListItemNormalization extends
-      DataContainerNormalizationOperation<NodeIdentifierWithPredicates> {
+        @Override
+        public NormalizedNode<?, ?> createDefault(
+            final PathArgument currentArg) {
+            DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode>
+                builder =
+                Builders.mapEntryBuilder().withNodeIdentifier(
+                    (NodeIdentifierWithPredicates) currentArg);
+            for (Entry<QName, Object> keyValue : ((NodeIdentifierWithPredicates) currentArg)
+                .getKeyValues().entrySet()) {
+                if (keyValue.getValue() == null) {
+                    throw new NullPointerException(
+                        "Null value found for path : "
+                            + currentArg);
+                }
+                builder.addChild(Builders.leafBuilder()
+                    //
+                    .withNodeIdentifier(new NodeIdentifier(keyValue.getKey()))
+                    .withValue(keyValue.getValue()).build());
+            }
+            return builder.build();
+        }
 
-    private final List<QName> keyDefinition;
-    private final ListSchemaNode schemaNode;
 
-    protected ListItemNormalization(
-        final NodeIdentifierWithPredicates identifier,
-        final ListSchemaNode schema) {
-      super(identifier, schema);
-      this.schemaNode = schema;
-      keyDefinition = schema.getKeyDefinition();
+        @Override
+        public boolean isKeyedEntry() {
+            return true;
+        }
     }
 
-    @Override
-    protected NormalizedNodeContainerBuilder createBuilder(final Node node) {
-      return Builders.mapEntryBuilder().withNodeIdentifier(
-          (NodeIdentifierWithPredicates) NodeIdentifierFactory.getArgument(node
-              .getPath()));
-    }
 
-    @Override
-    public NormalizedNode<?, ?> createDefault(final PathArgument currentArg) {
-      DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> builder =
-          Builders.mapEntryBuilder().withNodeIdentifier(
-              (NodeIdentifierWithPredicates) currentArg);
-      for (Entry<QName, Object> keyValue : ((NodeIdentifierWithPredicates) currentArg)
-          .getKeyValues().entrySet()) {
-        if (keyValue.getValue() == null) {
-          throw new NullPointerException("Null value found for path : "
-              + currentArg);
-        }
-        builder.addChild(Builders.leafBuilder()
-            //
-            .withNodeIdentifier(new NodeIdentifier(keyValue.getKey()))
-            .withValue(keyValue.getValue()).build());
-      }
-      return builder.build();
-    }
+    private static final class ContainerNormalization extends
+        DataContainerNormalizationOperation<NodeIdentifier> {
 
+        protected ContainerNormalization(final ContainerSchemaNode schema) {
+            super(new NodeIdentifier(schema.getQName()), schema);
+        }
 
-    @Override
-    public boolean isKeyedEntry() {
-      return true;
-    }
-  }
+        @Override
+        protected NormalizedNodeContainerBuilder createBuilder(
+            final Node node) {
+            return Builders.containerBuilder()
+                .withNodeIdentifier(getIdentifier());
+        }
 
-  private static final class ContainerNormalization extends
-      DataContainerNormalizationOperation<NodeIdentifier> {
+        @Override
+        public NormalizedNode<?, ?> createDefault(
+            final PathArgument currentArg) {
+            return Builders.containerBuilder()
+                .withNodeIdentifier((NodeIdentifier) currentArg).build();
+        }
 
-    protected ContainerNormalization(final ContainerSchemaNode schema) {
-      super(new NodeIdentifier(schema.getQName()), schema);
     }
 
-    @Override
-    protected NormalizedNodeContainerBuilder createBuilder(final Node node) {
-      return Builders.containerBuilder().withNodeIdentifier(getIdentifier());
-    }
 
-    @Override
-    public NormalizedNode<?, ?> createDefault(final PathArgument currentArg) {
-      return Builders.containerBuilder()
-          .withNodeIdentifier((NodeIdentifier) currentArg).build();
-    }
+    private static abstract class MixinNormalizationOp<T extends PathArgument>
+        extends NodeToNormalizationNodeOperation<T> {
 
-  }
+        protected MixinNormalizationOp(final T identifier) {
+            super(identifier);
+        }
 
-  private static abstract class MixinNormalizationOp<T extends PathArgument>
-      extends NodeToNormalizationNodeOperation<T> {
+        @Override
+        public final boolean isMixin() {
+            return true;
+        }
 
-    protected MixinNormalizationOp(final T identifier) {
-      super(identifier);
     }
 
-    @Override
-    public final boolean isMixin() {
-      return true;
-    }
 
-  }
+    private static final class LeafListMixinNormalization extends
+        MixinNormalizationOp<NodeIdentifier> {
 
-  private static final class LeafListMixinNormalization extends
-      MixinNormalizationOp<NodeIdentifier> {
+        private final NodeToNormalizedNodeBuilder<?> innerOp;
 
-    private final NodeToNormalizedNodeBuilder<?> innerOp;
+        public LeafListMixinNormalization(final LeafListSchemaNode potential) {
+            super(new NodeIdentifier(potential.getQName()));
+            innerOp = new LeafListEntryNormalization(potential);
+        }
 
-    public LeafListMixinNormalization(final LeafListSchemaNode potential) {
-      super(new NodeIdentifier(potential.getQName()));
-      innerOp = new LeafListEntryNormalization(potential);
-    }
+        @Override
+        protected NormalizedNodeContainerBuilder createBuilder(
+            final Node node) {
+            return Builders.leafSetBuilder()
+                .withNodeIdentifier(getIdentifier());
+        }
 
-    @Override
-    protected NormalizedNodeContainerBuilder createBuilder(
-        final Node node) {
-      return Builders.leafSetBuilder().withNodeIdentifier(getIdentifier());
-    }
+        @Override
+        public NormalizedNode<?, ?> createDefault(
+            final PathArgument currentArg) {
+            return Builders.leafSetBuilder().withNodeIdentifier(getIdentifier())
+                .build();
+        }
 
-    @Override
-    public NormalizedNode<?, ?> createDefault(final PathArgument currentArg) {
-      return Builders.leafSetBuilder().withNodeIdentifier(getIdentifier())
-          .build();
-    }
+        @Override
+        public NodeToNormalizedNodeBuilder<?> getChild(
+            final PathArgument child) {
+            if (child instanceof NodeWithValue) {
+                return innerOp;
+            }
+            return null;
+        }
 
-    @Override
-    public NodeToNormalizedNodeBuilder<?> getChild(final PathArgument child) {
-      if (child instanceof NodeWithValue) {
-        return innerOp;
-      }
-      return null;
-    }
+        @Override
+        public NodeToNormalizedNodeBuilder<?> getChild(final QName child) {
+            if (getIdentifier().getNodeType().equals(child)) {
+                return innerOp;
+            }
+            return null;
+        }
 
-    @Override
-    public NodeToNormalizedNodeBuilder<?> getChild(final QName child) {
-      if (getIdentifier().getNodeType().equals(child)) {
-        return innerOp;
-      }
-      return null;
     }
 
-  }
 
-  private static final class AugmentationNormalization extends
-      MixinNormalizationOp<AugmentationIdentifier> {
+    private static final class AugmentationNormalization extends
+        MixinNormalizationOp<AugmentationIdentifier> {
 
-    private final Map<QName, NodeToNormalizedNodeBuilder<?>> byQName;
-    private final Map<PathArgument, NodeToNormalizedNodeBuilder<?>> byArg;
+        private final Map<QName, NodeToNormalizedNodeBuilder<?>> byQName;
+        private final Map<PathArgument, NodeToNormalizedNodeBuilder<?>> byArg;
 
-    public AugmentationNormalization(final AugmentationSchema augmentation,
-        final DataNodeContainer schema) {
-      super(augmentationIdentifierFrom(augmentation));
+        public AugmentationNormalization(final AugmentationSchema augmentation,
+            final DataNodeContainer schema) {
+            super(augmentationIdentifierFrom(augmentation));
 
-      ImmutableMap.Builder<QName, NodeToNormalizedNodeBuilder<?>> byQNameBuilder =
-          ImmutableMap.builder();
-      ImmutableMap.Builder<PathArgument, NodeToNormalizedNodeBuilder<?>> byArgBuilder =
-          ImmutableMap.builder();
+            ImmutableMap.Builder<QName, NodeToNormalizedNodeBuilder<?>>
+                byQNameBuilder =
+                ImmutableMap.builder();
+            ImmutableMap.Builder<PathArgument, NodeToNormalizedNodeBuilder<?>>
+                byArgBuilder =
+                ImmutableMap.builder();
+
+            for (DataSchemaNode augNode : augmentation.getChildNodes()) {
+                DataSchemaNode resolvedNode =
+                    schema.getDataChildByName(augNode.getQName());
+                NodeToNormalizedNodeBuilder<?> resolvedOp =
+                    fromDataSchemaNode(resolvedNode);
+                byArgBuilder.put(resolvedOp.getIdentifier(), resolvedOp);
+                for (QName resQName : resolvedOp.getQNameIdentifiers()) {
+                    byQNameBuilder.put(resQName, resolvedOp);
+                }
+            }
+            byQName = byQNameBuilder.build();
+            byArg = byArgBuilder.build();
 
-      for (DataSchemaNode augNode : augmentation.getChildNodes()) {
-        DataSchemaNode resolvedNode =
-            schema.getDataChildByName(augNode.getQName());
-        NodeToNormalizedNodeBuilder<?> resolvedOp =
-            fromDataSchemaNode(resolvedNode);
-        byArgBuilder.put(resolvedOp.getIdentifier(), resolvedOp);
-        for (QName resQName : resolvedOp.getQNameIdentifiers()) {
-          byQNameBuilder.put(resQName, resolvedOp);
         }
-      }
-      byQName = byQNameBuilder.build();
-      byArg = byArgBuilder.build();
 
-    }
+        @Override
+        public NodeToNormalizedNodeBuilder<?> getChild(
+            final PathArgument child) {
+            return byArg.get(child);
+        }
 
-    @Override
-    public NodeToNormalizedNodeBuilder<?> getChild(final PathArgument child) {
-      return byArg.get(child);
-    }
+        @Override
+        public NodeToNormalizedNodeBuilder<?> getChild(final QName child) {
+            return byQName.get(child);
+        }
 
-    @Override
-    public NodeToNormalizedNodeBuilder<?> getChild(final QName child) {
-      return byQName.get(child);
-    }
+        @Override
+        protected Set<QName> getQNameIdentifiers() {
+            return getIdentifier().getPossibleChildNames();
+        }
 
-    @Override
-    protected Set<QName> getQNameIdentifiers() {
-      return getIdentifier().getPossibleChildNames();
-    }
+        @SuppressWarnings("rawtypes")
+        @Override
+        protected NormalizedNodeContainerBuilder createBuilder(
+            final Node node) {
+            return Builders.augmentationBuilder()
+                .withNodeIdentifier(getIdentifier());
+        }
 
-    @SuppressWarnings("rawtypes")
-    @Override
-    protected NormalizedNodeContainerBuilder createBuilder(final Node node) {
-      return Builders.augmentationBuilder().withNodeIdentifier(getIdentifier());
-    }
+        @Override
+        public NormalizedNode<?, ?> createDefault(
+            final PathArgument currentArg) {
+            return Builders.augmentationBuilder()
+                .withNodeIdentifier(getIdentifier())
+                .build();
+        }
 
-    @Override
-    public NormalizedNode<?, ?> createDefault(final PathArgument currentArg) {
-      return Builders.augmentationBuilder().withNodeIdentifier(getIdentifier())
-          .build();
     }
 
-  }
 
-  private static final class ListMixinNormalization extends
-      MixinNormalizationOp<NodeIdentifier> {
+    private static final class ListMixinNormalization extends
+        MixinNormalizationOp<NodeIdentifier> {
 
-    private final ListItemNormalization innerNode;
+        private final ListItemNormalization innerNode;
 
-    public ListMixinNormalization(final ListSchemaNode list) {
-      super(new NodeIdentifier(list.getQName()));
-      this.innerNode =
-          new ListItemNormalization(new NodeIdentifierWithPredicates(
-              list.getQName(), Collections.<QName, Object>emptyMap()), list);
-    }
+        public ListMixinNormalization(final ListSchemaNode list) {
+            super(new NodeIdentifier(list.getQName()));
+            this.innerNode =
+                new ListItemNormalization(new NodeIdentifierWithPredicates(
+                    list.getQName(), Collections.<QName, Object>emptyMap()),
+                    list);
+        }
 
-    @SuppressWarnings("rawtypes")
-    @Override
-    protected NormalizedNodeContainerBuilder createBuilder(
-        final Node node) {
-      return Builders.mapBuilder().withNodeIdentifier(getIdentifier());
-    }
+        @SuppressWarnings("rawtypes")
+        @Override
+        protected NormalizedNodeContainerBuilder createBuilder(
+            final Node node) {
+            return Builders.mapBuilder().withNodeIdentifier(getIdentifier());
+        }
 
-    @Override
-    public NormalizedNode<?, ?> createDefault(final PathArgument currentArg) {
-      return Builders.mapBuilder().withNodeIdentifier(getIdentifier()).build();
-    }
+        @Override
+        public NormalizedNode<?, ?> createDefault(
+            final PathArgument currentArg) {
+            return Builders.mapBuilder().withNodeIdentifier(getIdentifier())
+                .build();
+        }
 
-    @Override
-    public NodeToNormalizedNodeBuilder<?> getChild(final PathArgument child) {
-      if (child.getNodeType().equals(getIdentifier().getNodeType())) {
-        return innerNode;
-      }
-      return null;
-    }
+        @Override
+        public NodeToNormalizedNodeBuilder<?> getChild(
+            final PathArgument child) {
+            if (child.getNodeType().equals(getIdentifier().getNodeType())) {
+                return innerNode;
+            }
+            return null;
+        }
 
-    @Override
-    public NodeToNormalizedNodeBuilder<?> getChild(final QName child) {
-      if (getIdentifier().getNodeType().equals(child)) {
-        return innerNode;
-      }
-      return null;
-    }
+        @Override
+        public NodeToNormalizedNodeBuilder<?> getChild(final QName child) {
+            if (getIdentifier().getNodeType().equals(child)) {
+                return innerNode;
+            }
+            return null;
+        }
 
-  }
-
-  private static class ChoiceNodeNormalization extends
-      MixinNormalizationOp<NodeIdentifier> {
-
-    private final ImmutableMap<QName, NodeToNormalizedNodeBuilder<?>> byQName;
-    private final ImmutableMap<PathArgument, NodeToNormalizedNodeBuilder<?>> byArg;
-
-    protected ChoiceNodeNormalization(
-        final org.opendaylight.yangtools.yang.model.api.ChoiceNode schema) {
-      super(new NodeIdentifier(schema.getQName()));
-      ImmutableMap.Builder<QName, NodeToNormalizedNodeBuilder<?>> byQNameBuilder =
-          ImmutableMap.builder();
-      ImmutableMap.Builder<PathArgument, NodeToNormalizedNodeBuilder<?>> byArgBuilder =
-          ImmutableMap.builder();
-
-      for (ChoiceCaseNode caze : schema.getCases()) {
-        for (DataSchemaNode cazeChild : caze.getChildNodes()) {
-          NodeToNormalizedNodeBuilder<?> childOp =
-              fromDataSchemaNode(cazeChild);
-          byArgBuilder.put(childOp.getIdentifier(), childOp);
-          for (QName qname : childOp.getQNameIdentifiers()) {
-            byQNameBuilder.put(qname, childOp);
-          }
-        }
-      }
-      byQName = byQNameBuilder.build();
-      byArg = byArgBuilder.build();
     }
 
-    @Override
-    public NodeToNormalizedNodeBuilder<?> getChild(final PathArgument child) {
-      return byArg.get(child);
-    }
 
-    @Override
-    public NodeToNormalizedNodeBuilder<?> getChild(final QName child) {
-      return byQName.get(child);
-    }
+    private static class ChoiceNodeNormalization extends
+        MixinNormalizationOp<NodeIdentifier> {
+
+        private final ImmutableMap<QName, NodeToNormalizedNodeBuilder<?>>
+            byQName;
+        private final ImmutableMap<PathArgument, NodeToNormalizedNodeBuilder<?>>
+            byArg;
+
+        protected ChoiceNodeNormalization(
+            final org.opendaylight.yangtools.yang.model.api.ChoiceNode schema) {
+            super(new NodeIdentifier(schema.getQName()));
+            ImmutableMap.Builder<QName, NodeToNormalizedNodeBuilder<?>>
+                byQNameBuilder =
+                ImmutableMap.builder();
+            ImmutableMap.Builder<PathArgument, NodeToNormalizedNodeBuilder<?>>
+                byArgBuilder =
+                ImmutableMap.builder();
+
+            for (ChoiceCaseNode caze : schema.getCases()) {
+                for (DataSchemaNode cazeChild : caze.getChildNodes()) {
+                    NodeToNormalizedNodeBuilder<?> childOp =
+                        fromDataSchemaNode(cazeChild);
+                    byArgBuilder.put(childOp.getIdentifier(), childOp);
+                    for (QName qname : childOp.getQNameIdentifiers()) {
+                        byQNameBuilder.put(qname, childOp);
+                    }
+                }
+            }
+            byQName = byQNameBuilder.build();
+            byArg = byArgBuilder.build();
+        }
 
-    @Override
-    protected NormalizedNodeContainerBuilder createBuilder(final Node node) {
-      return Builders.choiceBuilder().withNodeIdentifier(getIdentifier());
-    }
+        @Override
+        public NodeToNormalizedNodeBuilder<?> getChild(
+            final PathArgument child) {
+            return byArg.get(child);
+        }
 
-    @Override
-    public NormalizedNode<?, ?> createDefault(final PathArgument currentArg) {
-      return Builders.choiceBuilder().withNodeIdentifier(getIdentifier())
-          .build();
-    }
-  }
-
-  public static NodeToNormalizedNodeBuilder<?> fromSchemaAndPathArgument(
-      final DataNodeContainer schema, final QName child) {
-    DataSchemaNode potential = schema.getDataChildByName(child);
-    if (potential == null) {
-      Iterable<org.opendaylight.yangtools.yang.model.api.ChoiceNode> choices =
-          FluentIterable.from(schema.getChildNodes()).filter(
-              org.opendaylight.yangtools.yang.model.api.ChoiceNode.class);
-      potential = findChoice(choices, child);
-    }
-    if (potential == null) {
-      if (logger.isTraceEnabled()) {
-        logger.trace("BAD CHILD = {}", child.toString());
-      }
-    }
+        @Override
+        public NodeToNormalizedNodeBuilder<?> getChild(final QName child) {
+            return byQName.get(child);
+        }
 
-    checkArgument(potential != null,
-        "Supplied QName %s is not valid according to schema %s", child, schema);
-    if ((schema instanceof DataSchemaNode)
-        && !((DataSchemaNode) schema).isAugmenting()
-        && potential.isAugmenting()) {
-      return fromAugmentation(schema, (AugmentationTarget) schema, potential);
-    }
-    return fromDataSchemaNode(potential);
-  }
-
-  /**
-   * Given a bunch of choice nodes and a the name of child find a choice node for that child which
-   * has a non-null value
-   *
-   * @param choices
-   * @param child
-   * @return
-   */
-  private static org.opendaylight.yangtools.yang.model.api.ChoiceNode findChoice(
-      final Iterable<org.opendaylight.yangtools.yang.model.api.ChoiceNode> choices,
-      final QName child) {
-    org.opendaylight.yangtools.yang.model.api.ChoiceNode foundChoice = null;
-    choiceLoop: for (org.opendaylight.yangtools.yang.model.api.ChoiceNode choice : choices) {
-      for (ChoiceCaseNode caze : choice.getCases()) {
-        if (caze.getDataChildByName(child) != null) {
-          foundChoice = choice;
-          break choiceLoop;
-        }
-      }
-    }
-    return foundChoice;
-  }
-
-
-  /**
-   * Create an AugmentationIdentifier based on the AugmentationSchema
-   *
-   * @param augmentation
-   * @return
-   */
-  public static AugmentationIdentifier augmentationIdentifierFrom(
-      final AugmentationSchema augmentation) {
-    ImmutableSet.Builder<QName> potentialChildren = ImmutableSet.builder();
-    for (DataSchemaNode child : augmentation.getChildNodes()) {
-      potentialChildren.add(child.getQName());
-    }
-    return new AugmentationIdentifier(null, potentialChildren.build());
-  }
-
-  /**
-   * Create an AugmentationNormalization based on the schema of the DataContainer, the
-   * AugmentationTarget and the potential schema node
-   *
-   * @param schema
-   * @param augments
-   * @param potential
-   * @return
-   */
-  private static AugmentationNormalization fromAugmentation(
-      final DataNodeContainer schema, final AugmentationTarget augments,
-      final DataSchemaNode potential) {
-    AugmentationSchema augmentation = null;
-    for (AugmentationSchema aug : augments.getAvailableAugmentations()) {
-      DataSchemaNode child = aug.getDataChildByName(potential.getQName());
-      if (child != null) {
-        augmentation = aug;
-        break;
-      }
+        @Override
+        protected NormalizedNodeContainerBuilder createBuilder(
+            final Node node) {
+            return Builders.choiceBuilder().withNodeIdentifier(getIdentifier());
+        }
 
+        @Override
+        public NormalizedNode<?, ?> createDefault(
+            final PathArgument currentArg) {
+            return Builders.choiceBuilder().withNodeIdentifier(getIdentifier())
+                .build();
+        }
     }
-    if (augmentation != null) {
-      return new AugmentationNormalization(augmentation, schema);
-    } else {
-      return null;
+
+    /**
+     * Find an appropriate NormalizedNodeBuilder using both the schema and the
+     * Path Argument
+     *
+     * @param schema
+     * @param child
+     * @return
+     */
+    public static NodeToNormalizedNodeBuilder<?> fromSchemaAndPathArgument(
+        final DataNodeContainer schema, final QName child) {
+        DataSchemaNode potential = schema.getDataChildByName(child);
+        if (potential == null) {
+            Iterable<org.opendaylight.yangtools.yang.model.api.ChoiceNode>
+                choices =
+                FluentIterable.from(schema.getChildNodes()).filter(
+                    org.opendaylight.yangtools.yang.model.api.ChoiceNode.class);
+            potential = findChoice(choices, child);
+        }
+        if (potential == null) {
+            if (logger.isTraceEnabled()) {
+                logger.trace("BAD CHILD = {}", child.toString());
+            }
+        }
+
+        checkArgument(potential != null,
+            "Supplied QName %s is not valid according to schema %s", child,
+            schema);
+
+        // If the schema in an instance of DataSchemaNode and the potential
+        // is augmenting something then there is a chance that this may be
+        // and augmentation node
+        if ((schema instanceof DataSchemaNode)
+            && potential.isAugmenting()) {
+
+            AugmentationNormalization augmentation =
+                fromAugmentation(schema, (AugmentationTarget) schema,
+                    potential);
+
+            // If an augmentation normalization (builder) is not found then
+            // we fall through to the regular processing
+            if(augmentation != null){
+                return augmentation;
+            }
+        }
+        return fromDataSchemaNode(potential);
+    }
+
+    /**
+     * Given a bunch of choice nodes and a the name of child find a choice node for that child which
+     * has a non-null value
+     *
+     * @param choices
+     * @param child
+     * @return
+     */
+    private static org.opendaylight.yangtools.yang.model.api.ChoiceNode findChoice(
+        final Iterable<org.opendaylight.yangtools.yang.model.api.ChoiceNode> choices,
+        final QName child) {
+        org.opendaylight.yangtools.yang.model.api.ChoiceNode foundChoice = null;
+        choiceLoop:
+        for (org.opendaylight.yangtools.yang.model.api.ChoiceNode choice : choices) {
+            for (ChoiceCaseNode caze : choice.getCases()) {
+                if (caze.getDataChildByName(child) != null) {
+                    foundChoice = choice;
+                    break choiceLoop;
+                }
+            }
+        }
+        return foundChoice;
     }
-  }
-
-  /**
-   *
-   * @param schema
-   * @param child
-   * @return
-   */
-  private static NodeToNormalizedNodeBuilder<?> fromSchema(
-      final DataNodeContainer schema, final PathArgument child) {
-    if (child instanceof AugmentationIdentifier) {
-      return fromSchemaAndPathArgument(schema, ((AugmentationIdentifier) child)
-          .getPossibleChildNames().iterator().next());
+
+
+    /**
+     * Create an AugmentationIdentifier based on the AugmentationSchema
+     *
+     * @param augmentation
+     * @return
+     */
+    public static AugmentationIdentifier augmentationIdentifierFrom(
+        final AugmentationSchema augmentation) {
+        ImmutableSet.Builder<QName> potentialChildren = ImmutableSet.builder();
+        for (DataSchemaNode child : augmentation.getChildNodes()) {
+            potentialChildren.add(child.getQName());
+        }
+        return new AugmentationIdentifier(potentialChildren.build());
+    }
+
+    /**
+     * Create an AugmentationNormalization based on the schema of the DataContainer, the
+     * AugmentationTarget and the potential schema node
+     *
+     * @param schema
+     * @param augments
+     * @param potential
+     * @return
+     */
+    private static AugmentationNormalization fromAugmentation(
+        final DataNodeContainer schema, final AugmentationTarget augments,
+        final DataSchemaNode potential) {
+        AugmentationSchema augmentation = null;
+        for (AugmentationSchema aug : augments.getAvailableAugmentations()) {
+            DataSchemaNode child = aug.getDataChildByName(potential.getQName());
+            if (child != null) {
+                augmentation = aug;
+                break;
+            }
+
+        }
+        if (augmentation != null) {
+            return new AugmentationNormalization(augmentation, schema);
+        } else {
+            return null;
+        }
     }
-    return fromSchemaAndPathArgument(schema, child.getNodeType());
-  }
-
-  public static NodeToNormalizedNodeBuilder<?> fromDataSchemaNode(
-      final DataSchemaNode potential) {
-    if (potential instanceof ContainerSchemaNode) {
-      return new ContainerNormalization((ContainerSchemaNode) potential);
-    } else if (potential instanceof ListSchemaNode) {
-      return new ListMixinNormalization((ListSchemaNode) potential);
-    } else if (potential instanceof LeafSchemaNode) {
-      return new LeafNormalization(new NodeIdentifier(potential.getQName()));
-    } else if (potential instanceof org.opendaylight.yangtools.yang.model.api.ChoiceNode) {
-      return new ChoiceNodeNormalization(
-          (org.opendaylight.yangtools.yang.model.api.ChoiceNode) potential);
-    } else if (potential instanceof LeafListSchemaNode) {
-      return new LeafListMixinNormalization((LeafListSchemaNode) potential);
+
+    /**
+     * @param schema
+     * @param child
+     * @return
+     */
+    private static NodeToNormalizedNodeBuilder<?> fromSchema(
+        final DataNodeContainer schema, final PathArgument child) {
+        if (child instanceof AugmentationIdentifier) {
+            QName childQName = ((AugmentationIdentifier) child)
+                .getPossibleChildNames().iterator().next();
+
+            return fromSchemaAndPathArgument(schema, childQName);
+        }
+        return fromSchemaAndPathArgument(schema, child.getNodeType());
+    }
+
+    public static NodeToNormalizedNodeBuilder<?> fromDataSchemaNode(
+        final DataSchemaNode potential) {
+        if (potential instanceof ContainerSchemaNode) {
+            return new ContainerNormalization((ContainerSchemaNode) potential);
+        } else if (potential instanceof ListSchemaNode) {
+            return new ListMixinNormalization((ListSchemaNode) potential);
+        } else if (potential instanceof LeafSchemaNode) {
+            return new LeafNormalization((LeafSchemaNode) potential,
+                new NodeIdentifier(potential.getQName()));
+        } else if (potential instanceof org.opendaylight.yangtools.yang.model.api.ChoiceNode) {
+            return new ChoiceNodeNormalization(
+                (org.opendaylight.yangtools.yang.model.api.ChoiceNode) potential);
+        } else if (potential instanceof LeafListSchemaNode) {
+            return new LeafListMixinNormalization(
+                (LeafListSchemaNode) potential);
+        }
+        return null;
     }
-    return null;
-  }
 
-  public static NodeToNormalizedNodeBuilder<?> from(final SchemaContext ctx) {
-    return new ContainerNormalization(ctx);
-  }
+    public static NodeToNormalizedNodeBuilder<?> from(final SchemaContext ctx) {
+        return new ContainerNormalization(ctx);
+    }
 
-  public abstract NormalizedNode<?, ?> createDefault(PathArgument currentArg);
+    public abstract NormalizedNode<?, ?> createDefault(PathArgument currentArg);
 
 }