Merge "Code refactoring"
[yangtools.git] / code-generator / binding-generator-impl / src / main / java / org / opendaylight / yangtools / sal / binding / generator / impl / BindingGeneratorImpl.java
index 48df06b1374a66614eab7fe0392dc32a3490639c..1760a7e13d254364bd30aafaf14d9bbfde34acce 100644 (file)
@@ -7,13 +7,8 @@
  */
 package org.opendaylight.yangtools.sal.binding.generator.impl;
 
-import static org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil.moduleNamespaceToPackageName;
-import static org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil.packageNameForGeneratedType;
-import static org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil.parseToClassName;
-import static org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil.parseToValidParamName;
-import static org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil.schemaNodeToTransferObjectBuilder;
-import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.findDataSchemaNode;
-import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.findParentModule;
+import static org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil.*;
+import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.*;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -32,6 +27,7 @@ import org.opendaylight.yangtools.sal.binding.generator.api.BindingGenerator;
 import org.opendaylight.yangtools.sal.binding.generator.spi.TypeProvider;
 import org.opendaylight.yangtools.sal.binding.model.api.GeneratedTransferObject;
 import org.opendaylight.yangtools.sal.binding.model.api.GeneratedType;
+import org.opendaylight.yangtools.sal.binding.model.api.ParameterizedType;
 import org.opendaylight.yangtools.sal.binding.model.api.Type;
 import org.opendaylight.yangtools.sal.binding.model.api.type.builder.EnumBuilder;
 import org.opendaylight.yangtools.sal.binding.model.api.type.builder.GeneratedPropertyBuilder;
@@ -41,6 +37,8 @@ import org.opendaylight.yangtools.sal.binding.model.api.type.builder.MethodSigna
 import org.opendaylight.yangtools.sal.binding.yang.types.GroupingDefinitionDependencySort;
 import org.opendaylight.yangtools.sal.binding.yang.types.TypeProviderImpl;
 import org.opendaylight.yangtools.yang.binding.DataRoot;
+import org.opendaylight.yangtools.yang.binding.Identifiable;
+import org.opendaylight.yangtools.yang.binding.Identifier;
 import org.opendaylight.yangtools.yang.binding.RpcService;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.common.RpcResult;
@@ -62,10 +60,12 @@ import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.opendaylight.yangtools.yang.model.api.SchemaNode;
 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.UsesNode;
 import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition;
 import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition;
 import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition.EnumPair;
+import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition;
 import org.opendaylight.yangtools.yang.model.util.DataNodeIterator;
 import org.opendaylight.yangtools.yang.model.util.ExtendedType;
 import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil;
@@ -102,6 +102,16 @@ public final class BindingGeneratorImpl implements BindingGenerator {
      */
     private final Map<SchemaPath, GeneratedType> allGroupings = new HashMap<SchemaPath, GeneratedType>();
 
+    /**
+     * Constant with the concrete name of namespace.
+     */
+    private final static String YANG_EXT_NAMESPACE = "urn:opendaylight:yang:extension:yang-ext";
+
+    /**
+     * Constant with the concrete name of identifier.
+     */
+    private final static String AUGMENT_IDENTIFIER_NAME = "augment-identifier";
+
     /**
      * Only parent constructor is invoked.
      */
@@ -112,10 +122,10 @@ public final class BindingGeneratorImpl implements BindingGenerator {
     /**
      * Resolves generated types from <code>context</code> schema nodes of all
      * modules.
-     * 
+     *
      * Generated types are created for modules, groupings, types, containers,
      * lists, choices, augments, rpcs, notification, identities.
-     * 
+     *
      * @param context
      *            schema context which contains data about all schema nodes
      *            saved in modules
@@ -164,10 +174,10 @@ public final class BindingGeneratorImpl implements BindingGenerator {
     /**
      * Resolves generated types from <code>context</code> schema nodes only for
      * modules specified in <code>modules</code>
-     * 
+     *
      * Generated types are created for modules, groupings, types, containers,
      * lists, choices, augments, rpcs, notification, identities.
-     * 
+     *
      * @param context
      *            schema context which contains data about all schema nodes
      *            saved in modules
@@ -232,7 +242,7 @@ public final class BindingGeneratorImpl implements BindingGenerator {
     /**
      * Converts all extended type definitions of module to the list of
      * <code>Type</code> objects.
-     * 
+     *
      * @param module
      *            module from which is obtained set of type definitions
      * @return list of <code>Type</code> which are generated from extended
@@ -243,7 +253,7 @@ public final class BindingGeneratorImpl implements BindingGenerator {
      *             <li>if name of module equals null</li>
      *             <li>if type definitions of module equal null</li>
      *             </ul>
-     * 
+     *
      */
     private List<Type> allTypeDefinitionsToGenTypes(final Module module) {
         if (module == null) {
@@ -272,7 +282,7 @@ public final class BindingGeneratorImpl implements BindingGenerator {
     /**
      * Converts all <b>containers</b> of the module to the list of
      * <code>Type</code> objects.
-     * 
+     *
      * @param module
      *            module from which is obtained DataNodeIterator to iterate over
      *            all containers
@@ -284,7 +294,7 @@ public final class BindingGeneratorImpl implements BindingGenerator {
      *             <li>if the name of module equals null</li>
      *             <li>if the set of child nodes equals null</li>
      *             </ul>
-     * 
+     *
      */
     private List<Type> allContainersToGenTypes(final Module module) {
         if (module == null) {
@@ -315,7 +325,7 @@ public final class BindingGeneratorImpl implements BindingGenerator {
     /**
      * Converts all <b>lists</b> of the module to the list of <code>Type</code>
      * objects.
-     * 
+     *
      * @param module
      *            module from which is obtained DataNodeIterator to iterate over
      *            all lists
@@ -327,7 +337,7 @@ public final class BindingGeneratorImpl implements BindingGenerator {
      *             <li>if the name of module equals null</li>
      *             <li>if the set of child nodes equals null</li>
      *             </ul>
-     * 
+     *
      */
     private List<Type> allListsToGenTypes(final Module module) {
         if (module == null) {
@@ -360,7 +370,7 @@ public final class BindingGeneratorImpl implements BindingGenerator {
     /**
      * Converts all <b>choices</b> of the module to the list of
      * <code>Type</code> objects.
-     * 
+     *
      * @param module
      *            module from which is obtained DataNodeIterator to iterate over
      *            all choices
@@ -371,7 +381,7 @@ public final class BindingGeneratorImpl implements BindingGenerator {
      *             <li>if the module equals null</li>
      *             <li>if the name of module equals null</li> *
      *             </ul>
-     * 
+     *
      */
     private List<GeneratedType> allChoicesToGenTypes(final Module module) {
         if (module == null) {
@@ -397,7 +407,7 @@ public final class BindingGeneratorImpl implements BindingGenerator {
     /**
      * Converts all <b>augmentation</b> of the module to the list
      * <code>Type</code> objects.
-     * 
+     *
      * @param module
      *            module from which is obtained list of all augmentation objects
      *            to iterate over them
@@ -409,7 +419,7 @@ public final class BindingGeneratorImpl implements BindingGenerator {
      *             <li>if the name of module equals null</li>
      *             <li>if the set of child nodes equals null</li>
      *             </ul>
-     * 
+     *
      */
     private List<Type> allAugmentsToGenTypes(final Module module) {
         if (module == null) {
@@ -436,7 +446,7 @@ public final class BindingGeneratorImpl implements BindingGenerator {
      * Returns list of <code>AugmentationSchema</code> objects. The objects are
      * sorted according to the length of their target path from the shortest to
      * the longest.
-     * 
+     *
      * @param module
      *            module from which is obtained list of all augmentation objects
      * @return list of sorted <code>AugmentationSchema</code> objects obtained
@@ -446,7 +456,7 @@ public final class BindingGeneratorImpl implements BindingGenerator {
      *             <li>if the module equals null</li>
      *             <li>if the set of augmentation equals null</li>
      *             </ul>
-     * 
+     *
      */
     private List<AugmentationSchema> resolveAugmentations(final Module module) {
         if (module == null) {
@@ -480,7 +490,7 @@ public final class BindingGeneratorImpl implements BindingGenerator {
      * Converts whole <b>module</b> to <code>GeneratedType</code> object.
      * Firstly is created the module builder object from which is finally
      * obtained reference to <code>GeneratedType</code> object.
-     * 
+     *
      * @param module
      *            module from which are obtained the module name, child nodes,
      *            uses and is derived package name
@@ -488,7 +498,7 @@ public final class BindingGeneratorImpl implements BindingGenerator {
      *         the module
      * @throws IllegalArgumentException
      *             if the module equals null
-     * 
+     *
      */
     private GeneratedType moduleToDataType(final Module module) {
         if (module == null) {
@@ -511,7 +521,7 @@ public final class BindingGeneratorImpl implements BindingGenerator {
      * Converts all <b>rpcs</b> inputs and outputs substatements of the module
      * to the list of <code>Type</code> objects. In addition are to containers
      * and lists which belong to input or output also part of returning list.
-     * 
+     *
      * @param module
      *            module from which is obtained set of all rpc objects to
      *            iterate over them
@@ -523,7 +533,7 @@ public final class BindingGeneratorImpl implements BindingGenerator {
      *             <li>if the name of module equals null</li>
      *             <li>if the set of child nodes equals null</li>
      *             </ul>
-     * 
+     *
      */
     private List<Type> allRPCMethodsToGenType(final Module module) {
         if (module == null) {
@@ -615,7 +625,7 @@ public final class BindingGeneratorImpl implements BindingGenerator {
      * Converts all <b>notifications</b> of the module to the list of
      * <code>Type</code> objects. In addition are to this list added containers
      * and lists which are part of this notification.
-     * 
+     *
      * @param module
      *            module from which is obtained set of all notification objects
      *            to iterate over them
@@ -627,7 +637,7 @@ public final class BindingGeneratorImpl implements BindingGenerator {
      *             <li>if the name of module equals null</li>
      *             <li>if the set of child nodes equals null</li>
      *             </ul>
-     * 
+     *
      */
     private List<Type> allNotificationsToGenType(final Module module) {
         if (module == null) {
@@ -678,7 +688,7 @@ public final class BindingGeneratorImpl implements BindingGenerator {
     /**
      * Converts all <b>identities</b> of the module to the list of
      * <code>Type</code> objects.
-     * 
+     *
      * @param module
      *            module from which is obtained set of all identity objects to
      *            iterate over them
@@ -687,7 +697,7 @@ public final class BindingGeneratorImpl implements BindingGenerator {
      *            {@link identityToGenType}
      * @return list of <code>Type</code> which are generated from identities
      *         (object of type <code>IdentitySchemaNode</code>
-     * 
+     *
      */
     private List<Type> allIdentitiesToGenTypes(final Module module, final SchemaContext context) {
         List<Type> genTypes = new ArrayList<>();
@@ -711,18 +721,18 @@ public final class BindingGeneratorImpl implements BindingGenerator {
      * If identity doesn't contain base identity then only reference to abstract
      * class {@link org.opendaylight.yangtools.yang.model.api.BaseIdentity
      * BaseIdentity} is added
-     * 
+     *
      * @param basePackageName
-     *            string containing package name to which identity belongs
+     *            string contains the module package name
      * @param identity
      *            IdentitySchemaNode which contains data about identity
      * @param context
      *            SchemaContext which is used to get package and name
      *            information about base of identity
-     * 
+     *
      * @return GeneratedType which is generated from identity (object of type
      *         <code>IdentitySchemaNode</code>
-     * 
+     *
      */
     private GeneratedType identityToGenType(final String basePackageName, final IdentitySchemaNode identity,
             final SchemaContext context) {
@@ -756,13 +766,13 @@ public final class BindingGeneratorImpl implements BindingGenerator {
      * dependencies. At least dependend (indepedent) groupings are in the list
      * saved at first positions. For every grouping the record is added to map
      * {@link BindingGeneratorImpl#allGroupings allGroupings}
-     * 
+     *
      * @param module
      *            module from which is obtained set of all grouping objects to
      *            iterate over them
      * @return list of <code>Type</code> which are generated from groupings
      *         (object of type <code>GroupingDefinition</code>)
-     * 
+     *
      */
     private List<Type> allGroupingsToGenTypes(final Module module) {
         if (module == null) {
@@ -788,9 +798,9 @@ public final class BindingGeneratorImpl implements BindingGenerator {
      * Converts individual grouping to GeneratedType. Firstly generated type
      * builder is created and every child node of grouping is resolved to the
      * method.
-     * 
+     *
      * @param basePackageName
-     *            string containing name of package to which grouping belongs.
+     *            string contains the module package name
      * @param grouping
      *            GroupingDefinition which contains data about grouping
      * @return GeneratedType which is generated from grouping (object of type
@@ -813,7 +823,7 @@ public final class BindingGeneratorImpl implements BindingGenerator {
      * Tries to find EnumTypeDefinition in <code>typeDefinition</code>. If base
      * type of <code>typeDefinition</code> is of the type ExtendedType then this
      * method is recursivelly called with this base type.
-     * 
+     *
      * @param typeDefinition
      *            TypeDefinition in which should be EnumTypeDefinition found as
      *            base type
@@ -834,10 +844,10 @@ public final class BindingGeneratorImpl implements BindingGenerator {
     /**
      * Adds enumeration builder created from <code>enumTypeDef</code> to
      * <code>typeBuilder</code>.
-     * 
+     *
      * Each <code>enumTypeDef</code> item is added to builder with its name and
      * value.
-     * 
+     *
      * @param enumTypeDef
      *            EnumTypeDefinition contains enum data
      * @param enumName
@@ -855,33 +865,16 @@ public final class BindingGeneratorImpl implements BindingGenerator {
 
             final String enumerationName = parseToClassName(enumName);
             final EnumBuilder enumBuilder = typeBuilder.addEnumeration(enumerationName);
+            enumBuilder.updateEnumPairsFromEnumTypeDef(enumTypeDef);
 
-            if (enumBuilder != null) {
-                final List<EnumPair> enums = enumTypeDef.getValues();
-                if (enums != null) {
-                    int listIndex = 0;
-                    for (final EnumPair enumPair : enums) {
-                        if (enumPair != null) {
-                            final String enumPairName = parseToClassName(enumPair.getName());
-                            Integer enumPairValue = enumPair.getValue();
-
-                            if (enumPairValue == null) {
-                                enumPairValue = listIndex;
-                            }
-                            enumBuilder.addValue(enumPairName, enumPairValue);
-                            listIndex++;
-                        }
-                    }
-                }
-                return enumBuilder;
-            }
+            return enumBuilder;
         }
         return null;
     }
 
     /**
      * Generates type builder for <code>module</code>.
-     * 
+     *
      * @param module
      *            Module which is source of package name for generated type
      *            builder
@@ -910,7 +903,7 @@ public final class BindingGeneratorImpl implements BindingGenerator {
      * generated types for all containers, list and choices which are child of
      * <code>augSchema</code> node or a generated types for cases are added if
      * augmented node is choice.
-     * 
+     *
      * @param augmentPackageName
      *            string with the name of the package to which the augmentation
      *            belongs
@@ -971,10 +964,10 @@ public final class BindingGeneratorImpl implements BindingGenerator {
 
     /**
      * Returns a generated type builder for an augmentation.
-     * 
+     *
      * The name of the type builder is equal to the name of augmented node with
      * serial number as suffix.
-     * 
+     *
      * @param augmentPackageName
      *            string with contains the package name to which the augment
      *            belongs
@@ -996,8 +989,10 @@ public final class BindingGeneratorImpl implements BindingGenerator {
             augmentBuilders = new HashMap<>();
             genTypeBuilders.put(augmentPackageName, augmentBuilders);
         }
+        final String augIdentifier = getAugmentIdentifier(augSchema.getUnknownSchemaNodes());
 
-        final String augTypeName = augGenTypeName(augmentBuilders, targetTypeName);
+        final String augTypeName = augIdentifier != null ? parseToClassName(augIdentifier) : augGenTypeName(
+                augmentBuilders, targetTypeName);
         final Type targetTypeRef = new ReferencedTypeImpl(targetPackageName, targetTypeName);
         final Set<DataSchemaNode> augChildNodes = augSchema.getChildNodes();
 
@@ -1012,16 +1007,33 @@ public final class BindingGeneratorImpl implements BindingGenerator {
         return augTypeBuilder;
     }
 
+    /**
+     * 
+     * @param unknownSchemaNodes
+     * @return
+     */
+    private String getAugmentIdentifier(List<UnknownSchemaNode> unknownSchemaNodes) {
+        String ret = null;
+        for (UnknownSchemaNode unknownSchemaNode : unknownSchemaNodes) {
+            QName nodeType = unknownSchemaNode.getNodeType();
+            if (AUGMENT_IDENTIFIER_NAME.equals(nodeType.getLocalName())
+                    && YANG_EXT_NAMESPACE.equals(nodeType.getNamespace().toString())) {
+                return unknownSchemaNode.getNodeParameter();
+            }
+        }
+        return ret;
+    }
+
     /**
      * Convert a container, list and choice subnodes (and recursivelly their
      * subnodes) of augment to generated types
-     * 
+     *
      * @param augBasePackageName
      *            string with the augment package name
      * @param augChildNodes
      *            set of data schema nodes which represents child nodes of the
      *            augment
-     * 
+     *
      * @return list of <code>Type</code> which represents container, list and
      *         choice subnodes of augment
      */
@@ -1075,7 +1087,7 @@ public final class BindingGeneratorImpl implements BindingGenerator {
      * Returns first unique name for the augment generated type builder. The
      * generated type builder name for augment consists from name of augmented
      * node and serial number of its augmentation.
-     * 
+     *
      * @param builders
      *            map of builders which were created in the package to which the
      *            augmentation belongs
@@ -1099,10 +1111,9 @@ public final class BindingGeneratorImpl implements BindingGenerator {
      * generated type builder is created. The subnodes of
      * <code>containerNode</code> are added as methods and the instance of
      * <code>GeneratedType</code> is returned.
-     * 
+     *
      * @param basePackageName
-     *            string with name of the package to which the superior node
-     *            belongs
+     *            string contains the module package name
      * @param containerNode
      *            container schema node with the data about childs nodes and
      *            schema paths
@@ -1122,11 +1133,25 @@ public final class BindingGeneratorImpl implements BindingGenerator {
     }
 
     /**
-     * 
+     * Adds the methods to <code>typeBuilder</code> which represent subnodes of
+     * node for which <code>typeBuilder</code> was created.
+     *
+     * The subnodes aren't mapped to the methods if they are part of grouping or
+     * augment (in this case are already part of them).
+     *
      * @param basePackageName
+     *            string contains the module package name
      * @param typeBuilder
+     *            generated type builder which represents any node. The subnodes
+     *            of this node are added to the <code>typeBuilder</code> as
+     *            methods. The subnode can be of type leaf, leaf-list, list,
+     *            container, choice.
      * @param schemaNodes
-     * @return
+     *            set of data schema nodes which are the children of the node
+     *            for which <code>typeBuilder</code> was created
+     * @return generated type builder which is the same builder as input
+     *         parameter. The getter methods (representing child nodes) could be
+     *         added to it.
      */
     private GeneratedTypeBuilder resolveDataSchemaNodes(final String basePackageName,
             final GeneratedTypeBuilder typeBuilder, final Set<DataSchemaNode> schemaNodes) {
@@ -1141,6 +1166,24 @@ public final class BindingGeneratorImpl implements BindingGenerator {
         return typeBuilder;
     }
 
+    /**
+     * Adds the methods to <code>typeBuilder</code> what represents subnodes of
+     * node for which <code>typeBuilder</code> was created.
+     *
+     * @param basePackageName
+     *            string contains the module package name
+     * @param typeBuilder
+     *            generated type builder which represents any node. The subnodes
+     *            of this node are added to the <code>typeBuilder</code> as
+     *            methods. The subnode can be of type leaf, leaf-list, list,
+     *            container, choice.
+     * @param schemaNodes
+     *            set of data schema nodes which are the children of the node
+     *            for which <code>typeBuilder</code> was created
+     * @return generated type builder which is the same object as the input
+     *         parameter <code>typeBuilder</code>. The getter method could be
+     *         added to it.
+     */
     private GeneratedTypeBuilder augSchemaNodeToMethods(final String basePackageName,
             final GeneratedTypeBuilder typeBuilder, final Set<DataSchemaNode> schemaNodes) {
         if ((schemaNodes != null) && (typeBuilder != null)) {
@@ -1153,6 +1196,19 @@ public final class BindingGeneratorImpl implements BindingGenerator {
         return typeBuilder;
     }
 
+    /**
+     * Adds to <code>typeBuilder</code> a method which is derived from
+     * <code>schemaNode</code>.
+     *
+     * @param basePackageName
+     *            string with the module package name
+     * @param schemaNode
+     *            data schema node which is added to <code>typeBuilder</code> as
+     *            a method
+     * @param typeBuilder
+     *            generated type builder to which is <code>schemaNode</code>
+     *            added as a method.
+     */
     private void addSchemaNodeToBuilderAsMethod(final String basePackageName, final DataSchemaNode schemaNode,
             final GeneratedTypeBuilder typeBuilder) {
         if (schemaNode != null && typeBuilder != null) {
@@ -1170,6 +1226,31 @@ public final class BindingGeneratorImpl implements BindingGenerator {
         }
     }
 
+    /**
+     * Creates a getter method for a choice node.
+     *
+     * Firstly generated type builder for choice is created or found in
+     * {@link BindingGeneratorImpl#allGroupings allGroupings}. The package name
+     * in the builder is created as concatenation of module package name and
+     * names of all parent nodes. In the end the getter method for choice is
+     * added to <code>typeBuilder</code> and return type is set to choice
+     * builder.
+     *
+     * @param basePackageName
+     *            string with the module package name
+     * @param typeBuilder
+     *            generated type builder to which is <code>choiceNode</code>
+     *            added as getter method
+     * @param choiceNode
+     *            choice node which is mapped as a getter method
+     * @throws IllegalArgumentException
+     *             <ul>
+     *             <li>if <code>basePackageName</code> equals null</li>
+     *             <li>if <code>typeBuilder</code> equals null</li>
+     *             <li>if <code>choiceNode</code> equals null</li>
+     *             </ul>
+     *
+     */
     private void resolveChoiceSchemaNode(final String basePackageName, final GeneratedTypeBuilder typeBuilder,
             final ChoiceNode choiceNode) {
         if (basePackageName == null) {
@@ -1190,6 +1271,29 @@ public final class BindingGeneratorImpl implements BindingGenerator {
         }
     }
 
+    /**
+     * Converts <code>choiceNode</code> to the list of generated types for
+     * choice and its cases.
+     *
+     * The package names for choice and for its cases are created as
+     * concatenation of the module package (<code>basePackageName</code>) and
+     * names of all parents node.
+     *
+     * @param basePackageName
+     *            string with the module package name
+     * @param choiceNode
+     *            choice node which is mapped to generated type. Also child
+     *            nodes - cases are mapped to generated types.
+     * @return list of generated types which contains generated type for choice
+     *         and generated types for all cases which aren't added do choice
+     *         through <i>uses</i>.
+     * @throws IllegalArgumentException
+     *             <ul>
+     *             <li>if <code>basePackageName</code> equals null</li>
+     *             <li>if <code>choiceNode</code> equals null</li>
+     *             </ul>
+     *
+     */
     private List<GeneratedType> choiceToGeneratedType(final String basePackageName, final ChoiceNode choiceNode) {
         if (basePackageName == null) {
             throw new IllegalArgumentException("Base Package Name cannot be NULL!");
@@ -1212,6 +1316,32 @@ public final class BindingGeneratorImpl implements BindingGenerator {
         return generatedTypes;
     }
 
+    /**
+     * Converts <code>caseNodes</code> set to list of corresponding generated
+     * types.
+     *
+     * For every <i>case</i> which isn't added through augment or <i>uses</i> is
+     * created generated type builder. The package names for the builder is
+     * created as concatenation of the module package (
+     * <code>basePackageName</code>) and names of all parents nodes of the
+     * concrete <i>case</i>. There is also relation "<i>implements type</i>"
+     * between every case builder and <i>choice</i> type
+     *
+     * @param basePackageName
+     *            string with the module package name
+     * @param refChoiceType
+     *            type which represents superior <i>case</i>
+     * @param caseNodes
+     *            set of choice case nodes which are mapped to generated types
+     * @return list of generated types for <code>caseNodes</code>.
+     * @throws IllegalArgumentException
+     *             <ul>
+     *             <li>if <code>basePackageName</code> equals null</li>
+     *             <li>if <code>refChoiceType</code> equals null</li>
+     *             <li>if <code>caseNodes</code> equals null</li>
+     *             </ul>
+     *             *
+     */
     private List<GeneratedType> generateTypesFromChoiceCases(final String basePackageName, final Type refChoiceType,
             final Set<ChoiceCaseNode> caseNodes) {
         if (basePackageName == null) {
@@ -1245,8 +1375,8 @@ public final class BindingGeneratorImpl implements BindingGenerator {
     /**
      * Generates list of generated types for all the cases of a choice which are
      * added to the choice through the augment.
-     * 
-     * 
+     *
+     *
      * @param basePackageName
      *            string contains name of package to which augment belongs. If
      *            an augmented choice is from an other package (pcg1) than an
@@ -1297,6 +1427,23 @@ public final class BindingGeneratorImpl implements BindingGenerator {
         return generatedTypes;
     }
 
+    /**
+     * Converts <code>leaf</code> to the getter method which is added to
+     * <code>typeBuilder</code>.
+     *
+     * @param typeBuilder
+     *            generated type builder to which is added getter method as
+     *            <code>leaf</code> mapping
+     * @param leaf
+     *            leaf schema node which is mapped as getter method which is
+     *            added to <code>typeBuilder</code>
+     * @return boolean value
+     *         <ul>
+     *         <li>false - if <code>leaf</code> or <code>typeBuilder</code> are
+     *         null</li>
+     *         <li>true - in other cases</li>
+     *         </ul>
+     */
     private boolean resolveLeafSchemaNodeAsMethod(final GeneratedTypeBuilder typeBuilder, final LeafSchemaNode leaf) {
         if ((leaf != null) && (typeBuilder != null)) {
             final String leafName = leaf.getQName().getLocalName();
@@ -1305,6 +1452,7 @@ public final class BindingGeneratorImpl implements BindingGenerator {
                 leafDesc = "";
             }
 
+            final Module parentModule = findParentModule(schemaContext, leaf);
             if (leafName != null && !leaf.isAddedByUses()) {
                 final TypeDefinition<?> typeDef = leaf.getType();
 
@@ -1320,12 +1468,12 @@ public final class BindingGeneratorImpl implements BindingGenerator {
                     }
                     ((TypeProviderImpl) typeProvider).putReferencedType(leaf.getPath(), returnType);
                 } else if (typeDef instanceof UnionType) {
-                    GeneratedTOBuilder genTOBuilder = addEnclosedTOToTypeBuilder(typeDef, typeBuilder, leafName);
+                    GeneratedTOBuilder genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, leafName, parentModule);
                     if (genTOBuilder != null) {
                         returnType = new ReferencedTypeImpl(genTOBuilder.getPackageName(), genTOBuilder.getName());
                     }
                 } else if (typeDef instanceof BitsTypeDefinition) {
-                    GeneratedTOBuilder genTOBuilder = addEnclosedTOToTypeBuilder(typeDef, typeBuilder, leafName);
+                    GeneratedTOBuilder genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, leafName, parentModule);
                     if (genTOBuilder != null) {
                         returnType = new ReferencedTypeImpl(genTOBuilder.getPackageName(), genTOBuilder.getName());
                     }
@@ -1341,6 +1489,25 @@ public final class BindingGeneratorImpl implements BindingGenerator {
         return false;
     }
 
+    /**
+     * Converts <code>leaf</code> schema node to property of generated TO
+     * builder.
+     *
+     * @param toBuilder
+     *            generated TO builder to which is <code>leaf</code> added as
+     *            property
+     * @param leaf
+     *            leaf schema node which is added to <code>toBuilder</code> as
+     *            property
+     * @param isReadOnly
+     *            boolean value which says if leaf property is|isn't read only
+     * @return boolean value
+     *         <ul>
+     *         <li>false - if <code>leaf</code>, <code>toBuilder</code> or leaf
+     *         name equals null or if leaf is added by <i>uses</i>.</li>
+     *         <li>true - other cases</li>
+     *         </ul>
+     */
     private boolean resolveLeafSchemaNodeAsProperty(final GeneratedTOBuilder toBuilder, final LeafSchemaNode leaf,
             boolean isReadOnly) {
         if ((leaf != null) && (toBuilder != null)) {
@@ -1374,6 +1541,23 @@ public final class BindingGeneratorImpl implements BindingGenerator {
         return false;
     }
 
+    /**
+     * Converts <code>node</code> leaf list schema node to getter method of
+     * <code>typeBuilder</code>.
+     *
+     * @param typeBuilder
+     *            generated type builder to which is <code>node</code> added as
+     *            getter method
+     * @param node
+     *            leaf list schema node which is added to
+     *            <code>typeBuilder</code> as getter method
+     * @return boolean value
+     *         <ul>
+     *         <li>true - if <code>node</code>, <code>typeBuilder</code>,
+     *         nodeName equal null or <code>node</code> is added by <i>uses</i></li>
+     *         <li>false - other cases</li>
+     *         </ul>
+     */
     private boolean resolveLeafListSchemaNode(final GeneratedTypeBuilder typeBuilder, final LeafListSchemaNode node) {
         if ((node != null) && (typeBuilder != null)) {
             final String nodeName = node.getQName().getLocalName();
@@ -1393,6 +1577,32 @@ public final class BindingGeneratorImpl implements BindingGenerator {
         return false;
     }
 
+    /**
+     * Creates a getter method for a container node.
+     *
+     * Firstly generated type builder for container is created or found in
+     * {@link BindingGeneratorImpl#allGroupings allGroupings}. The package name
+     * in the builder is created as concatenation of module package name and
+     * names of all parent nodes. In the end the getter method for container is
+     * added to <code>typeBuilder</code> and return type is set to container
+     * type builder.
+     *
+     * @param basePackageName
+     *            string with the module package name
+     * @param typeBuilder
+     *            generated type builder to which is <code>containerNode</code>
+     *            added as getter method
+     * @param containerNode
+     *            container schema node which is mapped as getter method to
+     *            <code>typeBuilder</code>
+     * @return boolean value
+     *         <ul>
+     *         <li>false - if <code>containerNode</code>,
+     *         <code>typeBuilder</code>, container node name equal null or
+     *         <code>containerNode</code> is added by uses</li>
+     *         <li>true - other cases</li>
+     *         </ul>
+     */
     private boolean resolveContainerSchemaNode(final String basePackageName, final GeneratedTypeBuilder typeBuilder,
             final ContainerSchemaNode containerNode) {
         if ((containerNode != null) && (typeBuilder != null)) {
@@ -1410,15 +1620,40 @@ public final class BindingGeneratorImpl implements BindingGenerator {
         return false;
     }
 
+    /**
+     * Creates a getter method for a list node.
+     *
+     * Firstly generated type builder for list is created or found in
+     * {@link BindingGeneratorImpl#allGroupings allGroupings}. The package name
+     * in the builder is created as concatenation of module package name and
+     * names of all parent nodes. In the end the getter method for list is added
+     * to <code>typeBuilder</code> and return type is set to list type builder.
+     *
+     * @param basePackageName
+     *            string with the module package name
+     * @param typeBuilder
+     *            generated type builder to which is <code></code> added as
+     *            getter method
+     * @param listNode
+     *            list schema node which is mapped as getter method to
+     *            <code>typeBuilder</code>
+     * @return boolean value
+     *         <ul>
+     *         <li>false - if <code>listNode</code>, <code>typeBuilder</code>,
+     *         list node name equal null or <code>listNode</code> is added by
+     *         uses</li>
+     *         <li>true - other cases</li>
+     *         </ul>
+     */
     private boolean resolveListSchemaNode(final String basePackageName, final GeneratedTypeBuilder typeBuilder,
-            final ListSchemaNode schemaNode) {
-        if ((schemaNode != null) && (typeBuilder != null)) {
-            final String listName = schemaNode.getQName().getLocalName();
-
-            if (listName != null && !schemaNode.isAddedByUses()) {
-                final String packageName = packageNameForGeneratedType(basePackageName, schemaNode.getPath());
-                final GeneratedTypeBuilder rawGenType = addDefaultInterfaceDefinition(packageName, schemaNode);
-                constructGetter(typeBuilder, listName, schemaNode.getDescription(), Types.listTypeFor(rawGenType));
+            final ListSchemaNode listNode) {
+        if ((listNode != null) && (typeBuilder != null)) {
+            final String listName = listNode.getQName().getLocalName();
+
+            if (listName != null && !listNode.isAddedByUses()) {
+                final String packageName = packageNameForGeneratedType(basePackageName, listNode.getPath());
+                final GeneratedTypeBuilder rawGenType = addDefaultInterfaceDefinition(packageName, listNode);
+                constructGetter(typeBuilder, listName, listNode.getDescription(), Types.listTypeFor(rawGenType));
                 return true;
             }
         }
@@ -1426,14 +1661,25 @@ public final class BindingGeneratorImpl implements BindingGenerator {
     }
 
     /**
-     * Method instantiates new Generated Type Builder and sets the implements
-     * definitions of Data Object and Augmentable.
-     * 
+     * Instantiates generated type builder with <code>packageName</code> and
+     * <code>schemaNode</code>.
+     *
+     * The new builder always implements
+     * {@link org.opendaylight.yangtools.yang.binding.DataObject DataObject}.<br />
+     * If <code>schemaNode</code> is instance of GroupingDefinition it also
+     * implements {@link org.opendaylight.yangtools.yang.binding.Augmentable
+     * Augmentable}.<br />
+     * If <code>schemaNode</code> is instance of
+     * {@link org.opendaylight.yangtools.yang.model.api.DataNodeContainer
+     * DataNodeContainer} it can also implement nodes which are specified in
+     * <i>uses</i>.
+     *
      * @param packageName
-     *            Generated Type Package Name
+     *            string with the name of the package to which
+     *            <code>schemaNode</code> belongs.
      * @param schemaNode
-     *            Schema Node definition
-     * @return Generated Type Builder instance for Schema Node definition
+     *            schema node for which is created generated type builder
+     * @return generated type builder <code>schemaNode</code>
      */
     private GeneratedTypeBuilder addDefaultInterfaceDefinition(final String packageName, final SchemaNode schemaNode) {
         final GeneratedTypeBuilder builder = addRawInterfaceDefinition(packageName, schemaNode, "");
@@ -1450,15 +1696,42 @@ public final class BindingGeneratorImpl implements BindingGenerator {
     }
 
     /**
-     * 
+     * Wraps the calling of the same overloaded method.
+     *
      * @param packageName
+     *            string with the package name to which returning generated type
+     *            builder belongs
      * @param schemaNode
-     * @return
+     *            schema node which provide data about the schema node name
+     * @return generated type builder for <code>schemaNode</code>
      */
     private GeneratedTypeBuilder addRawInterfaceDefinition(final String packageName, final SchemaNode schemaNode) {
         return addRawInterfaceDefinition(packageName, schemaNode, "");
     }
 
+    /**
+     * Returns reference to generated type builder for specified
+     * <code>schemaNode</code> with <code>packageName</code>.
+     *
+     * Firstly the generated type builder is searched in
+     * {@link BindingGeneratorImpl#genTypeBuilders genTypeBuilders}. If it isn't
+     * found it is created and added to <code>genTypeBuilders</code>.
+     *
+     * @param packageName
+     *            string with the package name to which returning generated type
+     *            builder belongs
+     * @param schemaNode
+     *            schema node which provide data about the schema node name
+     * @return generated type builder for <code>schemaNode</code>
+     * @throws IllegalArgumentException
+     *             <ul>
+     *             <li>if <code>schemaNode</code> equals null</li>
+     *             <li>if <code>packageName</code> equals null</li>
+     *             <li>if Q name of schema node is null</li>
+     *             <li>if schema node name is nul</li>
+     *             </ul>
+     *
+     */
     private GeneratedTypeBuilder addRawInterfaceDefinition(final String packageName, final SchemaNode schemaNode,
             final String prefix) {
         if (schemaNode == null) {
@@ -1496,6 +1769,14 @@ public final class BindingGeneratorImpl implements BindingGenerator {
         return newType;
     }
 
+    /**
+     * Creates the name of the getter method from <code>methodName</code>.
+     *
+     * @param methodName
+     *            string with the name of the getter method
+     * @return string with the name of the getter method for
+     *         <code>methodName</code> in JAVA method format
+     */
     private String getterMethodName(final String methodName) {
         final StringBuilder method = new StringBuilder();
         method.append("get");
@@ -1503,6 +1784,14 @@ public final class BindingGeneratorImpl implements BindingGenerator {
         return method.toString();
     }
 
+    /**
+     * Creates the name of the setter method from <code>methodName</code>.
+     *
+     * @param methodName
+     *            string with the name of the setter method
+     * @return string with the name of the setter method for
+     *         <code>methodName</code> in JAVA method format
+     */
     private String setterMethodName(final String methodName) {
         final StringBuilder method = new StringBuilder();
         method.append("set");
@@ -1510,6 +1799,27 @@ public final class BindingGeneratorImpl implements BindingGenerator {
         return method.toString();
     }
 
+    /**
+     * Created a method signature builder as part of
+     * <code>interfaceBuilder</code>.
+     *
+     * The method signature builder is created for the getter method of
+     * <code>schemaNodeName</code>. Also <code>comment</code> and
+     * <code>returnType</code> information are added to the builder.
+     *
+     * @param interfaceBuilder
+     *            generated type builder for which the getter method should be
+     *            created
+     * @param schemaNodeName
+     *            string with schema node name. The name will be the part of the
+     *            getter method name.
+     * @param comment
+     *            string with comment for the getter method
+     * @param returnType
+     *            type which represents the return type of the getter method
+     * @return method signature builder which represents the getter method of
+     *         <code>interfaceBuilder</code>
+     */
     private MethodSignatureBuilder constructGetter(final GeneratedTypeBuilder interfaceBuilder,
             final String schemaNodeName, final String comment, final Type returnType) {
         final MethodSignatureBuilder getMethod = interfaceBuilder.addMethod(getterMethodName(schemaNodeName));
@@ -1520,6 +1830,29 @@ public final class BindingGeneratorImpl implements BindingGenerator {
         return getMethod;
     }
 
+    /**
+     * Creates a method signature builder as a part of
+     * <code>interfaceBuilder</code> for <code>schemaNodeName</code>
+     *
+     * The method signature builder is created for the setter method of
+     * <code>schemaNodeName</code>. Also <code>comment</code>
+     * <code>parameterType</code> data are added to the builder. The return type
+     * of the method is set to <code>void</code>.
+     *
+     * @param interfaceBuilder
+     *            generated type builder for which the setter method should be
+     *            created
+     * @param schemaNodeName
+     *            string with schema node name. The name will be the part of the
+     *            setter method name.
+     * @param comment
+     *            string with comment for the setter method
+     * @param parameterType
+     *            type which represents the type of the setter method input
+     *            parameter
+     * @return method signature builder which represents the setter method of
+     *         <code>interfaceBuilder</code>
+     */
     private MethodSignatureBuilder constructSetter(final GeneratedTypeBuilder interfaceBuilder,
             final String schemaNodeName, final String comment, final Type parameterType) {
         final MethodSignatureBuilder setMethod = interfaceBuilder.addMethod(setterMethodName(schemaNodeName));
@@ -1540,10 +1873,21 @@ public final class BindingGeneratorImpl implements BindingGenerator {
         }
 
         final String packageName = packageNameForGeneratedType(basePackageName, list.getPath());
-        final GeneratedTypeBuilder typeBuilder = resolveListTypeBuilder(packageName, list);
+        // final GeneratedTypeBuilder typeBuilder =
+        // resolveListTypeBuilder(packageName, list);
+        final GeneratedTypeBuilder typeBuilder = addDefaultInterfaceDefinition(packageName, list);
+
         final List<String> listKeys = listKeys(list);
-        GeneratedTOBuilder genTOBuilder = resolveListKeyTOBuilder(packageName, list, listKeys);
+        GeneratedTOBuilder genTOBuilder = resolveListKeyTOBuilder(packageName, list);
 
+        if (genTOBuilder != null) {
+            ParameterizedType identifierMarker = Types.parameterizedTypeFor(Types.typeForClass(Identifier.class),
+                    typeBuilder);
+            ParameterizedType identifiableMarker = Types.parameterizedTypeFor(Types.typeForClass(Identifiable.class),
+                    genTOBuilder);
+            genTOBuilder.addImplementsType(identifierMarker);
+            typeBuilder.addImplementsType(identifiableMarker);
+        }
         final Set<DataSchemaNode> schemaNodes = list.getChildNodes();
 
         for (final DataSchemaNode schemaNode : schemaNodes) {
@@ -1555,6 +1899,28 @@ public final class BindingGeneratorImpl implements BindingGenerator {
         return typeBuildersToGenTypes(typeBuilder, genTOBuilder);
     }
 
+    /**
+     * Adds <code>schemaNode</code> to <code>typeBuilder</code> as getter method
+     * or to <code>genTOBuilder</code> as property.
+     *
+     * @param basePackageName
+     *            string contains the module package name
+     * @param schemaNode
+     *            data schema node which should be added as getter method to
+     *            <code>typeBuilder</code> or as a property to
+     *            <code>genTOBuilder</code> if is part of the list key
+     * @param typeBuilder
+     *            generated type builder for the list schema node
+     * @param genTOBuilder
+     *            generated TO builder for the list keys
+     * @param listKeys
+     *            list of string which contains names of the list keys
+     * @throws IllegalArgumentException
+     *             <ul>
+     *             <li>if <code>schemaNode</code> equals null</li>
+     *             <li>if <code>typeBuilder</code> equals null</li>
+     *             </ul>
+     */
     private void addSchemaNodeToListBuilders(final String basePackageName, final DataSchemaNode schemaNode,
             final GeneratedTypeBuilder typeBuilder, final GeneratedTOBuilder genTOBuilder, final List<String> listKeys) {
         if (schemaNode == null) {
@@ -1567,7 +1933,8 @@ public final class BindingGeneratorImpl implements BindingGenerator {
 
         if (schemaNode instanceof LeafSchemaNode) {
             final LeafSchemaNode leaf = (LeafSchemaNode) schemaNode;
-            if (!isPartOfListKey(leaf, listKeys)) {
+            final String leafName = leaf.getQName().getLocalName();
+            if (!listKeys.contains(leafName)) {
                 resolveLeafSchemaNodeAsMethod(typeBuilder, leaf);
             } else {
                 resolveLeafSchemaNodeAsProperty(genTOBuilder, leaf, true);
@@ -1589,7 +1956,7 @@ public final class BindingGeneratorImpl implements BindingGenerator {
 
         if (genTOBuilder != null) {
             final GeneratedTransferObject genTO = genTOBuilder.toInstance();
-            constructGetter(typeBuilder, genTO.getName(), "Returns Primary Key of Yang List Type", genTO);
+            constructGetter(typeBuilder, "key", "Returns Primary Key of Yang List Type", genTO);
             genTypes.add(genTO);
         }
         genTypes.add(typeBuilder.toInstance());
@@ -1597,24 +1964,15 @@ public final class BindingGeneratorImpl implements BindingGenerator {
     }
 
     /**
+     * Selects the names of the list keys from <code>list</code> and returns
+     * them as the list of the strings
+     *
      * @param list
-     * @return
+     *            of string with names of the list keys
+     * @return list of string which represents names of the list keys. If the
+     *         <code>list</code> contains no keys then the empty list is
+     *         returned.
      */
-    private GeneratedTOBuilder resolveListKey(final String packageName, final ListSchemaNode list) {
-        final String listName = list.getQName().getLocalName() + "Key";
-        return schemaNodeToTransferObjectBuilder(packageName, list, listName);
-    }
-
-    private boolean isPartOfListKey(final LeafSchemaNode leaf, final List<String> keys) {
-        if ((leaf != null) && (keys != null) && (leaf.getQName() != null)) {
-            final String leafName = leaf.getQName().getLocalName();
-            if (keys.contains(leafName)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
     private List<String> listKeys(final ListSchemaNode list) {
         final List<String> listKeys = new ArrayList<>();
 
@@ -1628,67 +1986,88 @@ public final class BindingGeneratorImpl implements BindingGenerator {
         return listKeys;
     }
 
-    private GeneratedTypeBuilder resolveListTypeBuilder(final String packageName, final ListSchemaNode list) {
-        if (packageName == null) {
-            throw new IllegalArgumentException("Package Name for Generated Type cannot be NULL!");
-        }
-        if (list == null) {
-            throw new IllegalArgumentException("List Schema Node cannot be NULL!");
-        }
-
-        final String schemaNodeName = list.getQName().getLocalName();
-        final String genTypeName = parseToClassName(schemaNodeName);
-
-        GeneratedTypeBuilder typeBuilder = null;
-        final Map<String, GeneratedTypeBuilder> builders = genTypeBuilders.get(packageName);
-        if (builders != null) {
-            typeBuilder = builders.get(genTypeName);
-        }
-        if (typeBuilder == null) {
-            typeBuilder = addDefaultInterfaceDefinition(packageName, list);
-        }
-        return typeBuilder;
-    }
-
-    private GeneratedTOBuilder resolveListKeyTOBuilder(final String packageName, final ListSchemaNode list,
-            final List<String> listKeys) {
+    /**
+     * Generates for the <code>list</code> which contains any list keys special
+     * generated TO builder.
+     *
+     * @param packageName
+     *            string with package name to which the list belongs
+     * @param list
+     *            list schema node which is source of data about the list name
+     * @return generated TO builder which represents the keys of the
+     *         <code>list</code> or null if <code>list</code> is null or list of
+     *         key definitions is null or empty.
+     */
+    private GeneratedTOBuilder resolveListKeyTOBuilder(final String packageName, final ListSchemaNode list) {
         GeneratedTOBuilder genTOBuilder = null;
-        if (listKeys.size() > 0) {
-            genTOBuilder = resolveListKey(packageName, list);
+        if ((list.getKeyDefinition() != null) && (!list.getKeyDefinition().isEmpty())) {
+            if (list != null) {
+                final String listName = list.getQName().getLocalName() + "Key";
+                genTOBuilder = schemaNodeToTransferObjectBuilder(packageName, listName);
+            }
         }
         return genTOBuilder;
+
     }
 
-    private GeneratedTOBuilder addEnclosedTOToTypeBuilder(TypeDefinition<?> typeDef, GeneratedTypeBuilder typeBuilder,
-            String leafName) {
-        String className = parseToClassName(leafName);
-        GeneratedTOBuilder genTOBuilder = null;
-        if (typeDef instanceof UnionType) {
-            genTOBuilder = ((TypeProviderImpl) typeProvider).addUnionGeneratedTypeDefinition(
-                    typeBuilder.getFullyQualifiedName(), typeDef, className);
+    /**
+     * Builds generated TO builders for <code>typeDef</code> of type
+     * {@link org.opendaylight.yangtools.yang.model.util.UnionType UnionType} or
+     * {@link org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition
+     * BitsTypeDefinition} which are also added to <code>typeBuilder</code> as
+     * enclosing transfer object.
+     *
+     * If more then one generated TO builder is created for enclosing then all
+     * of the generated TO builders are added to <code>typeBuilder</code> as
+     * enclosing transfer objects.
+     * 
+     * @param typeDef
+     *            type definition which can be of type <code>UnionType</code> or
+     *            <code>BitsTypeDefinition</code>
+     * @param typeBuilder
+     *            generated type builder to which is added generated TO created
+     *            from <code>typeDef</code>
+     * @param leafName
+     *            string with name for generated TO builder
+     * @return generated TO builder for <code>typeDef</code>
+     */
+    private GeneratedTOBuilder addTOToTypeBuilder(TypeDefinition<?> typeDef, GeneratedTypeBuilder typeBuilder,
+            String leafName, Module parentModule) {
+        final String classNameFromLeaf = parseToClassName(leafName);
+        List<GeneratedTOBuilder> genTOBuilders = new ArrayList<>();
+        final String packageName = typeBuilder.getFullyQualifiedName();
+        if (typeDef instanceof UnionTypeDefinition) {
+            genTOBuilders.addAll(((TypeProviderImpl) typeProvider).provideGeneratedTOBuildersForUnionTypeDef(
+                    packageName, typeDef, classNameFromLeaf));
         } else if (typeDef instanceof BitsTypeDefinition) {
-            genTOBuilder = ((TypeProviderImpl) typeProvider).bitsTypedefToTransferObject(
-                    typeBuilder.getFullyQualifiedName(), typeDef, className);
+            genTOBuilders.add(((TypeProviderImpl) typeProvider).provideGeneratedTOBuilderForBitsTypeDefinition(
+                    packageName, typeDef, classNameFromLeaf));
         }
-        if (genTOBuilder != null) {
-            typeBuilder.addEnclosingTransferObject(genTOBuilder);
-            return genTOBuilder;
+        if (genTOBuilders != null && !genTOBuilders.isEmpty()) {
+            for (GeneratedTOBuilder genTOBuilder : genTOBuilders) {
+                typeBuilder.addEnclosingTransferObject(genTOBuilder);
+            }
+            return genTOBuilders.get(0);
         }
         return null;
 
     }
 
     /**
-     * Adds the implemented types to type builder. The method passes through the
-     * list of elements which contains {@code dataNodeContainer} and adds them
-     * as <i>implements type</i> to <code>builder</code>
-     * 
+     * Adds the implemented types to type builder.
+     *
+     * The method passes through the list of <i>uses</i> in
+     * {@code dataNodeContainer}. For every <i>use</i> is obtained coresponding
+     * generated type from {@link BindingGeneratorImpl#allGroupings
+     * allGroupings} which is adde as <i>implements type</i> to
+     * <code>builder</code>
+     *
      * @param dataNodeContainer
      *            element which contains the list of used YANG groupings
      * @param builder
      *            builder to which are added implemented types according to
      *            <code>dataNodeContainer</code>
-     * @return generated type builder which contains implemented types
+     * @return generated type builder with all implemented types
      */
     private GeneratedTypeBuilder addImplementedInterfaceFromUses(final DataNodeContainer dataNodeContainer,
             final GeneratedTypeBuilder builder) {