Merge "Migrate newer YANG Tools docs to rst"
authorColin Dixon <colin@colindixon.com>
Thu, 10 Nov 2016 17:43:40 +0000 (17:43 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Thu, 10 Nov 2016 17:43:40 +0000 (17:43 +0000)
docs/developer-guide/images/yang-data-api.png [new file with mode: 0644]
docs/developer-guide/images/yang-model-api.png [new file with mode: 0644]
docs/developer-guide/yang-tools.rst

diff --git a/docs/developer-guide/images/yang-data-api.png b/docs/developer-guide/images/yang-data-api.png
new file mode 100644 (file)
index 0000000..b8fe9f8
Binary files /dev/null and b/docs/developer-guide/images/yang-data-api.png differ
diff --git a/docs/developer-guide/images/yang-model-api.png b/docs/developer-guide/images/yang-model-api.png
new file mode 100644 (file)
index 0000000..80e0e1a
Binary files /dev/null and b/docs/developer-guide/images/yang-model-api.png differ
index b30175a7fb3ed5af88421d8d40d816c0a50683ca..9486121c587e53c3e68c7d4f44314948773a5823 100644 (file)
@@ -1,5 +1,5 @@
-YANG Tools
-==========
+YANG Tools Developer Guide
+==========================
 
 Overview
 --------
@@ -20,10 +20,6 @@ YANG Tools provides following features in OpenDaylight:
       uses conceptual meta-model more tailored to YANG and OpenDaylight
       use-cases than a standard XML DOM model allows for.
 
-   -  **Java Binding** - concrete data model and classes generated from
-      YANG models, designed to provide compile-time safety when working
-      with YANG-modeled data.
-
 -  serialization / deserialization of YANG-modeled data driven by YANG
    models
 
@@ -33,10 +29,10 @@ YANG Tools provides following features in OpenDaylight:
    -  JSON - as defined in
       `draft-lhotka-netmod-yang-json-01 <https://tools.ietf.org/html/rfc6020>`__
 
-   -  Java Binding to Normalized Node and vice-versa
+   -  support for third-party generators processing YANG models.
 
--  Integration of YANG model parsing into Maven build lifecycle and
-   support for third-party generators processing YANG models.
+Architecture
+~~~~~~~~~~~~
 
 YANG Tools project consists of following logical subsystems:
 
@@ -57,1217 +53,663 @@ YANG Tools project consists of following logical subsystems:
    components, which wants to generate code or other artefacts based on
    YANG model.
 
--  **YANG Java Binding** - Mapping of YANG model to generated Java APIs.
-   Java Binding also references to set of compile-time and runtime
-   components which implements this mapping, provides generation of
-   classes and APIs based on YANG models and integrate these Java
-   Binding objects with **YANG Data** APIs and components.
-
-   -  **Models** - Set of **IETF** and **YANG Tools** models, with
-      generated Java Bindings so they could be simply consumed outside
-      of **YANG Tools**.
-
-YANG Java Binding: Mapping rules
---------------------------------
-
-This chapter covers the details of mapping YANG to Java.
-
-.. note::
-
-    The following source code examples does not show canonical generated
-    code, but rather illustrative example. Generated classes and
-    interfaces may differ from this examples, but APIs are preserved.
-
-General conversion rules
-~~~~~~~~~~~~~~~~~~~~~~~~
-
-Package names of YANG models
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-| The package name consists of the following parts:
+Concepts
+~~~~~~~~
 
--  **Opendaylight prefix** - Specifies the opendaylight prefix. Every
-   package name starts with the prefix ``org.opendaylight.yang.gen.v``.
+Project defines base concepts and helper classes which are
+project-agnostic and could be used outside of YANG Tools project scope.
 
--  **Java Binding version** - Specifies the YANG Java Binding version.
-   Curent Binding version is ``1``.
+Components
+~~~~~~~~~~
 
--  **Namespace** - Specified by the value of ``namespace`` substatement.
-   URI is converted to package name structure.
+-  yang-common
 
--  **Revision** - Specifies the concatenation of word ``rev`` and value
-   of ``module`` substatements ``revision`` argument value without
-   leading zeros before month and day. For example: ``rev201379``
+-  yang-data-api
 
-After the package name is generated, we check if it contains any Java
-keywords or starts with a digit. If so, then we add an underscore before
-the offending token.
+-  yang-data-codec-gson
 
-The following is a list of keywords which are prefixed with underscore:
+-  yang-data-codec-xml
 
-abstract, assert, boolean, break, byte, case, catch, char, class, const,
-continue, default, double, do, else, enum, extends, false, final,
-finally, float, for, goto, if, implements, import, instanceof, int,
-interface, long, native, new, null, package, private, protected, public,
-return, short, static, strictfp, super, switch, synchronized, this,
-throw, throws, transient, true, try, void, volatile, while
+-  yang-data-impl
 
-As an example suppose following yang model:
+-  yang-data-jaxen
 
-.. code:: yang
-
-    module module {
-        namespace "urn:2:case#module";
-        prefix "sbd";
-        organization "OPEN DAYLIGHT";
-        contact "http://www.example.com/";
-        revision 2013-07-09 {
-        }
-    }
-
-After applying rules (replacing digits and Java keywords) the resulting
-package name is
-``org.opendaylight.yang.gen.v1.urn._2._case.module.rev201379``
-
-Additional Packages
-^^^^^^^^^^^^^^^^^^^
-
-In cases when YANG statement contain some of specific YANG statements
-additional packages are generated to designate this containment. Table
-below provides details of parent statement and nested statements, which
-yields additional package generation:
-
-+--------------------------------------+--------------------------------------+
-| Parent statement                     | Substatement                         |
-+======================================+======================================+
-| ``list``                             | list, container, choice              |
-+--------------------------------------+--------------------------------------+
-| ``container``                        | list, container, choice              |
-+--------------------------------------+--------------------------------------+
-| ``choice``                           | leaf, list, leaf-list, container,    |
-|                                      | case                                 |
-+--------------------------------------+--------------------------------------+
-| ``case``                             | list, container, choice              |
-+--------------------------------------+--------------------------------------+
-| rpc ``input`` or ``output``          | list, container, (choice isn’t       |
-|                                      | supported)                           |
-+--------------------------------------+--------------------------------------+
-| ``notification``                     | list, container, (choice isn’t       |
-|                                      | supported)                           |
-+--------------------------------------+--------------------------------------+
-| ``augment``                          | list, container, choice, case        |
-+--------------------------------------+--------------------------------------+
-
-Substatements are not only mapped to Java setter methods in the
-interface representing the parent statement, but they also generate
-packages with names consisting of the parent statement package name with
-the parent statement name appended.
-
-For example, this YANG model considers the container statement ``cont``
-as the direct substatement of the module.
-
-.. code:: yang
-
-    container cont {
-      container cont-inner {
-      }
-      list outter-list {
-        list list-in-list {
-        }
-      }
-    }
+-  yang-data-transform
 
-Container ``cont`` is the parent statement for the substatements
-``cont-inner`` and ``outter-list``. ``list outter-list`` is the parent
-statement for substatement ``list-in-list``.
+-  yang-data-util
 
-| Java code is generated in the following structure:
+-  yang-maven-plugin
 
--  ``org.opendaylight.yang.gen.v1.urn.module.rev201379`` - package
-   contains direct substatements of module statement
+-  yang-maven-plugin-it
 
-   -  ``Cont.java``
+-  yang-maven-plugin-spi
 
--  ``org.opendaylight.yang.gen.v1.urn.module.rev201379.cont`` - package
-   contains substatements of ``cont`` container statement
+-  yang-model-api
 
-   -  ``ContInner.java`` - interface representing container
-      ``cont-inner``
+-  yang-model-export
 
-   -  ``OutterList.java`` - interface representing list ``outer-list``
+-  yang-model-util
 
--  ``org.opendaylight.yang.gen.v1.urn.module.rev201379.cont.outter.list``
-   - package contains substatements of outter-list list element
+-  yang-parser-api
 
-   -  ``ListInList.java``
+-  yang-parser-impl
 
-Class and interface names
-^^^^^^^^^^^^^^^^^^^^^^^^^
+YANG Model API
+^^^^^^^^^^^^^^
 
-Some YANG statements are mapped to Java classes and interfaces. The name
-of YANG element may contain various characters which aren’t permitted in
-Java class names. Firstly whitespaces are trimmed from YANG name. Next
-the characters space, -, \` are deleted and the subsequent letter is
-capitalized. At the end, first letter is capitalized.
+Class diagram of yang model API
 
-For example, ``example-name_ without_capitalization`` would map to
-``ExampleNameWithoutCapitalization``.
+.. figure:: images/yang-model-api.png
 
-Getter and setter names
-^^^^^^^^^^^^^^^^^^^^^^^
+   YANG Model API
 
-In some cases, YANG statements are converted to getter and/or setter
-methods. The process for getter is:
+YANG Parser
+^^^^^^^^^^^
 
-1. the name of YANG statement is converted to Java class name style as
-   `explained above <#_class_and_interface_names>`__.
+Yang Statement Parser works on the idea of statement concepts as defined
+in RFC6020, section 6.3. We come up here with basic ModelStatement and
+StatementDefinition, following RFC6020 idea of having sequence of
+statements, where every statement contains keyword and zero or one
+argument. ModelStatement is extended by DeclaredStatement (as it comes
+from source, e.g. YANG source) and EffectiveStatement, which contains
+other substatements and tends to represent result of semantic processing
+of other statements (uses, augment for YANG). IdentifierNamespace
+represents common superclass for YANG model namespaces.
 
-2. the word ``get`` is added as prefix, if resulting type is
-   ``Boolean``, the name is prefixed with ``is`` prefix instead of
-   ``get``.
+Input of the Yang Statement Parser is a collection of
+StatementStreamSource objects. StatementStreamSource interface is used
+for inference of effective model and is required to emit its statements
+using supplied StatementWriter. Each source (e.g. YANG source) has to be
+processed in three steps in order to emit different statements for each
+step. This package provides support for various namespaces used across
+statement parser in order to map relations during declaration phase
+process.
 
-3. the return type of the getter method is set to Java type representing
-   substatement
+Currently, there are two implementations of StatementStreamSource in
+Yangtools:
 
-The process for setter is:
+-  YangStatementSourceImpl - intended for yang sources
 
-1. the name of YANG statement is converted to Java class name style as
-   `explained above <#_class_and_interface_names>`__.
+-  YinStatementSourceImpl - intended for yin sources
 
-2. the word ``set`` is added as prefix
+YANG Data API
+^^^^^^^^^^^^^
 
-3. the input parameter name is set to element’s name converted to Java
-   parameter style
+Class diagram of yang data API
 
-4. the return parameter is set to builder type
+.. figure:: images/yang-data-api.png
 
-Statement specific mapping
-~~~~~~~~~~~~~~~~~~~~~~~~~~
+   YANG Data API
 
-module statement
+YANG Data Codecs
 ^^^^^^^^^^^^^^^^
 
-YANG ``module`` statement is converted to Java as two Java classes. Each
-of the classes is in the separate Java file. The names of Java files are
-composed as follows: ``<module name><suffix>.java`` where ``<suffix>``
-is either data or service.
-
-Data Interface
-''''''''''''''
-
-Data Interface has a mapping similar to container, but contains only top
-level nodes defined in module.
-
-Data interface serves only as marker interface for type-safe APIs of
-``InstanceIdentifier``.
-
-Service Interface
-'''''''''''''''''
-
-Service Interface serves to describe RPC contract defined in the module.
-This RPC contract is defined by ``rpc`` statements.
-
-RPC implementation usually implement this interface and users of the
-RPCs use this interface to invoke RPCs.
-
-container statement
-^^^^^^^^^^^^^^^^^^^
+Codecs which enable serialization of NormalizedNodes into YANG-modeled
+data in XML or JSON format and deserialization of YANG-modeled data in
+XML or JSON format into NormalizedNodes.
 
-YANG containers are mapped to Java interfaces which extend the Java
-DataObject and Augmentable<container-interface>, where
-container-interface is the name of the mapped interface.
+YANG Maven Plugin
+^^^^^^^^^^^^^^^^^
 
-For example, the following YANG:
+Maven plugin which integrates YANG parser into Maven build lifecycle and
+provides code-generation framework for components, which wants to
+generate code or other artefacts based on YANG model.
 
-**YANG model.**
+How to / Tutorials
+------------------
 
-.. code:: yang
+Working with YANG Model
+~~~~~~~~~~~~~~~~~~~~~~~
 
-    container cont {
+First thing you need to do if you want to work with YANG models is to
+instantiate a SchemaContext object. This object type describes one or
+more parsed YANG modules.
 
-    }
+In order to create it you need to utilize YANG statement parser which
+takes one or more StatementStreamSource objects as input and then
+produces the SchemaContext object.
 
-is converted into this Java:
+StatementStreamSource object contains the source file information. It
+has two implementations, one for YANG sources - YangStatementSourceImpl,
+and one for YIN sources - YinStatementSourceImpl.
 
-**Cont.java.**
+Here is an example of creating StatementStreamSource objects for YANG
+files, providing them to the YANG statement parser and building the
+SchemaContext:
 
 .. code:: java
 
-    public interface Cont extends ChildOf<...>, Augmentable<Cont> {
-    }
+    StatementStreamSource yangModuleSource == new YangStatementSourceImpl("/example.yang", false);
+    StatementStreamSource yangModuleSource2 == new YangStatementSourceImpl("/example2.yang", false);
 
-Leaf statement
-^^^^^^^^^^^^^^
+    CrossSourceStatementReactor.BuildAction reactor == YangInferencePipeline.RFC6020_REACTOR.newBuild();
+    reactor.addSources(yangModuleSource, yangModuleSource2);
 
-Each leaf has to contain at least one type substatement. The leaf is
-mapped to getter method of parent statement with return type equal to
-type substatement value.
+    SchemaContext schemaContext == reactor.buildEffective();
 
-For example, the following YANG:
+First, StatementStreamSource objects with two constructor arguments
+should be instantiated: path to the yang source file (which is a regular
+String object) and a boolean which determines if the path is absolute or
+relative.
 
-**YANG model.**
+Next comes the initiation of new yang parsing cycle - which is
+represented by CrossSourceStatementReactor.BuildAction object. You can
+get it by calling method newBuild() on CrossSourceStatementReactor
+object (RFC6020\_REACTOR) in YangInferencePipeline class.
 
-.. code:: yang
-
-    container cont {
-      leaf lf {
-        type string;
-      }
-    }
+Then you should feed yang sources to it by calling method addSources()
+that takes one or more StatementStreamSource objects as arguments.
 
-is converted into this Java:
+Finally you call the method buildEffective() on the reactor object which
+returns EffectiveSchemaContext (that is a concrete implementation of
+SchemaContext). Now you are ready to work with contents of the added
+yang sources.
 
-**Cont.java.**
+Let us explain how to work with models contained in the newly created
+SchemaContext. If you want to get all the modules in the schemaContext,
+you have to call method getModules() which returns a Set of modules. If
+you want to get all the data definitions in schemaContext, you need to
+call method getDataDefinitions, etc.
 
 .. code:: java
 
-    public interface Cont extends DataObject, Augmentable<Cont> {
-        String getLf(); 
-    }
-
--  Represents ``leaf lf``
-
-leaf-list statement
-^^^^^^^^^^^^^^^^^^^
+    Set<Module> modules == schemaContext.getModules();
+    Set<DataSchemaNodes> dataSchemaNodes == schemaContext.getDataDefinitions();
 
-Each leaf-list has to contain one type substatement. The leaf-list is
-mapped to getter method of parent statement with return type equal to
-List of type substatement value.
+Usually you want to access specific modules. Getting a concrete module
+from SchemaContext is a matter of calling one of these methods:
 
-For example, the following YANG:
+-  findModuleByName(),
 
-**YANG model.**
+-  findModuleByNamespace(),
 
-.. code:: yang
+-  findModuleByNamespaceAndRevision().
 
-    container cont {
-        leaf-list lf-lst {
-            type string;
-        }
-    }
-
-is converted into this Java:
-
-**Cont.java.**
+In the first case, you need to provide module name as it is defined in
+the yang source file and module revision date if it specified in the
+yang source file (if it is not defined, you can just pass a null value).
+In order to provide the revision date in proper format, you can use a
+utility class named SimpleDateFormatUtil.
 
 .. code:: java
 
-    public interface Cont extends DataObject, Augmentable<Cont> {
-        List<String> getLfLst();
-    }
-
-list statement
-^^^^^^^^^^^^^^
-
-``list`` statements are mapped to Java interfaces and a getter method is
-generated in the interface associated with it’s parent statement. The
-return type of getter the method is a Java List of objects implementing
-the interface generated corresponding to the ``list statement.
-Mapping of `list`` substatement to Java:
-
-For example, the following YANG:
-
-**YANG model.**
-
-.. code:: yang
-
-    container cont {
-      list outter-list {
-        key "leaf-in-list";
-        leaf number {
-          type uint64;
-        }
-      }
-    }
-
-The list statement ``example-list`` is mapped to the Java interface
-``ExampleList`` and the ``Cont`` interface (parent of ``ExampleList``)
-contains getter method with return type ``List<ExampleList>``. The
-presence of a ``key`` statement, triggers generation of
-``ExampleListKey``, which may be used to identify item in list.
-
-The end result is this Java:
+    Module exampleModule == schemaContext.findModuleByName("example-module", null);
+    // or
+    Date revisionDate == SimpleDateFormatUtil.getRevisionFormat().parse("2015-09-02");
+    Module exampleModule == schemaContext.findModuleByName("example-module", revisionDate);
 
-**OutterList.java.**
+In the second case, you have to provide module namespace in form of an
+URI object.
 
 .. code:: java
 
-    package org.opendaylight.yang.gen.v1.urn.module.rev201379.cont;
-
-    import org.opendaylight.yangtools.yang.binding.DataObject;
-    import org.opendaylight.yangtools.yang.binding.Augmentable;
-    import Java.util.List;
-    import org.opendaylight.yang.gen.v1.urn.module.rev201379.cont.outter.list.ListInList;
-
-    public interface OutterList extends DataObject, Augmentable<OutterList> {
-
-        List<String> getLeafListInList();
+    Module exampleModule == schema.findModuleByNamespace(new URI("opendaylight.org/example-module"));
 
-        List<ListInList> getListInList();
+In the third case, you provide both module namespace and revision date
+as arguments.
 
-        /*
-        Returns Primary Key of Yang List Type
-        */
-        OutterListKey getOutterListKey();
-
-    }
-
-**OutterListKey.java.**
+Once you have a Module object, you can access its contents as they are
+defined in YANG Model API. One way to do this is to use method like
+getIdentities() or getRpcs() which will give you a Set of objects.
+Otherwise you can access a DataSchemaNode directly via the method
+getDataChildByName() which takes a QName object as its only argument.
+Here are a few examples.
 
 .. code:: java
 
-    package org.opendaylight.yang.gen.v1.urn.module.rev201379.cont;
-
-    import org.opendaylight.yang.gen.v1.urn.module.rev201379.cont.OutterListKey;
-    import Java.math.BigInteger;
-
-    public class OutterListKey {
-
-        private BigInteger _leafInList;
-
-        public OutterListKey(BigInteger _leafInList) {
-            super();
-            this_leafInList = _leafInList;
-        }
-
-        public BigInteger getLeafInList() {
-            return _leafInList;
-        }
-
-        @Override
-        public int hashCode() {
-            final int prime = 31;
-            int result = 1;
-            result = prime * result + ((_leafInList == null) ? 0 : _leafInList.hashCode());
-            return result;
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if (this == obj) {
-                return true;
-            }
-            if (obj == null) {
-                return false;
-            }
-            if (getClass() != obj.getClass()) {
-                return false;
-            }
-            OutterListKey other = (OutterListKey) obj;
-            if (_leafInList == null) {
-                if (other._LeafInList != null) {
-                    return false;
-                }
-            } else if(!_leafInList.equals(other._leafInList)) {
-                return false;
-            }
-            return true;
-        }
-
-        @Override
-        public String toString() {
-            StringBuilder builder = new StringBuilder();
-            builder.append("OutterListKey [_leafInList=");
-            builder.append(_leafInList);
-            builder.append("]");
-            return builder.toString();
-        }
-    }
+    Set<AugmentationSchema> augmentationSchemas == exampleModule.getAugmentations();
+    Set<ModuleImport> moduleImports == exampleModule.getImports();
 
-choice and case statements
-^^^^^^^^^^^^^^^^^^^^^^^^^^
+    ChoiceSchemaNode choiceSchemaNode == (ChoiceSchemaNode) exampleModule.getDataChildByName(QName.create(exampleModule.getQNameModule(), "example-choice"));
 
-A ``choice`` element is mapped in mostly the same way a ``list`` element
-is. The ``choice`` element is mapped to and interface (marker interface)
-and a new getter method with the return type of a Java ``List`` of this
-marker interfaces is added to the interface corresponding to the parent
-statement. Any ``case`` substatements are mapped to Java interfaces
-which extend the marker interface.
+    ContainerSchemaNode containerSchemaNode == (ContainerSchemaNode) exampleModule.getDataChildByName(QName.create(exampleModule.getQNameModule(), "example-container"));
 
-For example, the following YANG:
+The YANG statement parser can work in three modes:
 
-**YANG model.**
+-  default mode
 
-.. code:: yang
+-  mode with active resolution of if-feature statements
 
-    container cont {
-        choice example-choice {
-            case foo-case {
-              leaf foo {
-                type string;
-              }
-            }
-            case bar-case {
-                leaf bar {
-                  type string;
-                }
-            }
-        }
-    }
+-  mode with active semantic version processing
 
-is converted into this Java:
+The default mode is active when you initialize the parsing cycle as
+usual by calling the method newBuild() without passing any arguments to
+it. The second and third mode can be activated by invoking the
+newBuild() with a special argument. You can either activate just one of
+them or both by passing proper arguments. Let us explain how these modes
+work.
 
-**Cont.java.**
+Mode with active resolution of if-features makes yang statements
+containing an if-feature statement conditional based on the supported
+features. These features are provided in the form of a QName-based
+java.util.function.Predicate object. In the example below, only two
+features are supported: example-feature-1 and example-feature-2. The
+Predicate which contains this information is passed to the method
+newBuild() and the mode is activated.
 
 .. code:: java
 
-    package org.opendaylight.yang.gen.v1.urn.module.rev201379;
-
-    import org.opendaylight.yangtools.yang.binding.DataObject;
-    import org.opendaylight.yangtools.yang.binding.Augmentable;
-    import org.opendaylight.yang.gen.v1.urn.module.rev201379.cont.ChoiceTest;
-
-    public interface Cont extends DataObject, Augmentable<Cont> {
-
-        ExampleChoice getExampleChoice();
-
+    Predicate<QName> isFeatureSupported == qName -> {
+        Set<QName> supportedFeatures == new HashSet<>();
+        supportedFeatures.add(QName.create("example-namespace", "2016-08-31", "example-feature-1"));
+        supportedFeatures.add(QName.create("example-namespace", "2016-08-31", "example-feature-2"));
+        return supportedFeatures.contains(qName);
     }
 
-**ExampleChoice.java.**
-
-.. code:: java
+    CrossSourceStatementReactor.BuildAction reactor == YangInferencePipeline.RFC6020_REACTOR.newBuild(isFeatureSupported);
 
-    package org.opendaylight.yang.gen.v1.urn.module.rev201379.cont;
-
-    import org.opendaylight.yangtools.yang.binding.DataObject;
-
-    public interface ExampleChoice extends DataContainer {
-    }
-
-**FooCase.java.**
+In case when no features should be supported, you should provide a
+Predicate<QName> object whose test() method just returns false.
 
 .. code:: java
 
-    package org.opendaylight.yang.gen.v1.urn.module.rev201379.cont.example.choice;
-
-    import org.opendaylight.yangtools.yang.binding.DataObject;
-    import org.opendaylight.yangtools.yang.binding.Augmentable;
-    import org.opendaylight.yang.gen.v1.urn.module.rev201379.cont.ChoiceTest;
-
-    public interface FooCase extends ExampleChoice, DataObject, Augmentable<FooCase> {
+    Predicate<QName> isFeatureSupported == qName -> false;
 
-        String getFoo();
+    CrossSourceStatementReactor.BuildAction reactor == YangInferencePipeline.RFC6020_REACTOR.newBuild(isFeatureSupported);
 
-    }
+When this mode is not activated, all features in the processed YANG
+sources are supported.
 
-**BarCase.java.**
+Mode with active semantic version processing changes the way how YANG
+import statements work - each module import is processed based on the
+specified semantic version statement and the revision-date statement is
+ignored. In order to activate this mode, you have to provide
+StatementParserMode.SEMVER\_MODE enum constant as argument to the method
+newBuild().
 
 .. code:: java
 
-    package org.opendaylight.yang.gen.v1.urn.module.rev201379.cont.example.choice;
-
-    import org.opendaylight.yangtools.yang.binding.DataObject;
-    import org.opendaylight.yangtools.yang.binding.Augmentable;
-    import org.opendaylight.yang.gen.v1.urn.module.rev201379.cont.ChoiceTest;
-
-    public interface BarCase extends ExampleChoice, DataObject, Augmentable<BarCase> {
-
-        String getBar();
-
-    }
-
-grouping and uses statements
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-``grouping`s are mapped to Java interfaces. `uses`` statements in some
-element (using of concrete grouping) are mapped as extension of
-interface for this element with the interface which represents grouping.
-
-For example, the following YANG:
+    CrossSourceStatementReactor.BuildAction reactor == YangInferencePipeline.RFC6020_REACTOR.newBuild(StatementParserMode.SEMVER_MODE);
 
-**YANG Model.**
+Before you use a semantic version statement in a YANG module, you need
+to define an extension for it so that the YANG statement parser can
+recognize it.
 
 .. code:: yang
 
-    grouping grp {
-      leaf foo {
-        type string;
-      }
-    }
-
-    container cont {
-        uses grp;
-    }
-
-is converted into this Java:
-
-**Grp.java.**
-
-.. code:: java
-
-    package org.opendaylight.yang.gen.v1.urn.module.rev201379;
-
-    import org.opendaylight.yangtools.yang.binding.DataObject;
-
-    public interface Grp extends DataObject {
-
-        String getFoo();
-
-    }
-
-**Cont.java.**
-
-.. code:: java
-
-    package org.opendaylight.yang.gen.v1.urn.module.rev201379;
-
-    import org.opendaylight.yangtools.yang.binding.DataObject;
-    import org.opendaylight.yangtools.yang.binding.Augmentable;
+    module semantic-version {
+        namespace "urn:opendaylight:yang:extension:semantic-version";
+        prefix sv;
+        yang-version 1;
 
-    public interface Cont extends DataObject, Augmentable<Cont>, Grp {
-    }
-
-rpc, input and output statements
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-An ``rpc`` statement is mapped to Java as method of class
-``ModuleService.java``. Any substatements of an ``rpc`` are mapped as
-follows:
-
-+--------------------------------------+--------------------------------------+
-| Rpc Substatement                     | Mapping                              |
-+======================================+======================================+
-| input                                | presence of input statement triggers |
-|                                      | generation of interface              |
-+--------------------------------------+--------------------------------------+
-| output                               | presence of output statement         |
-|                                      | triggers generation of interface     |
-+--------------------------------------+--------------------------------------+
-
-For example, the following YANG:
-
-**YANG model.**
-
-.. code:: yang
-
-    rpc rpc-test1 {
-        output {
-            leaf lf-output {
-                type string;
-            }
+        revision 2016-02-02 {
+            description "Initial version";
         }
-        input {
-            leaf lf-input {
-                type string;
+        sv:semantic-version "0.0.1";
+
+        extension semantic-version {
+            argument "semantic-version" {
+                yin-element false;
             }
         }
     }
 
-is converted into this Java:
-
-**ModuleService.java.**
-
-.. code:: java
-
-    package org.opendaylight.yang.gen.v1.urn.module.rev201379;
-
-    import Java.util.concurrent.Future;
-    import org.opendaylight.yangtools.yang.common.RpcResult;
-
-    public interface ModuleService {
-
-        Future<RpcResult<RpcTest1Output>> rpcTest1(RpcTest1Input input);
-
-    }
-
-**RpcTest1Input.java.**
-
-.. code:: java
-
-    package org.opendaylight.yang.gen.v1.urn.module.rev201379;
-
-    public interface RpcTest1Input {
-
-        String getLfInput();
-
-    }
-
-**RpcTest1Output.java.**
-
-.. code:: java
-
-    package org.opendaylight.yang.gen.v1.urn.module.rev201379;
-
-    public interface RpcTest1Output {
-
-        String getLfOutput();
-
-    }
-
-notification statement
-^^^^^^^^^^^^^^^^^^^^^^
-
-``notification`` statements are mapped to Java interfaces which extend
-the Notification interface.
-
-For example, the following YANG:
+In the example above, you see a YANG module which defines semantic
+version as an extension. This extension can be imported to other modules
+in which we want to utilize the semantic versioning concept.
 
-**YANG model.**
+Below is a simple example of the semantic versioning usage. With
+semantic version processing mode being active, the foo module imports
+the bar module based on its semantic version. Notice how both modules
+import the module with the semantic-version extension.
 
 .. code:: yang
 
-    notification notif {
-        }
-
-is converted into this Java:
-
-**Notif.java.**
-
-.. code:: java
-
-    package org.opendaylight.yang.gen.v1.urn.module.rev201379;
+    module foo {
+        namespace foo;
+        prefix foo;
+        yang-version 1;
 
+        import semantic-version { prefix sv; revision-date 2016-02-02; sv:semantic-version "0.0.1"; }
+        import bar { prefix bar; sv:semantic-version "0.1.2";}
 
-    import org.opendaylight.yangtools.yang.binding.DataObject;
-    import org.opendaylight.yangtools.yang.binding.Augmentable;
-    import org.opendaylight.yangtools.yang.binding.Notification;
+        revision "2016-02-01" {
+            description "Initial version";
+        }
+        sv:semantic-version "0.1.1";
 
-    public interface Notif extends DataObject, Augmentable<Notif>, Notification {
+        ...
     }
 
-augment statement
-~~~~~~~~~~~~~~~~~
-
-``augment`` statements are mapped to Java interfaces. The interface
-starts with the same name as the name of augmented interface with a
-suffix corresponding to the order number of augmenting interface. The
-augmenting interface also extends ``Augmentation<>`` with actual type
-parameter equal to augmented interface.
-
-For example, the following YANG:
-
-**YANG Model.**
-
 .. code:: yang
 
-    container cont {
-    }
-
-    augment "/cont" {
-      leaf additional-value {
-        type string;
-      }
-    }
-
-is converted into this Java:
+    module bar {
+        namespace bar;
+        prefix bar;
+        yang-version 1;
 
-**Cont.java.**
+        import semantic-version { prefix sv; revision-date 2016-02-02; sv:semantic-version "0.0.1"; }
 
-.. code:: java
-
-    package org.opendaylight.yang.gen.v1.urn.module.rev201379;
-
-    import org.opendaylight.yangtools.yang.binding.DataObject;
-    import org.opendaylight.yangtools.yang.binding.Augmentable;
-
-    public interface Cont extends DataObject, Augmentable<Cont> {
+        revision "2016-01-01" {
+            description "Initial version";
+        }
+        sv:semantic-version "0.1.2";
 
+        ...
     }
 
-**Cont1.java.**
-
-.. code:: java
-
-    package org.opendaylight.yang.gen.v1.urn.module.rev201379;
-
-    import org.opendaylight.yangtools.yang.binding.DataObject;
-    import org.opendaylight.yangtools.yang.binding.Augmentation;
+Every semantic version must have the following form: x.y.z. The x
+corresponds to a major version, the y corresponds to a minor version and
+the z corresponds to a patch version. If no semantic version is
+specified in a module or an import statement, then the default one is
+used - 0.0.0.
 
-    public interface Cont1 extends DataObject, Augmentation<Cont> {
+A major version number of 0 indicates that the model is still in
+development and is subject to change.
 
-    }
+Following a release of major version 1, all modules will increment major
+version number when backwards incompatible changes to the model are
+made.
 
-YANG Type mapping
-~~~~~~~~~~~~~~~~~
+The minor version is changed when features are added to the model that
+do not impact current clients use of the model.
 
-typedef statement
-^^^^^^^^^^^^^^^^^
+The patch version is incremented when non-feature changes (such as
+bugfixes or clarifications of human-readable descriptions that do not
+impact model functionality) are made that maintain backwards
+compatibility.
 
-YANG ``typedef`` statements are mapped to Java classes. A ``typedef``
-may contain following substatements:
-
-+--------------------------------------+--------------------------------------+
-| Substatement                         | Behaviour                            |
-+======================================+======================================+
-| type                                 | determines wrapped type and how      |
-|                                      | class will be generated              |
-+--------------------------------------+--------------------------------------+
-| descripton                           | Javadoc description                  |
-+--------------------------------------+--------------------------------------+
-| units                                | is not mapped                        |
-+--------------------------------------+--------------------------------------+
-| default                              | is not mapped                        |
-+--------------------------------------+--------------------------------------+
-
-Valid Arguments Type
-''''''''''''''''''''
-
-Simple values of type argument are mapped as follows:
-
-+--------------------------------------+--------------------------------------+
-| YANG Type                            | Java type                            |
-+======================================+======================================+
-| boolean                              | Boolean                              |
-+--------------------------------------+--------------------------------------+
-| empty                                | Boolean                              |
-+--------------------------------------+--------------------------------------+
-| int8                                 | Byte                                 |
-+--------------------------------------+--------------------------------------+
-| int16                                | Short                                |
-+--------------------------------------+--------------------------------------+
-| int32                                | Integer                              |
-+--------------------------------------+--------------------------------------+
-| int64                                | Long                                 |
-+--------------------------------------+--------------------------------------+
-| string                               | String or, wrapper class (if pattern |
-|                                      | substatement is specified)           |
-+--------------------------------------+--------------------------------------+
-| decimal64                            | Double                               |
-+--------------------------------------+--------------------------------------+
-| uint8                                | Short                                |
-+--------------------------------------+--------------------------------------+
-| uint16                               | Integer                              |
-+--------------------------------------+--------------------------------------+
-| uint32                               | Long                                 |
-+--------------------------------------+--------------------------------------+
-| uint64                               | BigInteger                           |
-+--------------------------------------+--------------------------------------+
-| binary                               | byte[]                               |
-+--------------------------------------+--------------------------------------+
-
-Complex values of type argument are mapped as follows:
-
-+--------------------------------------+--------------------------------------+
-| Argument Type                        | Java type                            |
-+======================================+======================================+
-| enumeration                          | generated java enum                  |
-+--------------------------------------+--------------------------------------+
-| bits                                 | generated class for bits             |
-+--------------------------------------+--------------------------------------+
-| leafref                              | same type as referenced leaf         |
-+--------------------------------------+--------------------------------------+
-| identityref                          | Class                                |
-+--------------------------------------+--------------------------------------+
-| union                                | generated java class                 |
-+--------------------------------------+--------------------------------------+
-| instance-identifier                  | ``org.opendaylight.yangtools.yang.bi |
-|                                      | nding.InstanceIdentifier``           |
-+--------------------------------------+--------------------------------------+
-
-Enumeration Substatement Enum
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-The YANG ``enumeration`` type has to contain some ``enum``
-substatements. An ``enumeration`` is mapped as Java enum type
-(standalone class) and every YANG enum substatements is mapped to Java
-enum’s predefined values.
-
-An ``enum`` statement can have following substatements:
-
-+--------------------------------------+--------------------------------------+
-| Enum’s Substatement                  | Java mapping                         |
-+======================================+======================================+
-| description                          | is not mapped in API                 |
-+--------------------------------------+--------------------------------------+
-| value                                | mapped as input parameter for every  |
-|                                      | predefined value of enum             |
-+--------------------------------------+--------------------------------------+
-
-For example, the following YANG:
-
-**YANG model.**
+When importing a module with activated semantic version processing mode,
+only the module with the newest (highest) compatible semantic version is
+imported. Two semantic versions are compatible when all of the following
+conditions are met:
 
-.. code:: yang
-
-    typedef typedef-enumeration {
-        type enumeration {
-            enum enum1 {
-                description "enum1 description";
-                value 18;
-            }
-            enum enum2 {
-                value 16;
-            }
-            enum enum3 {
-            }
-        }
-    }
+-  the major version in the import statement and major version in the
+   imported module are equal. For instance, 1.5.3 is compatible with
+   1.5.3, 1.5.4, 1.7.2, etc., but it is not compatible with 0.5.2 or
+   2.4.8, etc.
 
-is converted into this Java:
+-  the combination of minor version and patch version in the import
+   statement is not higher than the one in the imported module. For
+   instance, 1.5.2 is compatible with 1.5.2, 1.5.4, 1.6.8 etc. In fact,
+   1.5.2 is also compatible with versions like 1.5.1, 1.4.9 or 1.3.7 as
+   they have equal major version. However, they will not be imported
+   because their minor and patch version are lower (older).
 
-**TypedefEnumeration.java.**
+If the import statement does not specify a semantic version, then the
+default one is chosen - 0.0.0. Thus, the module is imported only if it
+has a semantic version compatible with the default one, for example
+0.0.0, 0.1.3, 0.3.5 and so on.
 
-.. code:: java
+Working with YANG Data
+~~~~~~~~~~~~~~~~~~~~~~
 
-    public enum TypedefEnumeration {
-        Enum1(18),
-        Enum2(16),
-        Enum3(19);
+If you want to work with YANG Data you are going to need NormalizedNode
+objects that are specified in the YANG Data API. NormalizedNode is an
+interface at the top of the YANG Data hierarchy. It is extended through
+sub-interfaces which define the behaviour of specific NormalizedNode
+types like AnyXmlNode, ChoiceNode, LeafNode, ContainerNode, etc.
+Concrete implemenations of these interfaces are defined in
+yang-data-impl module. Once you have one or more NormalizedNode
+instances, you can perform CRUD operations on YANG data tree which is an
+in-memory database designed to store normalized nodes in a tree-like
+structure.
 
-        int value;
+In some cases it is clear which NormalizedNode type belongs to which
+yang statement (e.g. AnyXmlNode, ChoiceNode, LeafNode). However, there
+are some normalized nodes which are named differently from their yang
+counterparts. They are listed below:
 
-        private TypedefEnumeration(int value) {
-            this.value = value;
-        }
-    }
+-  LeafSetNode - leaf-list
 
-Bits’s Substatement Bit
-^^^^^^^^^^^^^^^^^^^^^^^
+-  OrderedLeafSetNode - leaf-list that is ordered-by user
 
-The YANG ``bits`` type has to contain some bit substatements. YANG
-``bits`` is mapped to a Java class (standalone class) and every YANG
-``bits`` substatements is mapped to a boolean attribute of that class.
-In addition, the class provides overridden versions of the Object
-methods ``hashCode``, ``toString``, and ``equals``.
+-  LeafSetEntryNode - concrete entry in a leaf-list
 
-For example, the following YANG:
+-  MapNode - keyed list
 
-**YANG Model.**
+-  OrderedMapNode - keyed list that is ordered-by user
 
-.. code:: yang
+-  MapEntryNode - concrete entry in a keyed list
 
-    typedef typedef-bits {
-      type bits {
-        bit first-bit {
-          description "first-bit description";
-            position 15;
-          }
-        bit second-bit;
-      }
-    }
+-  UnkeyedListNode - unkeyed list
 
-is converted into this Java:
+-  UnkeyedListEntryNode - concrete entry in an unkeyed list
 
-**TypedefBits.java.**
+In order to create a concrete NormalizedNode object you can use the
+utility class Builders or ImmutableNodes. These classes can be found in
+yang-data-impl module and they provide methods for building each type of
+normalized node. Here is a simple example of building a normalized node:
 
 .. code:: java
 
-    public class TypedefBits {
-
-        private Boolean firstBit;
-        private Boolean secondBit;
-
-        public TypedefBits() {
-            super();
-        }
-
-        public Boolean getFirstBit() {
-            return firstBit;
-        }
+    \\ example 1
+    ContainerNode containerNode == Builders.containerBuilder().withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(QName.create(moduleQName, "example-container")).build();
 
-        public void setFirstBit(Boolean firstBit) {
-            this.firstBit = firstBit;
-        }
+    \\ example 2
+    ContainerNode containerNode2 == Builders.containerBuilder(containerSchemaNode).build();
 
-        public Boolean getSecondBit() {
-            return secondBit;
-        }
-
-        public void setSecondBit(Boolean secondBit) {
-            this.secondBit = secondBit;
-        }
-
-        @Override
-        public int hashCode() {
-            final int prime = 31;
-            int result = 1;
-            result = prime * result +
-             ((firstBit == null) ? 0 : firstBit.hashCode());
-            result = prime * result +
-             ((secondBit == null) ? 0 : secondBit.hashCode());
-            return result;
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if (this == obj) {
-                return true;
-            }
-            if (obj == null) {
-                return false;
-            }
-            if (getClass() != obj.getClass()) {
-                return false;
-            }
-            TypedefBits other = (TypedefBits) obj;
-            if (firstBit == null) {
-                if (other.firstBit != null) {
-                    return false;
-                }
-            } else if(!firstBit.equals(other.firstBit)) {
-                return false;
-            }
-            if (secondBit == null) {
-                if (other.secondBit != null) {
-                    return false;
-                }
-            } else if(!secondBit.equals(other.secondBit)) {
-                return false;
-            }
-            return true;
-        }
+Both examples produce the same result. NodeIdentifier is one of the four
+types of YangInstanceIdentifier (these types are described in the
+javadoc of YangInstanceIdentifier). The purpose of
+YangInstanceIdentifier is to uniquely identify a particular node in the
+data tree. In the first example, you have to add NodeIdentifier before
+building the resulting node. In the second example it is also added
+using the provided ContainerSchemaNode object.
 
-        @Override
-        public String toString() {
-            StringBuilder builder = new StringBuilder();
-            builder.append("TypedefBits [firstBit=");
-            builder.append(firstBit);
-            builder.append(", secondBit=");
-            builder.append(secondBit);
-            builder.append("]");
-            return builder.toString();
-        }
-    }
+ImmutableNodes class offers similar builder methods and also adds an
+overloaded method called fromInstanceId() which allows you to create a
+NormalizedNode object based on YangInstanceIdentifier and SchemaContext.
+Below is an example which shows the use of this method.
 
-Union’s Substatement Type
-^^^^^^^^^^^^^^^^^^^^^^^^^
+.. code:: java
 
-If the type of a ``typedef`` is ``union``, it has to contain ``type``
-substatements. The ``union typedef`` is mapped to class and its ``type``
-substatements are mapped to private class members. Every YANG union
-subtype gets its own Java constructor with a parameter which represent
-just that one attribute.
+    YangInstanceIdentifier.NodeIdentifier contId == new YangInstanceIdentifier.NodeIdentifier(QName.create(moduleQName, "example-container");
 
-For example, the following YANG:
+    NormalizedNode<?, ?> contNode == ImmutableNodes.fromInstanceId(schemaContext, YangInstanceIdentifier.create(contId));
 
-**YANG model.**
+Let us show a more complex example of creating a NormalizedNode. First,
+consider the following YANG module:
 
 .. code:: yang
 
-    typedef typedef-union {
-        type union {
-            type int32;
-            type string;
-        }
-    }
+    module example-module {
+        namespace "opendaylight.org/example-module";
+        prefix "example";
 
-is converted into this Java:
+        container parent-container {
+            container child-container {
+                list parent-ordered-list {
+                    ordered-by user;
 
-**TypdefUnion.java.**
-
-.. code:: java
+                    key "parent-key-leaf";
 
-    public class TypedefUnion {
+                    leaf parent-key-leaf {
+                        type string;
+                    }
 
-        private Integer int32;
-        private String string;
-
-        public TypedefUnion(Integer int32) {
-            super();
-            this.int32 = int32;
-        }
-
-        public TypedefUnion(String string) {
-            super();
-            this.string = string;
-        }
+                    leaf parent-ordinary-leaf {
+                        type string;
+                    }
 
-        public Integer getInt32() {
-            return int32;
-        }
+                    list child-ordered-list {
+                        ordered-by user;
 
-        public String getString() {
-            return string;
-        }
+                        key "child-key-leaf";
 
-        @Override
-        public int hashCode() {
-            final int prime = 31;
-            int result = 1;
-            result = prime * result + ((int32 == null) ? 0 : int32.hashCode());
-            result = prime * result + ((string == null) ? 0 : string.hashCode());
-            return result;
-        }
+                        leaf child-key-leaf {
+                            type string;
+                        }
 
-        @Override
-        public boolean equals(Object obj) {
-            if (this == obj) {
-                return true;
-            }
-            if (obj == null) {
-                return false;
-            }
-            if (getClass() != obj.getClass()) {
-                return false;
-            }
-            TypedefUnion other = (TypedefUnion) obj;
-            if (int32 == null) {
-                if (other.int32 != null) {
-                    return false;
-                }
-            } else if(!int32.equals(other.int32)) {
-                return false;
-            }
-            if (string == null) {
-                if (other.string != null) {
-                    return false;
+                        leaf child-ordinary-leaf {
+                            type string;
+                        }
+                    }
                 }
-            } else if(!string.equals(other.string)) {
-                return false;
             }
-            return true;
-        }
-
-        @Override
-        public String toString() {
-            StringBuilder builder = new StringBuilder();
-            builder.append("TypedefUnion [int32=");
-            builder.append(int32);
-            builder.append(", string=");
-            builder.append(string);
-            builder.append("]");
-            return builder.toString();
-        }
-    }
-
-String Mapping
-^^^^^^^^^^^^^^
-
-The YANG ``string`` type can contain the substatements ``length`` and
-``pattern`` which are mapped as follows:
-
-+--------------------------------------+--------------------------------------+
-| Type substatements                   | Mapping to Java                      |
-+======================================+======================================+
-| length                               | not mapped                           |
-+--------------------------------------+--------------------------------------+
-| pattern                              | | . list of string constants = list  |
-|                                      |   of patterns                        |
-|                                      | | . list of Pattern objects          |
-|                                      | | . static initialization block      |
-|                                      |   where list of Patterns is          |
-|                                      |   initialized from list of string of |
-|                                      |   constants                          |
-+--------------------------------------+--------------------------------------+
-
-For example, the following YANG:
-
-**YANG model.**
-
-.. code:: yang
-
-    typedef typedef-string {
-        type string {
-            length 44;
-            pattern "[a][.]*"
         }
     }
 
-is converted into this Java:
-
-**TypedefString.java.**
+In the following example, two normalized nodes based on the module above
+are written to and read from the data tree.
 
 .. code:: java
 
-    public class TypedefString {
-
-        private static final List<Pattern> patterns = new ArrayList<Pattern>();
-        public static final List<String> PATTERN`CONSTANTS = Arrays.asList("[a][.]*");
-
-        static {
-            for (String regEx : PATTERN`CONSTANTS) {
-                patterns.add(Pattern.compile(regEx));
-            }
-        }
-
-        private String typedefString;
-
-        public TypedefString(String typedefString) {
-            super();
-            // Pattern validation
-            this.typedefString = typedefString;
-        }
-
-        public String getTypedefString() {
-            return typedefString;
-        }
-
-        @Override
-        public int hashCode() {
-            final int prime = 31;
-            int result = 1;
-            result = prime * result + ((typedefString == null) ? 0 : typedefString.hashCode());
-            return result;
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if (this == obj) {
-                return true;
-            }
-            if (obj == null) {
-                return false;
-            }
-            if (getClass() != obj.getClass()) {
-                return false;
-            }
-            TypedefString other = (TypedefString) obj;
-            if (typedefString == null) {
-                if (other.typedefString != null) {
-                    return false;
-                }
-            } else if(!typedefString.equals(other.typedefString)) {
-                return false;
-            }
-            return true;
-        }
-
-        @Override
-        public String toString() {
-            StringBuilder builder = new StringBuilder();
-            builder.append("TypedefString [typedefString=");
-            builder.append(typedefString);
-            builder.append("]");
-            return builder.toString();
-        }
-    }
+    TipProducingDataTree inMemoryDataTree ==     InMemoryDataTreeFactory.getInstance().create(TreeType.OPERATIONAL);
+    inMemoryDataTree.setSchemaContext(schemaContext);
+
+    // first data tree modification
+    MapEntryNode parentOrderedListEntryNode == Builders.mapEntryBuilder().withNodeIdentifier(
+    new YangInstanceIdentifier.NodeIdentifierWithPredicates(
+    parentOrderedListQName, parentKeyLeafQName, "pkval1"))
+    .withChild(Builders.leafBuilder().withNodeIdentifier(
+    new YangInstanceIdentifier.NodeIdentifier(parentOrdinaryLeafQName))
+    .withValue("plfval1").build()).build();
+
+    OrderedMapNode parentOrderedListNode == Builders.orderedMapBuilder().withNodeIdentifier(
+    new YangInstanceIdentifier.NodeIdentifier(parentOrderedListQName))
+    .withChild(parentOrderedListEntryNode).build();
+
+    ContainerNode parentContainerNode == Builders.containerBuilder().withNodeIdentifier(
+    new YangInstanceIdentifier.NodeIdentifier(parentContainerQName))
+    .withChild(Builders.containerBuilder().withNodeIdentifier(
+    new NodeIdentifier(childContainerQName)).withChild(parentOrderedListNode).build()).build();
+
+    YangInstanceIdentifier path1 == YangInstanceIdentifier.of(parentContainerQName);
+
+    DataTreeModification treeModification == inMemoryDataTree.takeSnapshot().newModification();
+    treeModification.write(path1, parentContainerNode);
+
+    // second data tree modification
+    MapEntryNode childOrderedListEntryNode == Builders.mapEntryBuilder().withNodeIdentifier(
+    new YangInstanceIdentifier.NodeIdentifierWithPredicates(
+    childOrderedListQName, childKeyLeafQName, "chkval1"))
+    .withChild(Builders.leafBuilder().withNodeIdentifier(
+    new YangInstanceIdentifier.NodeIdentifier(childOrdinaryLeafQName))
+    .withValue("chlfval1").build()).build();
+
+    OrderedMapNode childOrderedListNode == Builders.orderedMapBuilder().withNodeIdentifier(
+    new YangInstanceIdentifier.NodeIdentifier(childOrderedListQName))
+    .withChild(childOrderedListEntryNode).build();
+
+    ImmutableMap.Builder<QName, Object> builder == ImmutableMap.builder();
+    ImmutableMap<QName, Object> keys == builder.put(parentKeyLeafQName, "pkval1").build();
+
+    YangInstanceIdentifier path2 == YangInstanceIdentifier.of(parentContainerQName).node(childContainerQName)
+    .node(parentOrderedListQName).node(new NodeIdentifierWithPredicates(parentOrderedListQName, keys)).node(childOrderedListQName);
+
+    treeModification.write(path2, childOrderedListNode);
+    treeModification.ready();
+    inMemoryDataTree.validate(treeModification);
+    inMemoryDataTree.commit(inMemoryDataTree.prepare(treeModification));
+
+    DataTreeSnapshot snapshotAfterCommits == inMemoryDataTree.takeSnapshot();
+    Optional<NormalizedNode<?, ?>> readNode == snapshotAfterCommits.readNode(path1);
+    Optional<NormalizedNode<?, ?>> readNode2 == snapshotAfterCommits.readNode(path2);
+
+First comes the creation of in-memory data tree instance. The schema
+context (containing the model mentioned above) of this tree is set.
+After that, two normalized nodes are built. The first one consists of a
+parent container, a child container and a parent ordered list which
+contains a key leaf and an ordinary leaf. The second normalized node is
+a child ordered list that also contains a key leaf and an ordinary leaf.
+
+In order to add a child node to a node, method withChild() is used. It
+takes a NormalizedNode as argument. When creating a list entry,
+YangInstanceIdentifier.NodeIdentifierWithPredicates should be used as
+its identifier. Its arguments are the QName of the list, QName of the
+list key and the value of the key. Method withValue() specifies a value
+for the ordinary leaf in the list.
+
+Before writing a node to the data tree, a path (YangInstanceIdentifier)
+which determines its place in the data tree needs to be defined. The
+path of the first normalized node starts at the parent container. The
+path of the second normalized node points to the child ordered list
+contained in the parent ordered list entry specified by the key value
+"pkval1".
+
+Write operation is performed with both normalized nodes mentioned
+earlier. It consist of several steps. The first step is to instantiate a
+DataTreeModification object based on a DataTreeSnapshot.
+DataTreeSnapshot gives you the current state of the data tree. Then
+comes the write operation which writes a normalized node at the provided
+path in the data tree. After doing both write operations, method ready()
+has to be called, marking the modification as ready for application to
+the data tree. No further operations within the modification are
+allowed. The modification is then validated - checked whether it can be
+applied to the data tree. Finally we commit it to the data tree.
+
+Now you can access the written nodes. In order to do this, you have to
+create a new DataTreeSnapshot instance and call the method readNode()
+with path argument pointing to a particular node in the tree.
+
+Serialization / deserialization of YANG Data
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+If you want to deserialize YANG-modeled data which have the form of an
+XML document, you can use the XML parser found in the module
+yang-data-codec-xml. The parser walks through the XML document
+containing YANG-modeled data based on the provided SchemaContext and
+emits node events into a NormalizedNodeStreamWriter. The parser
+disallows multiple instances of the same element except for leaf-list
+and list entries. The parser also expects that the YANG-modeled data in
+the XML source are wrapped in a root element. Otherwise it will not work
+correctly.
+
+Here is an example of using the XML parser.
 
-identity statement
-~~~~~~~~~~~~~~~~~~
-
-The purpose of the ``identity`` statement is to define a new globally
-unique, abstract, and untyped value.
+.. code:: java
 
-The ``base`` substatement argument is the name of existing identity from
-which the new identity is derived.
+    InputStream resourceAsStream == ExampleClass.class.getResourceAsStream("/example-module.yang");
 
-Given that, an ``identity`` statement is mapped to Java abstract class
-and any ``base`` substatements are mapped as ``extends`` Java keyword.
-The identity name is translated to class name.
+    XMLInputFactory factory == XMLInputFactory.newInstance();
+    XMLStreamReader reader == factory.createXMLStreamReader(resourceAsStream);
 
-For example, the following YANG:
+    NormalizedNodeResult result == new NormalizedNodeResult();
+    NormalizedNodeStreamWriter streamWriter == ImmutableNormalizedNodeStreamWriter.from(result);
 
-**YANG Model.**
+    XmlParserStream xmlParser == XmlParserStream.create(streamWriter, schemaContext);
+    xmlParser.parse(reader);
 
-.. code:: yang
+    NormalizedNode<?, ?> transformedInput == result.getResult();
 
-    identity toast-type {
+The XML parser utilizes the javax.xml.stream.XMLStreamReader for parsing
+an XML document. First, you should create an instance of this reader
+using XMLInputFactory and then load an XML document (in the form of
+InputStream object) into it.
 
-    }
+In order to emit node events while parsing the data you need to
+instantiate a NormalizedNodeStreamWriter. This writer is actually an
+interface and therefore you need to use a concrete implementation of it.
+In this example it is the ImmutableNormalizedNodeStreamWriter, which
+constructs immutable instances of NormalizedNodes.
 
-    identity white-bread {
-       base toast-type;
-    }
+There are two ways how to create an instance of this writer using the
+static overloaded method from(). One version of this method takes a
+NormalizedNodeResult as argument. This object type is a result holder in
+which the resulting NormalizedNode will be stored. The other version
+takes a NormalizedNodeContainerBuilder as argument. All created nodes
+will be written to this builder.
 
-is converted into this Java:
+Next step is to create an instance of the XML parser. The parser itself
+is represented by a class named XmlParserStream. You can use one of two
+versions of the static overloaded method create() to construct this
+object. One version accepts a NormalizedNodeStreamWriter and a
+SchemaContext as arguments, the other version takes the same arguments
+plus a SchemaNode. Node events are emitted to the writer. The
+SchemaContext is used to check if the YANG data in the XML source comply
+with the provided YANG model(s). The last argument, a SchemaNode object,
+describes the node that is the parent of nodes defined in the XML data.
+If you do not provide this argument, the parser sets the SchemaContext
+as the parent node.
 
-**ToastType.java.**
+The parser is now ready to walk through the XML. Parsing is initiated by
+calling the method parse() on the XmlParserStream object with
+XMLStreamReader as its argument.
 
-.. code:: java
+Finally you can access the result of parsing - a tree of NormalizedNodes
+containg the data as they are defined in the parsed XML document - by
+calling the method getResult() on the NormalizedNodeResult object.
 
-    public abstract class ToastType extends BaseIdentity {
-        protected ToastType() {
-            super();
-        }
-    }
+Introducing schema source repositories
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-**WhiteBread.java.**
+Writing YANG driven generators
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-.. code:: java
+Introducing specific extension support for YANG parser
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-    public abstract class WhiteBread extends ToastType {
-        protected WhiteBread() {
-            super();
-        }
-    }
+Diagnostics
+~~~~~~~~~~~