Add ability to get yang sources from SchemaContext.
[yangtools.git] / code-generator / binding-generator-impl / src / main / java / org / opendaylight / yangtools / sal / binding / generator / impl / BindingGeneratorImpl.xtend
index 357aad0490ddab76e7e66c40fad322f4fb5e51d5..94d4812cd039f3c5e72b6f46d85f503d51f761fb 100644 (file)
@@ -1,18 +1,26 @@
-/*\r
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.\r
- *\r
- * This program and the accompanying materials are made available under the\r
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
- * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
  */
 package org.opendaylight.yangtools.sal.binding.generator.impl;
 
+import static com.google.common.base.Preconditions.*;
+import static extension org.opendaylight.yangtools.binding.generator.util.Types.*;
+import static org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil.*;
+import static org.opendaylight.yangtools.binding.generator.util.BindingTypes.*;
+import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.*;
+
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.Iterator
+import java.util.Collection
 import org.opendaylight.yangtools.binding.generator.util.BindingTypes;
 import org.opendaylight.yangtools.binding.generator.util.ReferencedTypeImpl;
 import org.opendaylight.yangtools.binding.generator.util.Types;
@@ -54,11 +62,6 @@ import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition;
 import org.opendaylight.yangtools.yang.model.util.DataNodeIterator;
 import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil;
 import org.opendaylight.yangtools.yang.model.util.UnionType;
-import static com.google.common.base.Preconditions.*;
-import static extension org.opendaylight.yangtools.binding.generator.util.Types.*;
-import static org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil.*;
-import static org.opendaylight.yangtools.binding.generator.util.BindingTypes.*;
-import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.*;
 import org.opendaylight.yangtools.yang.parser.util.ModuleDependencySort
 import org.opendaylight.yangtools.yang.model.util.ExtendedType;
 import org.opendaylight.yangtools.yang.model.api.UsesNode
@@ -66,66 +69,70 @@ import org.opendaylight.yangtools.yang.binding.annotations.RoutingContext
 import org.opendaylight.yangtools.sal.binding.model.api.type.builder.AnnotationTypeBuilder
 import org.opendaylight.yangtools.yang.model.api.ModuleImport
 import org.opendaylight.yangtools.yang.binding.DataContainer
-import java.util.Iterator
 import org.opendaylight.yangtools.yang.model.api.AugmentationTarget
-import java.util.Collection
-import org.opendaylight.yangtools.yang.model.api.YangNode
 import org.opendaylight.yangtools.yang.model.api.NotificationDefinition
 import org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil
 import org.opendaylight.yangtools.sal.binding.model.api.Restrictions
 import org.opendaylight.yangtools.sal.binding.model.api.type.builder.GeneratedPropertyBuilder
 import org.opendaylight.yangtools.binding.generator.util.generated.type.builder.GeneratedPropertyBuilderImpl
+import org.opendaylight.yangtools.yang.common.QName
+import org.opendaylight.yangtools.yang.binding.BindingMapping
+import org.opendaylight.yangtools.sal.binding.model.api.type.builder.GeneratedTypeBuilderBase
+
+import com.google.common.collect.Sets
+import java.net.URI
+import java.util.Date
 
 public class BindingGeneratorImpl implements BindingGenerator {
 
     private final Map<Module, ModuleContext> genCtx = new HashMap()
 
-    /**\r
-     * Outter key represents the package name. Outter value represents map of\r
-     * all builders in the same package. Inner key represents the schema node\r
-     * name (in JAVA class/interface name format). Inner value represents\r
-     * instance of builder for schema node specified in key part.\r
+    /**
+     * Outer key represents the package name. Outer value represents map of
+     * all builders in the same package. Inner key represents the schema node
+     * name (in JAVA class/interface name format). Inner value represents
+     * instance of builder for schema node specified in key part.
      */
     private Map<String, Map<String, GeneratedTypeBuilder>> genTypeBuilders;
 
-    /**\r
-     * Provide methods for converting YANG types to JAVA types.\r
+    /**
+     * Provide methods for converting YANG types to JAVA types.
      */
     private var TypeProvider typeProvider;
 
-    /**\r
-     * Holds reference to schema context to resolve data of augmented elemnt\r
-     * when creating augmentation builder\r
+    /**
+     * Holds reference to schema context to resolve data of augmented element
+     * when creating augmentation builder
      */
     private var SchemaContext schemaContext;
 
-    /**\r
-     * Constant with the concrete name of namespace.\r
+    /**
+     * Constant with the concrete name of namespace.
      */
     private val static String YANG_EXT_NAMESPACE = "urn:opendaylight:yang:extension:yang-ext";
 
-    /**\r
-     * Constant with the concrete name of identifier.\r
+    /**
+     * Constant with the concrete name of identifier.
      */
     private val static String AUGMENT_IDENTIFIER_NAME = "augment-identifier";
 
-    /**\r
-     * Resolves generated types from <code>context</code> schema nodes of all\r
-     * modules.\r
-     *\r
-     * Generated types are created for modules, groupings, types, containers,\r
-     * lists, choices, augments, rpcs, notification, identities.\r
-     *\r
-     * @param context\r
-     *            schema context which contains data about all schema nodes\r
-     *            saved in modules\r
-     * @return list of types (usually <code>GeneratedType</code>\r
-     *         <code>GeneratedTransferObject</code>which are generated from\r
-     *         <code>context</code> data.\r
-     * @throws IllegalArgumentException\r
-     *             if param <code>context</code> is null\r
-     * @throws IllegalStateException\r
-     *             if <code>context</code> contain no modules\r
+    /**
+     * 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
+     * @return list of types (usually <code>GeneratedType</code>
+     *         <code>GeneratedTransferObject</code>which are generated from
+     *         <code>context</code> data.
+     * @throws IllegalArgumentException
+     *             if param <code>context</code> is null
+     * @throws IllegalStateException
+     *             if <code>context</code> contain no modules
      */
     override generateTypes(SchemaContext context) {
         checkArgument(context !== null, "Schema Context reference cannot be NULL.");
@@ -136,33 +143,33 @@ public class BindingGeneratorImpl implements BindingGenerator {
         return generateTypes(context, modules);
     }
 
-    /**\r
-     * Resolves generated types from <code>context</code> schema nodes only for\r
-     * modules specified in <code>modules</code>\r
-     *\r
-     * Generated types are created for modules, groupings, types, containers,\r
-     * lists, choices, augments, rpcs, notification, identities.\r
-     *\r
-     * @param context\r
-     *            schema context which contains data about all schema nodes\r
-     *            saved in modules\r
-     * @param modules\r
-     *            set of modules for which schema nodes should be generated\r
-     *            types\r
-     * @return list of types (usually <code>GeneratedType</code> or\r
-     *         <code>GeneratedTransferObject</code>) which:\r
-     *         <ul>\r
-     *         <li>are generated from <code>context</code> schema nodes and</li>\r
-     *         <li>are also part of some of the module in <code>modules</code>\r
-     *         set</li>.\r
-     *         </ul>\r
-     * @throws IllegalArgumentException\r
-     *             <ul>\r
-     *             <li>if param <code>context</code> is null or</li>\r
-     *             <li>if param <code>modules</code> is null</li>\r
-     *             </ul>\r
-     * @throws IllegalStateException\r
-     *             if <code>context</code> contain no modules\r
+    /**
+     * 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
+     * @param modules
+     *            set of modules for which schema nodes should be generated
+     *            types
+     * @return list of types (usually <code>GeneratedType</code> or
+     *         <code>GeneratedTransferObject</code>) which:
+     *         <ul>
+     *         <li>are generated from <code>context</code> schema nodes and</li>
+     *         <li>are also part of some of the module in <code>modules</code>
+     *         set</li>.
+     *         </ul>
+     * @throws IllegalArgumentException
+     *             <ul>
+     *             <li>if param <code>context</code> is null or</li>
+     *             <li>if param <code>modules</code> is null</li>
+     *             </ul>
+     * @throws IllegalStateException
+     *             if <code>context</code> contain no modules
      */
     override generateTypes(SchemaContext context, Set<Module> modules) {
         checkArgument(context !== null, "Schema Context reference cannot be NULL.");
@@ -183,10 +190,13 @@ public class BindingGeneratorImpl implements BindingGenerator {
 
         val List<Type> filteredGenTypes = new ArrayList();
         for (Module m : modules) {
-            filteredGenTypes.addAll(genCtx.get(m).generatedTypes);
-
+            val ctx = checkNotNull(genCtx.get(m), "Module context not found for module %s", m)
+            filteredGenTypes.addAll(ctx.generatedTypes);
+            val Set<Type> additionalTypes = (typeProvider as TypeProviderImpl).additionalTypes.get(m)
+            if (additionalTypes != null) {
+                filteredGenTypes.addAll(additionalTypes)
+            }
         }
-        //genCtx.clear;
 
         return filteredGenTypes;
     }
@@ -207,19 +217,19 @@ public class BindingGeneratorImpl implements BindingGenerator {
         }
     }
 
-    /**\r
-     * Converts all extended type definitions of module to the list of\r
-     * <code>Type</code> objects.\r
-     *\r
-     * @param module\r
-     *            module from which is obtained set of type definitions\r
-     * @throws IllegalArgumentException\r
-     *             <ul>\r
-     *             <li>if module equals null</li>\r
-     *             <li>if name of module equals null</li>\r
-     *             <li>if type definitions of module equal null</li>\r
-     *             </ul>\r
-     *\r
+    /**
+     * 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
+     * @throws IllegalArgumentException
+     *             <ul>
+     *             <li>if module equals null</li>
+     *             <li>if name of module equals null</li>
+     *             <li>if type definitions of module equal null</li>
+     *             </ul>
+     *
      */
     private def void allTypeDefinitionsToGenTypes(Module module) {
         checkArgument(module !== null, "Module reference cannot be NULL.");
@@ -238,82 +248,87 @@ public class BindingGeneratorImpl implements BindingGenerator {
         }
     }
 
-    private def void containerToGenType(Module module, String basePackageName, GeneratedTypeBuilder parent,
-        GeneratedTypeBuilder childOf, ContainerSchemaNode node) {
+    private def GeneratedTypeBuilder processDataSchemaNode(Module module, String basePackageName,
+        GeneratedTypeBuilder parent, GeneratedTypeBuilder childOf, DataSchemaNode node) {
         if (node.augmenting || node.addedByUses) {
-            return
+            return null
         }
         val packageName = packageNameForGeneratedType(basePackageName, node.path)
         val genType = addDefaultInterfaceDefinition(packageName, node, childOf)
-        constructGetter(parent, node.QName.localName, node.description, genType)
-        genCtx.get(module).addChildNodeType(node.path, genType)
-        resolveDataSchemaNodes(module, basePackageName, genType, genType, node.childNodes)
-        groupingsToGenTypes(module, node.groupings)
-        processUsesAugments(node, module)
+        if (node instanceof DataNodeContainer) {
+            genCtx.get(module).addChildNodeType(node.path, genType)
+            groupingsToGenTypes(module, (node as DataNodeContainer).groupings)
+            processUsesAugments(node as DataNodeContainer, module)
+        }
+        return genType
     }
 
-    private def void listToGenType(Module module, String basePackageName, GeneratedTypeBuilder parent,
-        GeneratedTypeBuilder childOf, ListSchemaNode node) {
-        if (node.augmenting || node.addedByUses) {
-            return
+    private def void containerToGenType(Module module, String basePackageName, GeneratedTypeBuilder parent,
+        GeneratedTypeBuilder childOf, ContainerSchemaNode node) {
+        val genType = processDataSchemaNode(module, basePackageName, parent, childOf, node)
+        if (genType != null) {
+            constructGetter(parent, node.QName.localName, node.description, genType)
+            resolveDataSchemaNodes(module, basePackageName, genType, genType, node.childNodes)
         }
-        val packageName = packageNameForGeneratedType(basePackageName, (node).path)
-        val genType = addDefaultInterfaceDefinition(packageName, node, childOf)
-        constructGetter(parent, node.QName.localName, node.description, Types.listTypeFor(genType))
-        genCtx.get(module).addChildNodeType(node.path, genType)
-        groupingsToGenTypes(module, node.groupings)
-        processUsesAugments(node, module)
+    }
 
-        val List<String> listKeys = listKeys(node);
-        val genTOBuilder = resolveListKeyTOBuilder(packageName, node);\r
+    private def void listToGenType(Module module, String basePackageName, GeneratedTypeBuilder parent,
+        GeneratedTypeBuilder childOf, ListSchemaNode node) {
+        val genType = processDataSchemaNode(module, basePackageName, parent, childOf, node)
+        if (genType != null) {
+            constructGetter(parent, node.QName.localName, node.description, Types.listTypeFor(genType))
+
+            val List<String> listKeys = listKeys(node);
+            val packageName = packageNameForGeneratedType(basePackageName, (node).path)
+            val genTOBuilder = resolveListKeyTOBuilder(packageName, node);
+            if (genTOBuilder !== null) {
+                val identifierMarker = IDENTIFIER.parameterizedTypeFor(genType);
+                val identifiableMarker = IDENTIFIABLE.parameterizedTypeFor(genTOBuilder);
+                genTOBuilder.addImplementsType(identifierMarker);
+                genType.addImplementsType(identifiableMarker);
+            }
 
-        if (genTOBuilder !== null) {
-            val identifierMarker = IDENTIFIER.parameterizedTypeFor(genType);
-            val identifiableMarker = IDENTIFIABLE.parameterizedTypeFor(genTOBuilder);
-            genTOBuilder.addImplementsType(identifierMarker);
-            genType.addImplementsType(identifiableMarker);
-        }
+            for (schemaNode : node.childNodes) {
+                if (!schemaNode.augmenting) {
+                    addSchemaNodeToListBuilders(basePackageName, schemaNode, genType, genTOBuilder, listKeys, module);
+                }
+            }
 
-        for (schemaNode : node.childNodes) {
-            if (!schemaNode.augmenting) {
-                addSchemaNodeToListBuilders(basePackageName, schemaNode, genType, genTOBuilder, listKeys, module);
+            // serialVersionUID
+            if (genTOBuilder !== null) {
+                val GeneratedPropertyBuilder prop = new GeneratedPropertyBuilderImpl("serialVersionUID");
+                prop.setValue(Long.toString(computeDefaultSUID(genTOBuilder as GeneratedTOBuilderImpl)));
+                genTOBuilder.setSUID(prop);
             }
-        }\r
-\r
-        // serialVersionUID\r
-        if (genTOBuilder !== null) {\r
-            val GeneratedPropertyBuilder prop = new GeneratedPropertyBuilderImpl("serialVersionUID");\r
-            prop.setValue(Long.toString(computeDefaultSUID(genTOBuilder as GeneratedTOBuilderImpl)));\r
-            genTOBuilder.setSUID(prop);\r
-        }
 
-        typeBuildersToGenTypes(module, genType, genTOBuilder);
+            typeBuildersToGenTypes(module, genType, genTOBuilder);
+        }
     }
 
     private def void processUsesAugments(DataNodeContainer node, Module module) {
         val basePackageName = moduleNamespaceToPackageName(module);
         for (usesNode : node.uses) {
             for (augment : usesNode.augmentations) {
-                augmentationToGenTypes(basePackageName, augment, module, usesNode);
+                usesAugmentationToGenTypes(basePackageName, augment, module, usesNode, node);
                 processUsesAugments(augment, module);
             }
         }
     }
 
-    /**\r
-     * Converts all <b>augmentation</b> of the module to the list\r
-     * <code>Type</code> objects.\r
-     *\r
-     * @param module\r
-     *            module from which is obtained list of all augmentation objects\r
-     *            to iterate over them\r
-     * @throws IllegalArgumentException\r
-     *             <ul>\r
-     *             <li>if the module equals null</li>\r
-     *             <li>if the name of module equals null</li>\r
-     *             <li>if the set of child nodes equals null</li>\r
-     *             </ul>\r
-     *\r
+    /**
+     * 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
+     * @throws IllegalArgumentException
+     *             <ul>
+     *             <li>if the module equals null</li>
+     *             <li>if the name of module equals null</li>
+     *             <li>if the set of child nodes equals null</li>
+     *             </ul>
+     *
      */
     private def void allAugmentsToGenTypes(Module module) {
         checkArgument(module !== null, "Module reference cannot be NULL.");
@@ -326,25 +341,25 @@ public class BindingGeneratorImpl implements BindingGenerator {
         val basePackageName = moduleNamespaceToPackageName(module);
         val List<AugmentationSchema> augmentations = resolveAugmentations(module);
         for (augment : augmentations) {
-            augmentationToGenTypes(basePackageName, augment, module, null);
-        }
-    }
-
-    /**\r
-     * Returns list of <code>AugmentationSchema</code> objects. The objects are\r
-     * sorted according to the length of their target path from the shortest to\r
-     * the longest.\r
-     *\r
-     * @param module\r
-     *            module from which is obtained list of all augmentation objects\r
-     * @return list of sorted <code>AugmentationSchema</code> objects obtained\r
-     *         from <code>module</code>\r
-     * @throws IllegalArgumentException\r
-     *             <ul>\r
-     *             <li>if the module equals null</li>\r
-     *             <li>if the set of augmentation equals null</li>\r
-     *             </ul>\r
-     *\r
+            augmentationToGenTypes(basePackageName, augment, module);
+        }
+    }
+
+    /**
+     * 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
+     *         from <code>module</code>
+     * @throws IllegalArgumentException
+     *             <ul>
+     *             <li>if the module equals null</li>
+     *             <li>if the set of augmentation equals null</li>
+     *             </ul>
+     *
      */
     private def List<AugmentationSchema> resolveAugmentations(Module module) {
         checkArgument(module !== null, "Module reference cannot be NULL.");
@@ -364,19 +379,19 @@ public class BindingGeneratorImpl implements BindingGenerator {
         return sortedAugmentations;
     }
 
-    /**\r
-     * Converts whole <b>module</b> to <code>GeneratedType</code> object.\r
-     * Firstly is created the module builder object from which is vally\r
-     * obtained reference to <code>GeneratedType</code> object.\r
-     *\r
-     * @param module\r
-     *            module from which are obtained the module name, child nodes,\r
-     *            uses and is derived package name\r
-     * @return <code>GeneratedType</code> which is internal representation of\r
-     *         the module\r
-     * @throws IllegalArgumentException\r
-     *             if the module equals null\r
-     *\r
+    /**
+     * Converts whole <b>module</b> to <code>GeneratedType</code> object.
+     * Firstly is created the module builder object from which is vally
+     * 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
+     * @return <code>GeneratedType</code> which is internal representation of
+     *         the module
+     * @throws IllegalArgumentException
+     *             if the module equals null
+     *
      */
     private def GeneratedTypeBuilder moduleToDataType(Module module) {
         checkArgument(module !== null, "Module reference cannot be NULL.");
@@ -387,21 +402,21 @@ public class BindingGeneratorImpl implements BindingGenerator {
         return moduleDataTypeBuilder;
     }
 
-    /**\r
-     * Converts all <b>rpcs</b> inputs and outputs substatements of the module\r
-     * to the list of <code>Type</code> objects. In addition are to containers\r
-     * and lists which belong to input or output also part of returning list.\r
-     *\r
-     * @param module\r
-     *            module from which is obtained set of all rpc objects to\r
-     *            iterate over them\r
-     * @throws IllegalArgumentException\r
-     *             <ul>\r
-     *             <li>if the module equals null</li>\r
-     *             <li>if the name of module equals null</li>\r
-     *             <li>if the set of child nodes equals null</li>\r
-     *             </ul>\r
-     *\r
+    /**
+     * 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
+     * @throws IllegalArgumentException
+     *             <ul>
+     *             <li>if the module equals null</li>
+     *             <li>if the name of module equals null</li>
+     *             <li>if the set of child nodes equals null</li>
+     *             </ul>
+     *
      */
     private def void rpcMethodsToGenType(Module module) {
         checkArgument(module !== null, "Module reference cannot be NULL.");
@@ -419,7 +434,7 @@ public class BindingGeneratorImpl implements BindingGenerator {
         interfaceBuilder.addImplementsType(Types.typeForClass(RpcService));
         for (rpc : rpcDefinitions) {
             if (rpc !== null) {
-                val rpcName = parseToClassName(rpc.QName.localName);
+                val rpcName = BindingMapping.getClassName(rpc.QName);
                 val rpcMethodName = parseToValidParamName(rpcName);
                 val method = interfaceBuilder.addMethod(rpcMethodName);
                 val input = rpc.input;
@@ -455,21 +470,21 @@ public class BindingGeneratorImpl implements BindingGenerator {
         genCtx.get(module).addTopLevelNodeType(interfaceBuilder)
     }
 
-    /**\r
-     * Converts all <b>notifications</b> of the module to the list of\r
-     * <code>Type</code> objects. In addition are to this list added containers\r
-     * and lists which are part of this notification.\r
-     *\r
-     * @param module\r
-     *            module from which is obtained set of all notification objects\r
-     *            to iterate over them\r
-     * @throws IllegalArgumentException\r
-     *             <ul>\r
-     *             <li>if the module equals null</li>\r
-     *             <li>if the name of module equals null</li>\r
-     *             <li>if the set of child nodes equals null</li>\r
-     *             </ul>\r
-     *\r
+    /**
+     * 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
+     * @throws IllegalArgumentException
+     *             <ul>
+     *             <li>if the module equals null</li>
+     *             <li>if the name of module equals null</li>
+     *             <li>if the set of child nodes equals null</li>
+     *             </ul>
+     *
      */
     private def void notificationsToGenType(Module module) {
         checkArgument(module !== null, "Module reference cannot be NULL.");
@@ -495,11 +510,11 @@ public class BindingGeneratorImpl implements BindingGenerator {
                 notificationInterface.addImplementsType(NOTIFICATION);
                 genCtx.get(module).addChildNodeType(notification.path, notificationInterface)
 
-                // Notification object\r
+                // Notification object
                 resolveDataSchemaNodes(module, basePackageName, notificationInterface, notificationInterface,
                     notification.childNodes);
 
-                listenerInterface.addMethod("on" + notificationInterface.name) //\r
+                listenerInterface.addMethod("on" + notificationInterface.name) //
                 .setAccessModifier(AccessModifier.PUBLIC).addParameter(notificationInterface, "notification").
                     setReturnType(Types.VOID);
             }
@@ -508,17 +523,17 @@ public class BindingGeneratorImpl implements BindingGenerator {
         genCtx.get(module).addTopLevelNodeType(listenerInterface)
     }
 
-    /**\r
-     * Converts all <b>identities</b> of the module to the list of\r
-     * <code>Type</code> objects.\r
-     *\r
-     * @param module\r
-     *            module from which is obtained set of all identity objects to\r
-     *            iterate over them\r
-     * @param context\r
-     *            schema context only used as input parameter for method\r
-     *            {@link identityToGenType}\r
-     *\r
+    /**
+     * 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
+     * @param context
+     *            schema context only used as input parameter for method
+     *            {@link identityToGenType}
+     *
      */
     private def void allIdentitiesToGenTypes(Module module, SchemaContext context) {
         val Set<IdentitySchemaNode> schemaIdentities = module.identities;
@@ -531,23 +546,23 @@ public class BindingGeneratorImpl implements BindingGenerator {
         }
     }
 
-    /**\r
-     * Converts the <b>identity</b> object to GeneratedType. Firstly it is\r
-     * created transport object builder. If identity contains base identity then\r
-     * reference to base identity is added to superior identity as its extend.\r
-     * If identity doesn't contain base identity then only reference to abstract\r
-     * class {@link org.opendaylight.yangtools.yang.model.api.BaseIdentity\r
-     * BaseIdentity} is added\r
-     *\r
-     * @param module current module\r
-     * @param basePackageName\r
-     *            string contains the module package name\r
-     * @param identity\r
-     *            IdentitySchemaNode which contains data about identity\r
-     * @param context\r
-     *            SchemaContext which is used to get package and name\r
-     *            information about base of identity\r
-     *\r
+    /**
+     * Converts the <b>identity</b> object to GeneratedType. Firstly it is
+     * created transport object builder. If identity contains base identity then
+     * reference to base identity is added to superior identity as its extend.
+     * 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 module current module
+     * @param basePackageName
+     *            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
+     *
      */
     private def void identityToGenType(Module module, String basePackageName, IdentitySchemaNode identity,
         SchemaContext context) {
@@ -555,7 +570,7 @@ public class BindingGeneratorImpl implements BindingGenerator {
             return;
         }
         val packageName = packageNameForGeneratedType(basePackageName, identity.path);
-        val genTypeName = parseToClassName(identity.QName.localName);
+        val genTypeName = BindingMapping.getClassName(identity.QName);
         val newType = new GeneratedTOBuilderImpl(packageName, genTypeName);
         val baseIdentity = identity.baseIdentity;
         if (baseIdentity === null) {
@@ -563,25 +578,35 @@ public class BindingGeneratorImpl implements BindingGenerator {
         } else {
             val baseIdentityParentModule = SchemaContextUtil.findParentModule(context, baseIdentity);
             val returnTypePkgName = moduleNamespaceToPackageName(baseIdentityParentModule);
-            val returnTypeName = parseToClassName(baseIdentity.QName.localName);
+            val returnTypeName = BindingMapping.getClassName(baseIdentity.QName);
             val gto = new GeneratedTOBuilderImpl(returnTypePkgName, returnTypeName).toInstance();
             newType.setExtendsType(gto);
         }
         newType.setAbstract(true);
-        genCtx.get(module).addIdentityType(newType)
-    }
-
-    /**\r
-     * Converts all <b>groupings</b> of the module to the list of\r
-     * <code>Type</code> objects. Firstly are groupings sorted according mutual\r
-     * dependencies. At least dependend (indepedent) groupings are in the list\r
-     * saved at first positions. For every grouping the record is added to map\r
-     * {@link BindingGeneratorImpl#allGroupings allGroupings}\r
-     *\r
-     * @param module\r
-     *            current module\r
-     * @param collection of groupings from which types will be generated\r
-     *\r
+        val qname = identity.QName;
+        
+        newType.qnameConstant(BindingMapping.QNAME_STATIC_FIELD_NAME,qname);
+        
+        genCtx.get(module).addIdentityType(identity.QName,newType)
+    }
+    
+    private static def qnameConstant(GeneratedTypeBuilderBase<?> toBuilder, String constantName, QName name) {
+        toBuilder.addConstant(QName.typeForClass,constantName,'''
+            org.opendaylight.yangtools.yang.common.QName.create("«name.namespace»","«name.formattedRevision»","«name.localName»")
+        ''');
+    }
+
+    /**
+     * Converts all <b>groupings</b> of the module to the list of
+     * <code>Type</code> objects. Firstly are groupings sorted according mutual
+     * dependencies. At least dependent (independent) groupings are in the list
+     * saved at first positions. For every grouping the record is added to map
+     * {@link BindingGeneratorImpl#allGroupings allGroupings}
+     *
+     * @param module
+     *            current module
+     * @param collection of groupings from which types will be generated
+     *
      */
     private def void groupingsToGenTypes(Module module, Collection<GroupingDefinition> groupings) {
         val basePackageName = moduleNamespaceToPackageName(module);
@@ -592,18 +617,18 @@ public class BindingGeneratorImpl implements BindingGenerator {
         }
     }
 
-    /**\r
-     * Converts individual grouping to GeneratedType. Firstly generated type\r
-     * builder is created and every child node of grouping is resolved to the\r
-     * method.\r
-     *\r
-     * @param basePackageName\r
-     *            string contains the module package name\r
-     * @param grouping\r
-     *            GroupingDefinition which contains data about grouping\r
-     * @param module current module\r
-     * @return GeneratedType which is generated from grouping (object of type\r
-     *         <code>GroupingDefinition</code>)\r
+    /**
+     * 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 contains the module package name
+     * @param grouping
+     *            GroupingDefinition which contains data about grouping
+     * @param module current module
+     * @return GeneratedType which is generated from grouping (object of type
+     *         <code>GroupingDefinition</code>)
      */
     private def void groupingToGenType(String basePackageName, GroupingDefinition grouping, Module module) {
         val packageName = packageNameForGeneratedType(basePackageName, grouping.path);
@@ -614,16 +639,16 @@ public class BindingGeneratorImpl implements BindingGenerator {
         processUsesAugments(grouping, module);
     }
 
-    /**\r
-     * Tries to find EnumTypeDefinition in <code>typeDefinition</code>. If base\r
-     * type of <code>typeDefinition</code> is of the type ExtendedType then this\r
-     * method is recursivelly called with this base type.\r
-     *\r
-     * @param typeDefinition\r
-     *            TypeDefinition in which should be EnumTypeDefinition found as\r
-     *            base type\r
-     * @return EnumTypeDefinition if it is found inside\r
-     *         <code>typeDefinition</code> or <code>null</code> in other case\r
+    /**
+     * Tries to find EnumTypeDefinition in <code>typeDefinition</code>. If base
+     * type of <code>typeDefinition</code> is of the type ExtendedType then this
+     * method is recursively called with this base type.
+     *
+     * @param typeDefinition
+     *            TypeDefinition in which should be EnumTypeDefinition found as
+     *            base type
+     * @return EnumTypeDefinition if it is found inside
+     *         <code>typeDefinition</code> or <code>null</code> in other case
      */
     private def EnumTypeDefinition enumTypeDefFromExtendedType(TypeDefinition<?> typeDefinition) {
         if (typeDefinition !== null) {
@@ -636,28 +661,28 @@ public class BindingGeneratorImpl implements BindingGenerator {
         return null;
     }
 
-    /**\r
-     * Adds enumeration builder created from <code>enumTypeDef</code> to\r
-     * <code>typeBuilder</code>.\r
-     *\r
-     * Each <code>enumTypeDef</code> item is added to builder with its name and\r
-     * value.\r
-     *\r
-     * @param enumTypeDef\r
-     *            EnumTypeDefinition contains enum data\r
-     * @param enumName\r
-     *            string contains name which will be assigned to enumeration\r
-     *            builder\r
-     * @param typeBuilder\r
-     *            GeneratedTypeBuilder to which will be enum builder assigned\r
-     * @return enumeration builder which contais data from\r
-     *         <code>enumTypeDef</code>\r
+    /**
+     * 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
+     *            string contains name which will be assigned to enumeration
+     *            builder
+     * @param typeBuilder
+     *            GeneratedTypeBuilder to which will be enum builder assigned
+     * @return enumeration builder which contains data from
+     *         <code>enumTypeDef</code>
      */
-    private def EnumBuilder resolveInnerEnumFromTypeDefinition(EnumTypeDefinition enumTypeDef, String enumName,
+    private def EnumBuilder resolveInnerEnumFromTypeDefinition(EnumTypeDefinition enumTypeDef, QName enumName,
         GeneratedTypeBuilder typeBuilder) {
         if ((enumTypeDef !== null) && (typeBuilder !== null) && (enumTypeDef.QName !== null) &&
             (enumTypeDef.QName.localName !== null)) {
-            val enumerationName = parseToClassName(enumName);
+            val enumerationName = BindingMapping.getClassName(enumName);
             val enumBuilder = typeBuilder.addEnumeration(enumerationName);
             enumBuilder.updateEnumPairsFromEnumTypeDef(enumTypeDef);
             return enumBuilder;
@@ -665,100 +690,132 @@ public class BindingGeneratorImpl implements BindingGenerator {
         return null;
     }
 
-    /**\r
-     * Generates type builder for <code>module</code>.\r
-     *\r
-     * @param module\r
-     *            Module which is source of package name for generated type\r
-     *            builder\r
-     * @param postfix\r
-     *            string which is added to the module class name representation\r
-     *            as suffix\r
-     * @return instance of GeneratedTypeBuilder which represents\r
-     *         <code>module</code>.\r
-     * @throws IllegalArgumentException\r
-     *             if <code>module</code> equals null\r
+    /**
+     * Generates type builder for <code>module</code>.
+     *
+     * @param module
+     *            Module which is source of package name for generated type
+     *            builder
+     * @param postfix
+     *            string which is added to the module class name representation
+     *            as suffix
+     * @return instance of GeneratedTypeBuilder which represents
+     *         <code>module</code>.
+     * @throws IllegalArgumentException
+     *             if <code>module</code> equals null
      */
     private def GeneratedTypeBuilder moduleTypeBuilder(Module module, String postfix) {
         checkArgument(module !== null, "Module reference cannot be NULL.");
         val packageName = moduleNamespaceToPackageName(module);
-        val moduleName = parseToClassName(module.name) + postfix;
+        val moduleName = BindingMapping.getClassName(module.name) + postfix;
         return new GeneratedTypeBuilderImpl(packageName, moduleName);
     }
 
-    /**\r
-     * Converts <code>augSchema</code> to list of <code>Type</code> which\r
-     * contains generated type for augmentation. In addition there are also\r
-     * generated types for all containers, list and choices which are child of\r
-     * <code>augSchema</code> node or a generated types for cases are added if\r
-     * augmented node is choice.\r
-     *\r
-     * @param augmentPackageName\r
-     *            string with the name of the package to which the augmentation\r
-     *            belongs\r
-     * @param augSchema\r
-     *            AugmentationSchema which is contains data about agumentation\r
-     *            (target path, childs...)\r
-     * @param module current module\r
-     * @param parentUsesNode parent uses node of this augment (can be null if this augment is not defined under uses statement)\r
-     * @throws IllegalArgumentException\r
-     *             <ul>\r
-     *             <li>if <code>augmentPackageName</code> equals null</li>\r
-     *             <li>if <code>augSchema</code> equals null</li>\r
-     *             <li>if target path of <code>augSchema</code> equals null</li>\r
-     *             </ul>\r
+    /**
+     * Converts <code>augSchema</code> to list of <code>Type</code> which
+     * contains generated type for augmentation. In addition there are also
+     * 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
+     * @param augSchema
+     *            AugmentationSchema which is contains data about augmentation
+     *            (target path, childs...)
+     * @param module current module
+     * @param parentUsesNode parent uses node of this augment (can be null if this augment is not defined under uses statement)
+     * @throws IllegalArgumentException
+     *             <ul>
+     *             <li>if <code>augmentPackageName</code> equals null</li>
+     *             <li>if <code>augSchema</code> equals null</li>
+     *             <li>if target path of <code>augSchema</code> equals null</li>
+     *             </ul>
      */
-    private def void augmentationToGenTypes(String augmentPackageName, AugmentationSchema augSchema, Module module,
-        UsesNode parentUsesNode) {
+    private def void augmentationToGenTypes(String augmentPackageName, AugmentationSchema augSchema, Module module) {
         checkArgument(augmentPackageName !== null, "Package Name cannot be NULL.");
         checkArgument(augSchema !== null, "Augmentation Schema cannot be NULL.");
         checkState(augSchema.targetPath !== null,
             "Augmentation Schema does not contain Target Path (Target Path is NULL).");
 
         processUsesAugments(augSchema, module);
-
-        // EVERY augmented interface will extends Augmentation<T> interface\r
-        // and DataObject interface\r
         val targetPath = augSchema.targetPath;
-        var targetSchemaNode = findDataSchemaNode(schemaContext, targetPath);
+        var SchemaNode targetSchemaNode = null
+
+        targetSchemaNode = findDataSchemaNode(schemaContext, targetPath);
         if (targetSchemaNode instanceof DataSchemaNode && (targetSchemaNode as DataSchemaNode).isAddedByUses()) {
-            if (parentUsesNode == null) {
-                targetSchemaNode = findOriginal(targetSchemaNode as DataSchemaNode);
-            } else {
-                targetSchemaNode = findOriginalTargetFromGrouping(targetSchemaNode.QName.localName, parentUsesNode);
-            }
+            targetSchemaNode = findOriginal(targetSchemaNode as DataSchemaNode);
             if (targetSchemaNode == null) {
                 throw new NullPointerException(
-                    "Failed to find target node from grouping for augmentation " + augSchema + " in module " +
+                    "Failed to find target node from grouping in augmentation " + augSchema + " in module " +
                         module.name);
             }
         }
+        if (targetSchemaNode == null) {
+            throw new IllegalArgumentException("augment target not found: " + targetPath)
+        }
 
-        if (targetSchemaNode !== null) {
-            var targetTypeBuilder = findChildNodeByPath(targetSchemaNode.path)
-            if (targetTypeBuilder === null) {
-                targetTypeBuilder = findCaseByPath(targetSchemaNode.path)
-            }
-            if (targetTypeBuilder === null) {
-                throw new NullPointerException("Target type not yet generated: " + targetSchemaNode);
-            }
-            if (!(targetSchemaNode instanceof ChoiceNode)) {
-                var packageName = augmentPackageName;
-                if (parentUsesNode != null) {
-                    packageName = packageNameForGeneratedType(augmentPackageName, augSchema.targetPath);
-                }
-                val augTypeBuilder = addRawAugmentGenTypeDefinition(module, packageName, augmentPackageName,
-                    targetTypeBuilder.toInstance, augSchema);
-                genCtx.get(module).addAugmentType(augTypeBuilder)
-            } else {
-                generateTypesFromAugmentedChoiceCases(module, augmentPackageName, targetTypeBuilder.toInstance,
-                    targetSchemaNode as ChoiceNode, augSchema.childNodes);
+        var targetTypeBuilder = findChildNodeByPath(targetSchemaNode.path)
+        if (targetTypeBuilder === null) {
+            targetTypeBuilder = findCaseByPath(targetSchemaNode.path)
+        }
+        if (targetTypeBuilder === null) {
+            throw new NullPointerException("Target type not yet generated: " + targetSchemaNode);
+        }
+
+        if (!(targetSchemaNode instanceof ChoiceNode)) {
+            var packageName = augmentPackageName;
+            val augTypeBuilder = addRawAugmentGenTypeDefinition(module, packageName, augmentPackageName,
+                targetTypeBuilder.toInstance, augSchema);
+            genCtx.get(module).addAugmentType(augTypeBuilder)
+            genCtx.get(module).addTypeToAugmentation(augTypeBuilder, augSchema);
+        } else {
+            generateTypesFromAugmentedChoiceCases(module, augmentPackageName, targetTypeBuilder.toInstance,
+                targetSchemaNode as ChoiceNode, augSchema.childNodes);
+        }
+    }
+
+    private def void usesAugmentationToGenTypes(String augmentPackageName, AugmentationSchema augSchema, Module module,
+        UsesNode usesNode, DataNodeContainer usesNodeParent) {
+        checkArgument(augmentPackageName !== null, "Package Name cannot be NULL.");
+        checkArgument(augSchema !== null, "Augmentation Schema cannot be NULL.");
+        checkState(augSchema.targetPath !== null,
+            "Augmentation Schema does not contain Target Path (Target Path is NULL).");
+
+        processUsesAugments(augSchema, module);
+        val targetPath = augSchema.targetPath;
+        var SchemaNode targetSchemaNode = null
+        targetSchemaNode = findOriginalTargetFromGrouping(targetPath, usesNode);
+        if (targetSchemaNode == null) {
+            throw new IllegalArgumentException("augment target not found: " + targetPath)
+        }
+
+        var targetTypeBuilder = findChildNodeByPath(targetSchemaNode.path)
+        if (targetTypeBuilder === null) {
+            targetTypeBuilder = findCaseByPath(targetSchemaNode.path)
+        }
+        if (targetTypeBuilder === null) {
+            throw new NullPointerException("Target type not yet generated: " + targetSchemaNode);
+        }
+
+        if (!(targetSchemaNode instanceof ChoiceNode)) {
+            var packageName = augmentPackageName;
+            if (usesNodeParent instanceof SchemaNode) {
+                packageName = packageNameForGeneratedType(augmentPackageName, (usesNodeParent as SchemaNode).path, true)
             }
+            val augTypeBuilder = addRawAugmentGenTypeDefinition(module, packageName, augmentPackageName,
+                targetTypeBuilder.toInstance, augSchema);
+            genCtx.get(module).addAugmentType(augTypeBuilder)
+            genCtx.get(module).addTypeToAugmentation(augTypeBuilder, augSchema);
+        } else {
+            generateTypesFromAugmentedChoiceCases(module, augmentPackageName, targetTypeBuilder.toInstance,
+                targetSchemaNode as ChoiceNode, augSchema.childNodes);
         }
     }
 
-    /**\r
-     * Utility method which search for original node defined in grouping.\r
+    /**
+     * Utility method which search for original node defined in grouping.
      */
     private def DataSchemaNode findOriginal(DataSchemaNode node) {
         var DataSchemaNode result = findCorrectTargetFromGrouping(node);
@@ -775,20 +832,30 @@ public class BindingGeneratorImpl implements BindingGenerator {
 
     private def DataSchemaNode findCorrectTargetFromAugment(DataSchemaNode node) {
         if (!node.augmenting) {
-            return null;
+            return null
         }
 
-        var String currentName = node.QName.localName;
-        var tmpPath = new ArrayList<String>();
-        var YangNode parent = node;
+        var QName currentName = node.QName
+        var Object currentNode = node
+        var Object parent = node;
+        val tmpPath = new ArrayList<QName>()
+        val tmpTree = new ArrayList<SchemaNode>()
+
         var AugmentationSchema augment = null;
         do {
-            parent = (parent as DataSchemaNode).parent;
+            val SchemaPath sp = (parent as SchemaNode).path
+            val List<QName> names = sp.path
+            val List<QName> newNames = new ArrayList(names)
+            newNames.remove(newNames.size - 1)
+            val SchemaPath newSp = new SchemaPath(newNames, sp.absolute)
+            parent = findDataSchemaNode(schemaContext, newSp)
             if (parent instanceof AugmentationTarget) {
                 tmpPath.add(currentName);
+                tmpTree.add(currentNode as SchemaNode)
                 augment = findNodeInAugment((parent as AugmentationTarget).availableAugmentations, currentName);
                 if (augment == null) {
-                    currentName = (parent as DataSchemaNode).QName.localName;
+                    currentName = (parent as DataSchemaNode).QName
+                    currentNode = parent
                 }
             }
         } while ((parent as DataSchemaNode).augmenting && augment == null);
@@ -797,31 +864,33 @@ public class BindingGeneratorImpl implements BindingGenerator {
             return null;
         } else {
             Collections.reverse(tmpPath);
+            Collections.reverse(tmpTree);
             var Object actualParent = augment;
             var DataSchemaNode result = null;
             for (name : tmpPath) {
                 if (actualParent instanceof DataNodeContainer) {
-                    result = (actualParent as DataNodeContainer).getDataChildByName(name);
-                    actualParent = (actualParent as DataNodeContainer).getDataChildByName(name);
+                    result = (actualParent as DataNodeContainer).getDataChildByName(name.localName);
+                    actualParent = (actualParent as DataNodeContainer).getDataChildByName(name.localName);
                 } else {
                     if (actualParent instanceof ChoiceNode) {
-                        result = (actualParent as ChoiceNode).getCaseNodeByName(name);
-                        actualParent = (actualParent as ChoiceNode).getCaseNodeByName(name);
+                        result = (actualParent as ChoiceNode).getCaseNodeByName(name.localName);
+                        actualParent = (actualParent as ChoiceNode).getCaseNodeByName(name.localName);
                     }
                 }
             }
 
             if (result.addedByUses) {
-                result = findCorrectTargetFromGrouping(result);
+                result = findCorrectTargetFromAugmentGrouping(result, augment, tmpTree);
             }
 
             return result;
         }
     }
 
-    private def AugmentationSchema findNodeInAugment(Collection<AugmentationSchema> augments, String name) {
+    private def AugmentationSchema findNodeInAugment(Collection<AugmentationSchema> augments, QName name) {
         for (augment : augments) {
-            if (augment.getDataChildByName(name) != null) {
+            val DataSchemaNode node = augment.getDataChildByName(name);
+            if (node != null) {
                 return augment;
             }
         }
@@ -830,8 +899,7 @@ public class BindingGeneratorImpl implements BindingGenerator {
 
     private def DataSchemaNode findCorrectTargetFromGrouping(DataSchemaNode node) {
         if (node.path.path.size == 1) {
-
-            // uses is under module statement\r
+            // uses is under module statement
             val Module m = findParentModule(schemaContext, node);
             var DataSchemaNode result = null;
             for (u : m.uses) {
@@ -843,104 +911,190 @@ public class BindingGeneratorImpl implements BindingGenerator {
                 result = gr.getDataChildByName(node.QName.localName);
             }
             if (result == null) {
-                throw new IllegalArgumentException("Failed to generate code for augment");
+                throw new IllegalArgumentException("Failed to generate code for augment")
             }
-            return result;
+            return result
         } else {
             var DataSchemaNode result = null;
-            var String currentName = node.QName.localName;
-            var tmpPath = new ArrayList<String>();
-            var YangNode parent = node.parent;
+            var QName currentName = node.QName
+            var tmpPath = new ArrayList<QName>()
+            var Object parent = null
+
+            val SchemaPath sp = node.path
+            val List<QName> names = sp.path
+            val List<QName> newNames = new ArrayList(names)
+            newNames.remove(newNames.size - 1)
+            val SchemaPath newSp = new SchemaPath(newNames, sp.absolute)
+            parent = findDataSchemaNode(schemaContext, newSp)
+
             do {
                 tmpPath.add(currentName);
-                val dataNodeParent = parent as DataNodeContainer;
-                for (u : dataNodeParent.uses) {
-                    if (result == null) {\r
-                        var SchemaNode targetGrouping = findNodeInSchemaContext(schemaContext, u.groupingPath.path);
-                        if (!(targetGrouping instanceof GroupingDefinition)) {
-                            throw new IllegalArgumentException("Failed to generate code for augment in " + u);
+                if (parent instanceof DataNodeContainer) {
+                    val dataNodeParent = parent as DataNodeContainer;
+                    for (u : dataNodeParent.uses) {
+                        if (result == null) {
+                            result = getResultFromUses(u, currentName.localName)
                         }
-                        var gr = targetGrouping as GroupingDefinition;
-                        result = gr.getDataChildByName(currentName);\r
                     }
                 }
                 if (result == null) {
-                    currentName = (parent as SchemaNode).QName.localName;
-                    if (parent instanceof DataSchemaNode) {
-                        parent = (parent as DataSchemaNode).parent;
+                    currentName = (parent as SchemaNode).QName
+                    if (parent instanceof SchemaNode) {
+                        val SchemaPath nodeSp = (parent as SchemaNode).path
+                        val List<QName> nodeNames = nodeSp.path
+                        val List<QName> nodeNewNames = new ArrayList(nodeNames)
+                        nodeNewNames.remove(nodeNewNames.size - 1)
+                        if (nodeNewNames.empty) {
+                            parent = getParentModule(parent as SchemaNode)
+                        } else {
+                            val SchemaPath nodeNewSp = new SchemaPath(nodeNewNames, nodeSp.absolute)
+                            parent = findDataSchemaNode(schemaContext, nodeNewSp)
+                        }
                     } else {
-                        parent = (parent as DataNodeContainer).parent;
+                        throw new IllegalArgumentException("Failed to generate code for augment")
                     }
                 }
             } while (result == null && !(parent instanceof Module));
 
             if (result != null) {
-                if (tmpPath.size == 1) {
-                    return result;
-                } else {
-                    var DataSchemaNode newParent = result;
-                    Collections.reverse(tmpPath);
-                    tmpPath.remove(0);
-                    for (name : tmpPath) {
-                        newParent = (newParent as DataNodeContainer).getDataChildByName(name);
-                    }
-                    return newParent;
+                result = getTargetNode(tmpPath, result)
+            }
+            return result;
+        }
+    }
+
+    private def DataSchemaNode findCorrectTargetFromAugmentGrouping(DataSchemaNode node, AugmentationSchema parentNode,
+        List<SchemaNode> dataTree) {
+
+        var DataSchemaNode result = null;
+        var QName currentName = node.QName
+        var tmpPath = new ArrayList<QName>()
+        tmpPath.add(currentName)
+        var int i = 1;
+        var Object parent = null
+
+        do {
+            if (dataTree.size < 2 || dataTree.size == i) {
+                parent = parentNode
+            } else {
+                parent = dataTree.get(dataTree.size - (i+1))
+                tmpPath.add((parent as SchemaNode).QName)
+            }
+
+            val dataNodeParent = parent as DataNodeContainer;
+            for (u : dataNodeParent.uses) {
+                if (result == null) {
+                    result = getResultFromUses(u, currentName.localName)
                 }
             }
+            if (result == null) {
+                i = i + 1
+                currentName = (parent as SchemaNode).QName
+            }
+        } while (result == null);
 
+        if (result != null) {
+            result = getTargetNode(tmpPath, result)
+        }
+        return result;
+    }
+
+    private def getResultFromUses(UsesNode u, String currentName) {
+        var SchemaNode targetGrouping = findNodeInSchemaContext(schemaContext, u.groupingPath.path)
+        if (!(targetGrouping instanceof GroupingDefinition)) {
+            throw new IllegalArgumentException("Failed to generate code for augment in " + u)
+        }
+        var gr = targetGrouping as GroupingDefinition
+        return gr.getDataChildByName(currentName)
+    }
+
+    private def getTargetNode(List<QName> tmpPath, DataSchemaNode node) {
+        var DataSchemaNode result = node
+        if (tmpPath.size == 1) {
+            if (result != null && result.addedByUses) {
+                result = findOriginal(result);
+            }
             return result;
+        } else {
+            var DataSchemaNode newParent = result;
+            Collections.reverse(tmpPath);
+
+            tmpPath.remove(0);
+            for (name : tmpPath) {
+                // searching by local name is must, because node has different namespace in its original location
+                if (newParent instanceof DataNodeContainer) {
+                    newParent = (newParent as DataNodeContainer).getDataChildByName(name.localName);
+                } else {
+                    newParent = (newParent as ChoiceNode).getCaseNodeByName(name.localName);
+                }
+            }
+            if (newParent != null && newParent.addedByUses) {
+                newParent = findOriginal(newParent);
+            }
+            return newParent;
         }
     }
 
-    /**\r
-     * Convenient method to find node added by uses statement.\r
+
+    /**
+     * Convenient method to find node added by uses statement.
      */
-    private def DataSchemaNode findOriginalTargetFromGrouping(String targetSchemaNodeName, UsesNode parentUsesNode) {
+    private def DataSchemaNode findOriginalTargetFromGrouping(SchemaPath targetPath, UsesNode parentUsesNode) {
         var SchemaNode targetGrouping = findNodeInSchemaContext(schemaContext, parentUsesNode.groupingPath.path);
         if (!(targetGrouping instanceof GroupingDefinition)) {
             throw new IllegalArgumentException("Failed to generate code for augment in " + parentUsesNode);
         }
 
         var grouping = targetGrouping as GroupingDefinition;
-        var result = grouping.getDataChildByName(targetSchemaNodeName);
+        var SchemaNode result = grouping;
+        val List<QName> path = targetPath.path
+        for (node : path) {
+            // finding by local name is valid, grouping cannot contain nodes with same name and different namespace
+            if (result instanceof DataNodeContainer) {
+                result = (result as DataNodeContainer).getDataChildByName(node.localName)
+            } else if (result instanceof ChoiceNode) {
+                result = (result as ChoiceNode).getCaseNodeByName(node.localName)
+            }
+        }
         if (result == null) {
             return null;
         }
-        var boolean fromUses = result.addedByUses;
 
+        val String targetSchemaNodeName = result.QName.localName;
+        var boolean fromUses = (result as DataSchemaNode).addedByUses
         var Iterator<UsesNode> groupingUses = grouping.uses.iterator;
         while (fromUses) {
             if (groupingUses.hasNext()) {
                 grouping = findNodeInSchemaContext(schemaContext, groupingUses.next().groupingPath.path) as GroupingDefinition;
                 result = grouping.getDataChildByName(targetSchemaNodeName);
-                fromUses = result.addedByUses;
+                fromUses = (result as DataSchemaNode).addedByUses;
             } else {
                 throw new NullPointerException("Failed to generate code for augment in " + parentUsesNode);
             }
         }
 
-        return result;
+        return result as DataSchemaNode
     }
 
-    /**\r
-     * Returns a generated type builder for an augmentation.\r
-     *\r
-     * The name of the type builder is equal to the name of augmented node with\r
-     * serial number as suffix.\r
-     *\r
-     * @param module current module\r
-     * @param augmentPackageName\r
-     *            string with contains the package name to which the augment\r
-     *            belongs\r
-     * @param basePackageName\r
-     *            string with the package name to which the augmented node\r
-     *            belongs\r
-     * @param targetTypeRef\r
-     *            target type\r
-     * @param augSchema\r
-     *            augmentation schema which contains data about the child nodes\r
-     *            and uses of augment\r
-     * @return generated type builder for augment\r
+    /**
+     * 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 module current module
+     * @param augmentPackageName
+     *            string with contains the package name to which the augment
+     *            belongs
+     * @param basePackageName
+     *            string with the package name to which the augmented node
+     *            belongs
+     * @param targetTypeRef
+     *            target type
+     * @param augSchema
+     *            augmentation schema which contains data about the child nodes
+     *            and uses of augment
+     * @return generated type builder for augment
      */
     private def GeneratedTypeBuilder addRawAugmentGenTypeDefinition(Module module, String augmentPackageName,
         String basePackageName, Type targetTypeRef, AugmentationSchema augSchema) {
@@ -952,7 +1106,7 @@ public class BindingGeneratorImpl implements BindingGenerator {
         val augIdentifier = getAugmentIdentifier(augSchema.unknownSchemaNodes);
 
         val augTypeName = if (augIdentifier !== null) {
-                parseToClassName(augIdentifier)
+                BindingMapping.getClassName(augIdentifier)
             } else {
                 augGenTypeName(augmentBuilders, targetTypeRef.name);
             }
@@ -968,10 +1122,10 @@ public class BindingGeneratorImpl implements BindingGenerator {
         return augTypeBuilder;
     }
 
-    /**\r
-     *\r
-     * @param unknownSchemaNodes\r
-     * @return nodeParameter of UnknownSchemaNode\r
+    /**
+     *
+     * @param unknownSchemaNodes
+     * @return nodeParameter of UnknownSchemaNode
      */
     private def String getAugmentIdentifier(List<UnknownSchemaNode> unknownSchemaNodes) {
         for (unknownSchemaNode : unknownSchemaNodes) {
@@ -984,17 +1138,17 @@ public class BindingGeneratorImpl implements BindingGenerator {
         return null;
     }
 
-    /**\r
-     * Returns first unique name for the augment generated type builder. The\r
-     * generated type builder name for augment consists from name of augmented\r
-     * node and serial number of its augmentation.\r
-     *\r
-     * @param builders\r
-     *            map of builders which were created in the package to which the\r
-     *            augmentation belongs\r
-     * @param genTypeName\r
-     *            string with name of augmented node\r
-     * @return string with unique name for augmentation builder\r
+    /**
+     * 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
+     * @param genTypeName
+     *            string with name of augmented node
+     * @return string with unique name for augmentation builder
      */
     private def String augGenTypeName(Map<String, GeneratedTypeBuilder> builders, String genTypeName) {
         var index = 1;
@@ -1004,28 +1158,28 @@ public class BindingGeneratorImpl implements BindingGenerator {
         return genTypeName + index;
     }
 
-    /**\r
-     * Adds the methods to <code>typeBuilder</code> which represent subnodes of\r
-     * node for which <code>typeBuilder</code> was created.\r
-     *\r
-     * The subnodes aren't mapped to the methods if they are part of grouping or\r
-     * augment (in this case are already part of them).\r
-     *\r
-     * @param module current module\r
-     * @param basePackageName\r
-     *            string contains the module package name\r
-     * @param parent\r
-     *            generated type builder which represents any node. The subnodes\r
-     *            of this node are added to the <code>typeBuilder</code> as\r
-     *            methods. The subnode can be of type leaf, leaf-list, list,\r
-     *            container, choice.\r
-     * @param childOf parent type\r
-     * @param schemaNodes\r
-     *            set of data schema nodes which are the children of the node\r
-     *            for which <code>typeBuilder</code> was created\r
-     * @return generated type builder which is the same builder as input\r
-     *         parameter. The getter methods (representing child nodes) could be\r
-     *         added to it.\r
+    /**
+     * 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 module current module
+     * @param basePackageName
+     *            string contains the module package name
+     * @param parent
+     *            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 childOf parent type
+     * @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 builder as input
+     *         parameter. The getter methods (representing child nodes) could be
+     *         added to it.
      */
     private def GeneratedTypeBuilder resolveDataSchemaNodes(Module module, String basePackageName,
         GeneratedTypeBuilder parent, GeneratedTypeBuilder childOf, Set<DataSchemaNode> schemaNodes) {
@@ -1039,25 +1193,25 @@ public class BindingGeneratorImpl implements BindingGenerator {
         return parent;
     }
 
-    /**\r
-     * Adds the methods to <code>typeBuilder</code> what represents subnodes of\r
-     * node for which <code>typeBuilder</code> was created.\r
-     *\r
-     * @param module current module\r
-     * @param basePackageName\r
-     *            string contains the module package name\r
-     * @param typeBuilder\r
-     *            generated type builder which represents any node. The subnodes\r
-     *            of this node are added to the <code>typeBuilder</code> as\r
-     *            methods. The subnode can be of type leaf, leaf-list, list,\r
-     *            container, choice.\r
-     * @param childOf parent type\r
-     * @param schemaNodes\r
-     *            set of data schema nodes which are the children of the node\r
-     *            for which <code>typeBuilder</code> was created\r
-     * @return generated type builder which is the same object as the input\r
-     *         parameter <code>typeBuilder</code>. The getter method could be\r
-     *         added to it.\r
+    /**
+     * Adds the methods to <code>typeBuilder</code> what represents subnodes of
+     * node for which <code>typeBuilder</code> was created.
+     *
+     * @param module current module
+     * @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 childOf parent type
+     * @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 def GeneratedTypeBuilder augSchemaNodeToMethods(Module module, String basePackageName,
         GeneratedTypeBuilder typeBuilder, GeneratedTypeBuilder childOf, Set<DataSchemaNode> schemaNodes) {
@@ -1071,20 +1225,20 @@ public class BindingGeneratorImpl implements BindingGenerator {
         return typeBuilder;
     }
 
-    /**\r
-     * Adds to <code>typeBuilder</code> a method which is derived from\r
-     * <code>schemaNode</code>.\r
-     *\r
-     * @param basePackageName\r
-     *            string with the module package name\r
-     * @param node\r
-     *            data schema node which is added to <code>typeBuilder</code> as\r
-     *            a method\r
-     * @param typeBuilder\r
-     *            generated type builder to which is <code>schemaNode</code>\r
-     *            added as a method.\r
-     * @param childOf parent type\r
-     * @param module current module\r
+    /**
+     * Adds to <code>typeBuilder</code> a method which is derived from
+     * <code>schemaNode</code>.
+     *
+     * @param basePackageName
+     *            string with the module package name
+     * @param node
+     *            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.
+     * @param childOf parent type
+     * @param module current module
      */
     private def void addSchemaNodeToBuilderAsMethod(String basePackageName, DataSchemaNode node,
         GeneratedTypeBuilder typeBuilder, GeneratedTypeBuilder childOf, Module module) {
@@ -1104,67 +1258,69 @@ public class BindingGeneratorImpl implements BindingGenerator {
         }
     }
 
-    /**\r
-     * Converts <code>choiceNode</code> to the list of generated types for\r
-     * choice and its cases.\r
-     *\r
-     * The package names for choice and for its cases are created as\r
-     * concatenation of the module package (<code>basePackageName</code>) and\r
-     * names of all parents node.\r
-     *\r
-     * @param module current module\r
-     * @param basePackageName\r
-     *            string with the module package name\r
-     * @param parent parent type\r
-     * @param childOf concrete parent for case child nodes\r
-     * @param choiceNode\r
-     *            choice node which is mapped to generated type. Also child\r
-     *            nodes - cases are mapped to generated types.\r
-     * @throws IllegalArgumentException\r
-     *             <ul>\r
-     *             <li>if <code>basePackageName</code> equals null</li>\r
-     *             <li>if <code>choiceNode</code> equals null</li>\r
-     *             </ul>\r
-     *\r
+    /**
+     * 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 module current module
+     * @param basePackageName
+     *            string with the module package name
+     * @param parent parent type
+     * @param childOf concrete parent for case child nodes
+     * @param choiceNode
+     *            choice node which is mapped to generated type. Also child
+     *            nodes - cases are mapped to generated types.
+     * @throws IllegalArgumentException
+     *             <ul>
+     *             <li>if <code>basePackageName</code> equals null</li>
+     *             <li>if <code>choiceNode</code> equals null</li>
+     *             </ul>
+     *
      */
     private def void choiceToGeneratedType(Module module, String basePackageName, GeneratedTypeBuilder parent,
         ChoiceNode choiceNode) {
         checkArgument(basePackageName !== null, "Base Package Name cannot be NULL.");
         checkArgument(choiceNode !== null, "Choice Schema Node cannot be NULL.");
 
-        val packageName = packageNameForGeneratedType(basePackageName, choiceNode.path);
-        val choiceTypeBuilder = addRawInterfaceDefinition(packageName, choiceNode);
-        constructGetter(parent, choiceNode.QName.localName, choiceNode.description, choiceTypeBuilder);
-        choiceTypeBuilder.addImplementsType(DataContainer.typeForClass);
-        genCtx.get(module).addChildNodeType(choiceNode.path, choiceTypeBuilder)
-        generateTypesFromChoiceCases(module, basePackageName, parent, choiceTypeBuilder.toInstance, choiceNode);
-    }
-
-    /**\r
-     * Converts <code>caseNodes</code> set to list of corresponding generated\r
-     * types.\r
-     *\r
-     * For every <i>case</i> which isn't added through augment or <i>uses</i> is\r
-     * created generated type builder. The package names for the builder is\r
-     * created as concatenation of the module package (\r
-     * <code>basePackageName</code>) and names of all parents nodes of the\r
-     * concrete <i>case</i>. There is also relation "<i>implements type</i>"\r
-     * between every case builder and <i>choice</i> type\r
-     *\r
-     * @param basePackageName\r
-     *            string with the module package name\r
-     * @param refChoiceType\r
-     *            type which represents superior <i>case</i>\r
-     * @param caseNodes\r
-     *            set of choice case nodes which are mapped to generated types\r
-     * @return list of generated types for <code>caseNodes</code>.\r
-     * @throws IllegalArgumentException\r
-     *             <ul>\r
-     *             <li>if <code>basePackageName</code> equals null</li>\r
-     *             <li>if <code>refChoiceType</code> equals null</li>\r
-     *             <li>if <code>caseNodes</code> equals null</li>\r
-     *             </ul>\r
-     *             *\r
+        if (!choiceNode.addedByUses) {
+            val packageName = packageNameForGeneratedType(basePackageName, choiceNode.path);
+            val choiceTypeBuilder = addRawInterfaceDefinition(packageName, choiceNode);
+            constructGetter(parent, choiceNode.QName.localName, choiceNode.description, choiceTypeBuilder);
+            choiceTypeBuilder.addImplementsType(DataContainer.typeForClass);
+            genCtx.get(module).addChildNodeType(choiceNode.path, choiceTypeBuilder)
+            generateTypesFromChoiceCases(module, basePackageName, parent, choiceTypeBuilder.toInstance, choiceNode);
+        }
+    }
+
+    /**
+     * 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 def void generateTypesFromChoiceCases(Module module, String basePackageName,
         GeneratedTypeBuilder choiceParent, Type refChoiceType, ChoiceNode choiceNode) {
@@ -1179,18 +1335,25 @@ public class BindingGeneratorImpl implements BindingGenerator {
 
         for (caseNode : caseNodes) {
             if (caseNode !== null && !caseNode.isAddedByUses() && !caseNode.isAugmenting()) {
-                val packageName = packageNameForGeneratedType(basePackageName, caseNode.path);
-                val caseTypeBuilder = addDefaultInterfaceDefinition(packageName, caseNode);
-                caseTypeBuilder.addImplementsType(refChoiceType);
+                val packageName = packageNameForGeneratedType(basePackageName, caseNode.path)
+                val caseTypeBuilder = addDefaultInterfaceDefinition(packageName, caseNode)
+                caseTypeBuilder.addImplementsType(refChoiceType)
                 genCtx.get(module).addCaseType(caseNode.path, caseTypeBuilder)
-                val Set<DataSchemaNode> caseChildNodes = caseNode.childNodes;
+                val Set<DataSchemaNode> caseChildNodes = caseNode.childNodes
                 if (caseChildNodes !== null) {
-                    val parentNode = choiceNode.parent;
-                    var SchemaNode parent;
+                    var Object parentNode = null
+                    val SchemaPath nodeSp = choiceNode.path
+                    val List<QName> nodeNames = nodeSp.path
+                    val List<QName> nodeNewNames = new ArrayList(nodeNames)
+                    nodeNewNames.remove(nodeNewNames.size - 1)
+                    val SchemaPath nodeNewSp = new SchemaPath(nodeNewNames, nodeSp.absolute)
+                    parentNode = findDataSchemaNode(schemaContext, nodeNewSp)
+
+                    var SchemaNode parent
                     if (parentNode instanceof AugmentationSchema) {
                         val augSchema = parentNode as AugmentationSchema;
                         val targetPath = augSchema.targetPath;
-                        var targetSchemaNode = findDataSchemaNode(schemaContext, targetPath);
+                        var targetSchemaNode = findDataSchemaNode(schemaContext, targetPath)
                         if (targetSchemaNode instanceof DataSchemaNode &&
                             (targetSchemaNode as DataSchemaNode).isAddedByUses()) {
                             targetSchemaNode = findOriginal(targetSchemaNode as DataSchemaNode);
@@ -1200,12 +1363,17 @@ public class BindingGeneratorImpl implements BindingGenerator {
                                         " in module " + module.name);
                             }
                         }
-                        parent = targetSchemaNode as SchemaNode
+                        parent = targetSchemaNode
                     } else {
-                        parent = choiceNode.parent as SchemaNode;
+                        val SchemaPath sp = choiceNode.path
+                        val List<QName> names = sp.path
+                        val List<QName> newNames = new ArrayList(names)
+                        newNames.remove(newNames.size - 1)
+                        val SchemaPath newSp = new SchemaPath(newNames, sp.absolute)
+                        parent = findDataSchemaNode(schemaContext, newSp)
                     }
                     var GeneratedTypeBuilder childOfType = findChildNodeByPath(parent.path)
-                    resolveDataSchemaNodes(module, basePackageName, caseTypeBuilder, childOfType, caseChildNodes);
+                    resolveDataSchemaNodes(module, basePackageName, caseTypeBuilder, childOfType, caseChildNodes)
                 }
             }
 
@@ -1213,30 +1381,30 @@ public class BindingGeneratorImpl implements BindingGenerator {
         }
     }
 
-    /**\r
-     * Generates list of generated types for all the cases of a choice which are\r
-     * added to the choice through the augment.\r
-     *\r
-     *\r
-     * @param basePackageName\r
-     *            string contains name of package to which augment belongs. If\r
-     *            an augmented choice is from an other package (pcg1) than an\r
-     *            augmenting choice (pcg2) then case's of the augmenting choice\r
-     *            will belong to pcg2.\r
-     * @param refChoiceType\r
-     *            Type which represents the choice to which case belongs. Every\r
-     *            case has to contain its choice in extend part.\r
-     * @param caseNodes\r
-     *            set of choice case nodes for which is checked if are/aren't\r
-     *            added to choice through augmentation\r
-     * @return list of generated types which represents augmented cases of\r
-     *         choice <code>refChoiceType</code>\r
-     * @throws IllegalArgumentException\r
-     *             <ul>\r
-     *             <li>if <code>basePackageName</code> equals null</li>\r
-     *             <li>if <code>refChoiceType</code> equals null</li>\r
-     *             <li>if <code>caseNodes</code> equals null</li>\r
-     *             </ul>\r
+    /**
+     * 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
+     *            augmenting choice (pcg2) then case's of the augmenting choice
+     *            will belong to pcg2.
+     * @param refChoiceType
+     *            Type which represents the choice to which case belongs. Every
+     *            case has to contain its choice in extend part.
+     * @param caseNodes
+     *            set of choice case nodes for which is checked if are/aren't
+     *            added to choice through augmentation
+     * @return list of generated types which represents augmented cases of
+     *         choice <code>refChoiceType</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 def void generateTypesFromAugmentedChoiceCases(Module module, String basePackageName, Type targetType,
         ChoiceNode targetNode, Set<DataSchemaNode> augmentedNodes) {
@@ -1250,7 +1418,14 @@ public class BindingGeneratorImpl implements BindingGenerator {
                 val caseTypeBuilder = addDefaultInterfaceDefinition(packageName, caseNode);
                 caseTypeBuilder.addImplementsType(targetType);
 
-                val SchemaNode parent = targetNode.parent as SchemaNode;
+                var SchemaNode parent = null
+                val SchemaPath nodeSp = targetNode.path
+                val List<QName> nodeNames = nodeSp.path
+                val List<QName> nodeNewNames = new ArrayList(nodeNames)
+                nodeNewNames.remove(nodeNewNames.size - 1)
+                val SchemaPath nodeNewSp = new SchemaPath(nodeNewNames, nodeSp.absolute)
+                parent = findDataSchemaNode(schemaContext, nodeNewSp)
+
                 var GeneratedTypeBuilder childOfType = null;
                 if (parent instanceof Module) {
                     childOfType = genCtx.get(parent as Module).moduleNode
@@ -1286,22 +1461,22 @@ public class BindingGeneratorImpl implements BindingGenerator {
 
     }
 
-    /**\r
-     * Converts <code>leaf</code> to the getter method which is added to\r
-     * <code>typeBuilder</code>.\r
-     *\r
-     * @param typeBuilder\r
-     *            generated type builder to which is added getter method as\r
-     *            <code>leaf</code> mapping\r
-     * @param leaf\r
-     *            leaf schema node which is mapped as getter method which is\r
-     *            added to <code>typeBuilder</code>\r
-     * @return boolean value\r
-     *         <ul>\r
-     *         <li>false - if <code>leaf</code> or <code>typeBuilder</code> are\r
-     *         null</li>\r
-     *         <li>true - in other cases</li>\r
-     *         </ul>\r
+    /**
+     * 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 def boolean resolveLeafSchemaNodeAsMethod(GeneratedTypeBuilder typeBuilder, LeafSchemaNode leaf) {
         if ((leaf !== null) && (typeBuilder !== null)) {
@@ -1316,27 +1491,28 @@ public class BindingGeneratorImpl implements BindingGenerator {
                 val TypeDefinition<?> typeDef = leaf.type;
 
                 var Type returnType = null;
+                var GeneratedTOBuilder genTOBuilder;
                 if (typeDef instanceof EnumTypeDefinition) {
                     returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, leaf);
                     val enumTypeDef = typeDef as EnumTypeDefinition;
-                    val enumBuilder = resolveInnerEnumFromTypeDefinition(enumTypeDef, leafName, typeBuilder);
+                    val enumBuilder = resolveInnerEnumFromTypeDefinition(enumTypeDef, leaf.QName, typeBuilder);
 
                     if (enumBuilder !== null) {
                         returnType = new ReferencedTypeImpl(enumBuilder.packageName, enumBuilder.name);
                     }
                     (typeProvider as TypeProviderImpl).putReferencedType(leaf.path, returnType);
                 } else if (typeDef instanceof UnionType) {
-                    val genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, leafName, leaf, parentModule);
+                    genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, leaf, parentModule);
                     if (genTOBuilder !== null) {
-                        returnType = new ReferencedTypeImpl(genTOBuilder.packageName, genTOBuilder.name);
+                        returnType = createReturnTypeForUnion(genTOBuilder, typeDef, typeBuilder, parentModule)
                     }
                 } else if (typeDef instanceof BitsTypeDefinition) {
-                    val genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, leafName, leaf, parentModule);
+                    genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, leaf, parentModule);
                     if (genTOBuilder !== null) {
                         returnType = new ReferencedTypeImpl(genTOBuilder.packageName, genTOBuilder.name);
                     }
-                } else {\r
-                    val Restrictions restrictions = BindingGeneratorUtil.getRestrictions(typeDef);\r
+                } else {
+                    val Restrictions restrictions = BindingGeneratorUtil.getRestrictions(typeDef);
                     returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, leaf, restrictions);
                 }
                 if (returnType !== null) {
@@ -1381,7 +1557,7 @@ public class BindingGeneratorImpl implements BindingGenerator {
                 val Class<RoutingContext> clazz = typeof(RoutingContext);
                 val AnnotationTypeBuilder rc = getter.addAnnotation(clazz.package.name, clazz.simpleName);
                 val packageName = packageNameForGeneratedType(basePackageName, identity.path);
-                val genTypeName = parseToClassName(identity.QName.localName);
+                val genTypeName = BindingMapping.getClassName(identity.QName.localName);
                 rc.addParameter("value", packageName + "." + genTypeName + ".class");
             }
         }
@@ -1405,27 +1581,27 @@ public class BindingGeneratorImpl implements BindingGenerator {
         return null;
     }
 
-    /**\r
-     * Converts <code>leaf</code> schema node to property of generated TO\r
-     * builder.\r
-     *\r
-     * @param toBuilder\r
-     *            generated TO builder to which is <code>leaf</code> added as\r
-     *            property\r
-     * @param leaf\r
-     *            leaf schema node which is added to <code>toBuilder</code> as\r
-     *            property\r
-     * @param isReadOnly\r
-     *            boolean value which says if leaf property is|isn't read only\r
-     * @return boolean value\r
-     *         <ul>\r
-     *         <li>false - if <code>leaf</code>, <code>toBuilder</code> or leaf\r
-     *         name equals null or if leaf is added by <i>uses</i>.</li>\r
-     *         <li>true - other cases</li>\r
-     *         </ul>\r
+    /**
+     * 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 def boolean resolveLeafSchemaNodeAsProperty(GeneratedTOBuilder toBuilder, LeafSchemaNode leaf,
-        boolean isReadOnly) {
+        boolean isReadOnly, Module module) {
         if ((leaf !== null) && (toBuilder !== null)) {
             val leafName = leaf.QName.localName;
             var String leafDesc = leaf.description;
@@ -1434,10 +1610,23 @@ public class BindingGeneratorImpl implements BindingGenerator {
             }
 
             if (leafName !== null) {
+                var Type returnType = null;
                 val TypeDefinition<?> typeDef = leaf.type;
+                if (typeDef instanceof UnionTypeDefinition) {
+                    // GeneratedType for this type definition should be already created
+                    var qname = typeDef.QName
+                    var Module unionModule = null
+                    if (qname.prefix == null || qname.prefix.empty) {
+                        unionModule = module
+                    } else {
+                        unionModule = findModuleFromImports(module.imports, qname.prefix)
+                    }
+                    val ModuleContext mc = genCtx.get(unionModule)
+                    returnType = mc.typedefs.get(typeDef.path)
+                } else {
+                    returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, leaf);
+                }
 
-                // TODO: properly resolve enum types\r
-                val returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, leaf);
                 if (returnType !== null) {
                     val propBuilder = toBuilder.addProperty(parseToValidParamName(leafName));
                     propBuilder.setReadOnly(isReadOnly);
@@ -1453,73 +1642,119 @@ public class BindingGeneratorImpl implements BindingGenerator {
         return false;
     }
 
-    /**\r
-     * Converts <code>node</code> leaf list schema node to getter method of\r
-     * <code>typeBuilder</code>.\r
-     *\r
-     * @param typeBuilder\r
-     *            generated type builder to which is <code>node</code> added as\r
-     *            getter method\r
-     * @param node\r
-     *            leaf list schema node which is added to\r
-     *            <code>typeBuilder</code> as getter method\r
-     * @return boolean value\r
-     *         <ul>\r
-     *         <li>true - if <code>node</code>, <code>typeBuilder</code>,\r
-     *         nodeName equal null or <code>node</code> is added by <i>uses</i></li>\r
-     *         <li>false - other cases</li>\r
-     *         </ul>\r
+    /**
+     * 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 def boolean resolveLeafListSchemaNode(GeneratedTypeBuilder typeBuilder, LeafListSchemaNode node) {
         if ((node !== null) && (typeBuilder !== null)) {
-            val nodeName = node.QName.localName;
+            val nodeName = node.QName;
             var String nodeDesc = node.description;
             if (nodeDesc === null) {
                 nodeDesc = "";
             }
             if (nodeName !== null && !node.isAddedByUses()) {
-                val TypeDefinition<?> type = node.type;
-                val listType = Types.listTypeFor(typeProvider.javaTypeForSchemaDefinitionType(type, node));
-                constructGetter(typeBuilder, nodeName, nodeDesc, listType);
+                val TypeDefinition<?> typeDef = node.type;
+                val parentModule = findParentModule(schemaContext, node);
+
+                var Type returnType = null;
+                if (typeDef instanceof EnumTypeDefinition) {
+                    returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, node);
+                    val enumTypeDef = typeDef as EnumTypeDefinition;
+                    val enumBuilder = resolveInnerEnumFromTypeDefinition(enumTypeDef, nodeName, typeBuilder);
+                    returnType = new ReferencedTypeImpl(enumBuilder.packageName, enumBuilder.name);
+                    (typeProvider as TypeProviderImpl).putReferencedType(node.path, returnType);
+                } else if (typeDef instanceof UnionType) {
+                    val genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, node, parentModule);
+                    if (genTOBuilder !== null) {
+                        returnType = createReturnTypeForUnion(genTOBuilder, typeDef, typeBuilder, parentModule)
+                    }
+                } else if (typeDef instanceof BitsTypeDefinition) {
+                    val genTOBuilder = addTOToTypeBuilder(typeDef, typeBuilder, node, parentModule);
+                    returnType = new ReferencedTypeImpl(genTOBuilder.packageName, genTOBuilder.name);
+                } else {
+                    val Restrictions restrictions = BindingGeneratorUtil.getRestrictions(typeDef);
+                    returnType = typeProvider.javaTypeForSchemaDefinitionType(typeDef, node, restrictions);
+                }
+
+                val listType = Types.listTypeFor(returnType);
+                constructGetter(typeBuilder, nodeName.localName, nodeDesc, listType);
                 return true;
             }
         }
         return false;
     }
 
+    private def Type createReturnTypeForUnion(GeneratedTOBuilder genTOBuilder, TypeDefinition<?> typeDef,
+        GeneratedTypeBuilder typeBuilder, Module parentModule) {
+        val Type returnType = new ReferencedTypeImpl(genTOBuilder.packageName, genTOBuilder.name);
+        genTOBuilder.setTypedef(true);
+        genTOBuilder.setIsUnion(true);
+        (typeProvider as TypeProviderImpl).addUnitsToGenTO(genTOBuilder, typeDef.getUnits());
+
+        // union builder
+        val GeneratedTOBuilder unionBuilder = new GeneratedTOBuilderImpl(typeBuilder.getPackageName(),
+            genTOBuilder.getName() + "Builder");
+        unionBuilder.setIsUnionBuilder(true);
+        val MethodSignatureBuilder method = unionBuilder.addMethod("getDefaultInstance");
+        method.setReturnType(returnType);
+        method.addParameter(Types.STRING, "defaultValue");
+        method.setAccessModifier(AccessModifier.PUBLIC);
+        method.setStatic(true);
+
+        val Set<Type> types = (typeProvider as TypeProviderImpl).additionalTypes.get(parentModule);
+        if (types == null) {
+            (typeProvider as TypeProviderImpl).additionalTypes.put(parentModule,
+                Sets.newHashSet(unionBuilder.toInstance))
+        } else {
+            types.add(unionBuilder.toInstance)
+        }
+        return returnType
+    }
+
     private def GeneratedTypeBuilder addDefaultInterfaceDefinition(String packageName, SchemaNode schemaNode) {
         return addDefaultInterfaceDefinition(packageName, schemaNode, null);
     }
 
-    /**\r
-     * Instantiates generated type builder with <code>packageName</code> and\r
-     * <code>schemaNode</code>.\r
-     *\r
-     * The new builder always implements\r
-     * {@link org.opendaylight.yangtools.yang.binding.DataObject DataObject}.<br />\r
-     * If <code>schemaNode</code> is instance of GroupingDefinition it also\r
-     * implements {@link org.opendaylight.yangtools.yang.binding.Augmentable\r
-     * Augmentable}.<br />\r
-     * If <code>schemaNode</code> is instance of\r
-     * {@link org.opendaylight.yangtools.yang.model.api.DataNodeContainer\r
-     * DataNodeContainer} it can also implement nodes which are specified in\r
-     * <i>uses</i>.\r
-     *\r
-     * @param packageName\r
-     *            string with the name of the package to which\r
-     *            <code>schemaNode</code> belongs.\r
-     * @param schemaNode\r
-     *            schema node for which is created generated type builder\r
-     * @param parent parent type (can be null)\r
-     * @return generated type builder <code>schemaNode</code>\r
+    /**
+     * 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
+     *            string with the name of the package to which
+     *            <code>schemaNode</code> belongs.
+     * @param schemaNode
+     *            schema node for which is created generated type builder
+     * @param parent parent type (can be null)
+     * @return generated type builder <code>schemaNode</code>
      */
     private def GeneratedTypeBuilder addDefaultInterfaceDefinition(String packageName, SchemaNode schemaNode,
         Type parent) {
-        val it = addRawInterfaceDefinition(packageName, schemaNode, "");\r
-        val qname = schemaNode.QName;
-        //addConstant(QName.typeForClass,"QNAME",'''\r
-        //    org.opendaylight.yangtools.yang.common.QName.create("«qname.namespace»","«qname.formattedRevision»","«qname.localName»");\r
-        //''')\r
+        val it = addRawInterfaceDefinition(packageName, schemaNode, "");
+        qnameConstant(BindingMapping.QNAME_STATIC_FIELD_NAME,schemaNode.QName);
         if (parent === null) {
             addImplementsType(DATA_OBJECT);
         } else {
@@ -1536,43 +1771,43 @@ public class BindingGeneratorImpl implements BindingGenerator {
         return it;
     }
 
-    /**\r
-     * Wraps the calling of the same overloaded method.\r
-     *\r
-     * @param packageName\r
-     *            string with the package name to which returning generated type\r
-     *            builder belongs\r
-     * @param schemaNode\r
-     *            schema node which provide data about the schema node name\r
-     * @return generated type builder for <code>schemaNode</code>\r
+    /**
+     * Wraps the calling of the same overloaded method.
+     *
+     * @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>
      */
     private def GeneratedTypeBuilder addRawInterfaceDefinition(String packageName, SchemaNode schemaNode) {
         return addRawInterfaceDefinition(packageName, schemaNode, "");
     }
 
-    /**\r
-     * Returns reference to generated type builder for specified\r
-     * <code>schemaNode</code> with <code>packageName</code>.\r
-     *\r
-     * Firstly the generated type builder is searched in\r
-     * {@link BindingGeneratorImpl#genTypeBuilders genTypeBuilders}. If it isn't\r
-     * found it is created and added to <code>genTypeBuilders</code>.\r
-     *\r
-     * @param packageName\r
-     *            string with the package name to which returning generated type\r
-     *            builder belongs\r
-     * @param schemaNode\r
-     *            schema node which provide data about the schema node name\r
-     * @param prefix return type name prefix\r
-     * @return generated type builder for <code>schemaNode</code>\r
-     * @throws IllegalArgumentException\r
-     *             <ul>\r
-     *             <li>if <code>schemaNode</code> equals null</li>\r
-     *             <li>if <code>packageName</code> equals null</li>\r
-     *             <li>if Q name of schema node is null</li>\r
-     *             <li>if schema node name is nul</li>\r
-     *             </ul>\r
-     *\r
+    /**
+     * 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
+     * @param prefix return type name prefix
+     * @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 null</li>
+     *             </ul>
+     *
      */
     private def GeneratedTypeBuilder addRawInterfaceDefinition(String packageName, SchemaNode schemaNode,
         String prefix) {
@@ -1584,12 +1819,12 @@ public class BindingGeneratorImpl implements BindingGenerator {
 
         var String genTypeName;
         if (prefix === null) {
-            genTypeName = parseToClassName(schemaNodeName);
+            genTypeName = BindingMapping.getClassName(schemaNodeName);
         } else {
-            genTypeName = prefix + parseToClassName(schemaNodeName);
+            genTypeName = prefix + BindingMapping.getClassName(schemaNodeName);
         }
 
-        //FIXME: Validation of name conflict\r
+        //FIXME: Validation of name conflict
         val newType = new GeneratedTypeBuilderImpl(packageName, genTypeName);
         if (!genTypeBuilders.containsKey(packageName)) {
             val Map<String, GeneratedTypeBuilder> builders = new HashMap();
@@ -1604,14 +1839,14 @@ public class BindingGeneratorImpl implements BindingGenerator {
         return newType;
     }
 
-    /**\r
-     * Creates the name of the getter method from <code>methodName</code>.\r
-     *\r
-     * @param methodName\r
-     *            string with the name of the getter method\r
-     * @param returnType return type\r
-     * @return string with the name of the getter method for\r
-     *         <code>methodName</code> in JAVA method format\r
+    /**
+     * Creates the name of the getter method from <code>methodName</code>.
+     *
+     * @param methodName
+     *            string with the name of the getter method
+     * @param returnType return type
+     * @return string with the name of the getter method for
+     *         <code>methodName</code> in JAVA method format
      */
     public static def String getterMethodName(String localName, Type returnType) {
         val method = new StringBuilder();
@@ -1620,30 +1855,30 @@ public class BindingGeneratorImpl implements BindingGenerator {
         } else {
             method.append("get");
         }
-        method.append(parseToClassName(localName));
+        method.append(BindingMapping.getPropertyName(localName).toFirstUpper);
         return method.toString();
     }
 
-    /**\r
-     * Created a method signature builder as part of\r
-     * <code>interfaceBuilder</code>.\r
-     *\r
-     * The method signature builder is created for the getter method of\r
-     * <code>schemaNodeName</code>. Also <code>comment</code> and\r
-     * <code>returnType</code> information are added to the builder.\r
-     *\r
-     * @param interfaceBuilder\r
-     *            generated type builder for which the getter method should be\r
-     *            created\r
-     * @param schemaNodeName\r
-     *            string with schema node name. The name will be the part of the\r
-     *            getter method name.\r
-     * @param comment\r
-     *            string with comment for the getter method\r
-     * @param returnType\r
-     *            type which represents the return type of the getter method\r
-     * @return method signature builder which represents the getter method of\r
-     *         <code>interfaceBuilder</code>\r
+    /**
+     * 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 def MethodSignatureBuilder constructGetter(GeneratedTypeBuilder interfaceBuilder, String schemaNodeName,
         String comment, Type returnType) {
@@ -1653,28 +1888,28 @@ public class BindingGeneratorImpl implements BindingGenerator {
         return getMethod;
     }
 
-    /**\r
-     * Adds <code>schemaNode</code> to <code>typeBuilder</code> as getter method\r
-     * or to <code>genTOBuilder</code> as property.\r
-     *\r
-     * @param basePackageName\r
-     *            string contains the module package name\r
-     * @param schemaNode\r
-     *            data schema node which should be added as getter method to\r
-     *            <code>typeBuilder</code> or as a property to\r
-     *            <code>genTOBuilder</code> if is part of the list key\r
-     * @param typeBuilder\r
-     *            generated type builder for the list schema node\r
-     * @param genTOBuilder\r
-     *            generated TO builder for the list keys\r
-     * @param listKeys\r
-     *            list of string which contains names of the list keys\r
-     * @param module current module\r
-     * @throws IllegalArgumentException\r
-     *             <ul>\r
-     *             <li>if <code>schemaNode</code> equals null</li>\r
-     *             <li>if <code>typeBuilder</code> equals null</li>\r
-     *             </ul>\r
+    /**
+     * 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
+     * @param module current module
+     * @throws IllegalArgumentException
+     *             <ul>
+     *             <li>if <code>schemaNode</code> equals null</li>
+     *             <li>if <code>typeBuilder</code> equals null</li>
+     *             </ul>
      */
     private def void addSchemaNodeToListBuilders(String basePackageName, DataSchemaNode schemaNode,
         GeneratedTypeBuilder typeBuilder, GeneratedTOBuilder genTOBuilder, List<String> listKeys, Module module) {
@@ -1683,10 +1918,10 @@ public class BindingGeneratorImpl implements BindingGenerator {
 
         if (schemaNode instanceof LeafSchemaNode) {
             val leaf = schemaNode as LeafSchemaNode;
-            val leafName = leaf.QName.localName;\r
+            val leafName = leaf.QName.localName;
             resolveLeafSchemaNodeAsMethod(typeBuilder, leaf);
             if (listKeys.contains(leafName)) {
-                resolveLeafSchemaNodeAsProperty(genTOBuilder, leaf, true);
+                resolveLeafSchemaNodeAsProperty(genTOBuilder, leaf, true, module)
             }
         } else if (!schemaNode.addedByUses) {
             if (schemaNode instanceof LeafListSchemaNode) {
@@ -1711,15 +1946,15 @@ public class BindingGeneratorImpl implements BindingGenerator {
         }
     }
 
-    /**\r
-     * Selects the names of the list keys from <code>list</code> and returns\r
-     * them as the list of the strings\r
-     *\r
-     * @param list\r
-     *            of string with names of the list keys\r
-     * @return list of string which represents names of the list keys. If the\r
-     *         <code>list</code> contains no keys then the empty list is\r
-     *         returned.\r
+    /**
+     * Selects the names of the list keys from <code>list</code> and returns
+     * them as the list of the strings
+     *
+     * @param list
+     *            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 def listKeys(ListSchemaNode list) {
         val List<String> listKeys = new ArrayList();
@@ -1733,61 +1968,77 @@ public class BindingGeneratorImpl implements BindingGenerator {
         return listKeys;
     }
 
-    /**\r
-     * Generates for the <code>list</code> which contains any list keys special\r
-     * generated TO builder.\r
-     *\r
-     * @param packageName\r
-     *            string with package name to which the list belongs\r
-     * @param list\r
-     *            list schema node which is source of data about the list name\r
-     * @return generated TO builder which represents the keys of the\r
-     *         <code>list</code> or null if <code>list</code> is null or list of\r
-     *         key definitions is null or empty.\r
+    /**
+     * 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 def GeneratedTOBuilder resolveListKeyTOBuilder(String packageName, ListSchemaNode list) {
         var GeneratedTOBuilder genTOBuilder = null;
         if ((list.keyDefinition !== null) && (!list.keyDefinition.isEmpty())) {
             val listName = list.QName.localName + "Key";
-            val String genTOName = parseToClassName(listName);
+            val String genTOName = BindingMapping.getClassName(listName);
             genTOBuilder = new GeneratedTOBuilderImpl(packageName, genTOName);
         }
         return genTOBuilder;
     }
 
-    /**\r
-     * Builds generated TO builders for <code>typeDef</code> of type\r
-     * {@link org.opendaylight.yangtools.yang.model.util.UnionType UnionType} or\r
-     * {@link org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition\r
-     * BitsTypeDefinition} which are also added to <code>typeBuilder</code> as\r
-     * enclosing transfer object.\r
-     *\r
-     * If more then one generated TO builder is created for enclosing then all\r
-     * of the generated TO builders are added to <code>typeBuilder</code> as\r
-     * enclosing transfer objects.\r
-     *\r
-     * @param typeDef\r
-     *            type definition which can be of type <code>UnionType</code> or\r
-     *            <code>BitsTypeDefinition</code>\r
-     * @param typeBuilder\r
-     *            generated type builder to which is added generated TO created\r
-     *            from <code>typeDef</code>\r
-     * @param leafName\r
-     *            string with name for generated TO builder\r
-     * @param leaf\r
-     * @param parentModule\r
-     * @return generated TO builder for <code>typeDef</code>\r
+    /**
+     * 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
+     * @param leaf
+     * @param parentModule
+     * @return generated TO builder for <code>typeDef</code>
      */
     private def GeneratedTOBuilder addTOToTypeBuilder(TypeDefinition<?> typeDef, GeneratedTypeBuilder typeBuilder,
-        String leafName, LeafSchemaNode leaf, Module parentModule) {
-        val classNameFromLeaf = parseToClassName(leafName);
+        DataSchemaNode leaf, Module parentModule) {
+        val classNameFromLeaf = BindingMapping.getClassName(leaf.QName);
         val List<GeneratedTOBuilder> genTOBuilders = new ArrayList();
         val packageName = typeBuilder.fullyQualifiedName;
         if (typeDef instanceof UnionTypeDefinition) {
-            genTOBuilders.addAll(
-                (typeProvider as TypeProviderImpl).
+            val List<GeneratedTOBuilder> types = (typeProvider as TypeProviderImpl).
                     provideGeneratedTOBuildersForUnionTypeDef(packageName, (typeDef as UnionTypeDefinition),
-                        classNameFromLeaf, leaf));
+                        classNameFromLeaf, leaf); 
+            genTOBuilders.addAll(types);
+                        
+            
+        var GeneratedTOBuilder resultTOBuilder = null;
+        if (!types.isEmpty()) {
+            resultTOBuilder = types.remove(0);
+            for (GeneratedTOBuilder genTOBuilder : types) {
+                resultTOBuilder.addEnclosingTransferObject(genTOBuilder);
+            }
+        }
+
+        val GeneratedPropertyBuilder genPropBuilder = resultTOBuilder.addProperty("value");
+        genPropBuilder.setReturnType(Types.primitiveType("char[]", null));
+        resultTOBuilder.addEqualsIdentity(genPropBuilder);
+        resultTOBuilder.addHashIdentity(genPropBuilder);
+        resultTOBuilder.addToStringProperty(genPropBuilder);
+
         } else if (typeDef instanceof BitsTypeDefinition) {
             genTOBuilders.add(
                 ((typeProvider as TypeProviderImpl) ).
@@ -1803,21 +2054,21 @@ public class BindingGeneratorImpl implements BindingGenerator {
 
     }
 
-    /**\r
-     * Adds the implemented types to type builder.\r
-     *\r
-     * The method passes through the list of <i>uses</i> in\r
-     * {@code dataNodeContainer}. For every <i>use</i> is obtained coresponding\r
-     * generated type from {@link BindingGeneratorImpl#allGroupings\r
-     * allGroupings} which is added as <i>implements type</i> to\r
-     * <code>builder</code>\r
-     *\r
-     * @param dataNodeContainer\r
-     *            element which contains the list of used YANG groupings\r
-     * @param builder\r
-     *            builder to which are added implemented types according to\r
-     *            <code>dataNodeContainer</code>\r
-     * @return generated type builder with all implemented types\r
+    /**
+     * 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 corresponding
+     * generated type from {@link BindingGeneratorImpl#allGroupings
+     * allGroupings} which is added 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 with all implemented types
      */
     private def addImplementedInterfaceFromUses(DataNodeContainer dataNodeContainer, GeneratedTypeBuilder builder) {
         for (usesNode : dataNodeContainer.uses) {
@@ -1862,9 +2113,16 @@ public class BindingGeneratorImpl implements BindingGenerator {
         }
         return null
     }
-\r
-\r
-    public def getModuleContexts() {\r
-        genCtx;\r
+
+    private def Module getParentModule(SchemaNode node) {
+        val QName qname = node.getPath().getPath().get(0);
+        val URI namespace = qname.getNamespace();
+        val Date revision = qname.getRevision();
+        return schemaContext.findModuleByNamespaceAndRevision(namespace, revision);
+    }
+
+    public def getModuleContexts() {
+        genCtx;
     }
+
 }