Merge "BUG-2512: get rid of commons-io"
[yangtools.git] / code-generator / binding-type-provider / src / main / java / org / opendaylight / yangtools / sal / binding / yang / types / TypeProviderImpl.java
index fe685e2478144f47ae92fd1af01b10b540b05f88..bd81da916adfac7030a676661ad17d8be34ba83e 100644 (file)
@@ -7,20 +7,30 @@
  */
 package org.opendaylight.yangtools.sal.binding.yang.types;
 
-import static org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil.moduleNamespaceToPackageName;
 import static org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil.packageNameForGeneratedType;
-import static org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil.parseToValidParamName;
 import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.findDataSchemaNode;
 import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.findDataSchemaNodeForRelativeXPath;
 import static org.opendaylight.yangtools.yang.model.util.SchemaContextUtil.findParentModule;
-
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Sets;
+import com.google.common.io.BaseEncoding;
+import java.io.Serializable;
 import java.math.BigDecimal;
 import java.math.BigInteger;
 import java.net.URI;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
-
 import org.apache.commons.lang3.StringEscapeUtils;
 import org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil;
 import org.opendaylight.yangtools.binding.generator.util.TypeConstants;
@@ -32,6 +42,7 @@ import org.opendaylight.yangtools.sal.binding.generator.spi.TypeProvider;
 import org.opendaylight.yangtools.sal.binding.model.api.AccessModifier;
 import org.opendaylight.yangtools.sal.binding.model.api.ConcreteType;
 import org.opendaylight.yangtools.sal.binding.model.api.Enumeration;
+import org.opendaylight.yangtools.sal.binding.model.api.GeneratedProperty;
 import org.opendaylight.yangtools.sal.binding.model.api.GeneratedTransferObject;
 import org.opendaylight.yangtools.sal.binding.model.api.Restrictions;
 import org.opendaylight.yangtools.sal.binding.model.api.Type;
@@ -51,16 +62,36 @@ import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.opendaylight.yangtools.yang.model.api.SchemaNode;
 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
-import org.opendaylight.yangtools.yang.model.api.type.*;
+import org.opendaylight.yangtools.yang.model.api.type.BinaryTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition;
 import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition.Bit;
-import org.opendaylight.yangtools.yang.model.util.*;
-import org.opendaylight.yangtools.yang.parser.util.ModuleDependencySort;
-
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Sets;
-import com.google.common.io.BaseEncoding;
+import org.opendaylight.yangtools.yang.model.api.type.BooleanTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.DecimalTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.EmptyTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.InstanceIdentifierTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.LeafrefTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.PatternConstraint;
+import org.opendaylight.yangtools.yang.model.api.type.StringTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition;
+import org.opendaylight.yangtools.yang.model.util.DataNodeIterator;
+import org.opendaylight.yangtools.yang.model.util.EnumerationType;
+import org.opendaylight.yangtools.yang.model.util.ExtendedType;
+import org.opendaylight.yangtools.yang.model.util.Int16;
+import org.opendaylight.yangtools.yang.model.util.Int32;
+import org.opendaylight.yangtools.yang.model.util.Int64;
+import org.opendaylight.yangtools.yang.model.util.Int8;
+import org.opendaylight.yangtools.yang.model.util.StringType;
+import org.opendaylight.yangtools.yang.model.util.Uint16;
+import org.opendaylight.yangtools.yang.model.util.Uint32;
+import org.opendaylight.yangtools.yang.model.util.Uint64;
+import org.opendaylight.yangtools.yang.model.util.Uint8;
+import org.opendaylight.yangtools.yang.model.util.UnionType;
 
 public final class TypeProviderImpl implements TypeProvider {
+    private static final Pattern NUMBERS_PATTERN = Pattern.compile("[0-9]+\\z");
+
     /**
      * Contains the schema data red from YANG files.
      */
@@ -69,7 +100,7 @@ public final class TypeProviderImpl implements TypeProvider {
     /**
      * Map<moduleName, Map<moduleDate, Map<typeName, type>>>
      */
-    private Map<String, Map<Date, Map<String, Type>>> genTypeDefsContextMap;
+    private final Map<String, Map<Date, Map<String, Type>>> genTypeDefsContextMap;
 
     /**
      * The map which maps schema paths to JAVA <code>Type</code>.
@@ -130,7 +161,8 @@ public final class TypeProviderImpl implements TypeProvider {
      * @see TypeProvider#javaTypeForYangType(String)
      */
     @Override
-    public Type javaTypeForYangType(String type) {
+    @Deprecated
+    public Type javaTypeForYangType(final String type) {
         return BaseYangTypes.BASE_YANG_TYPES_PROVIDER.javaTypeForYangType(type);
     }
 
@@ -154,18 +186,27 @@ public final class TypeProviderImpl implements TypeProvider {
      */
     @Override
     public Type javaTypeForSchemaDefinitionType(final TypeDefinition<?> typeDefinition, final SchemaNode parentNode,
-            Restrictions r) {
-        Type returnType = null;
+            final Restrictions r) {
+        Type returnType;
         Preconditions.checkArgument(typeDefinition != null, "Type Definition cannot be NULL!");
-        if (typeDefinition.getQName() == null) {
-            throw new IllegalArgumentException(
-                    "Type Definition cannot have non specified QName (QName cannot be NULL!)");
-        }
-        Preconditions.checkArgument(typeDefinition.getQName().getLocalName() != null,
-                "Type Definitions Local Name cannot be NULL!");
+        Preconditions.checkArgument(typeDefinition.getQName() != null,
+                "Type Definition cannot have non specified QName (QName cannot be NULL!)");
+        String typedefName = typeDefinition.getQName().getLocalName();
+        Preconditions.checkArgument(typedefName != null, "Type Definitions Local Name cannot be NULL!");
 
         if (typeDefinition instanceof ExtendedType) {
             returnType = javaTypeForExtendedType(typeDefinition);
+            if (r != null && returnType instanceof GeneratedTransferObject) {
+                GeneratedTransferObject gto = (GeneratedTransferObject) returnType;
+                Module module = findParentModule(schemaContext, parentNode);
+                String basePackageName = BindingMapping.getRootPackageName(module.getQNameModule());
+                String packageName = packageNameForGeneratedType(basePackageName, typeDefinition.getPath());
+                String genTOName = BindingMapping.getClassName(typedefName);
+                String name = packageName + "." + genTOName;
+                if (!(returnType.getFullyQualifiedName().equals(name))) {
+                    returnType = shadedTOWithRestrictions(gto, r);
+                }
+            }
         } else {
             returnType = javaTypeForLeafrefOrIdentityRef(typeDefinition, parentNode);
             if (returnType == null) {
@@ -173,15 +214,28 @@ public final class TypeProviderImpl implements TypeProvider {
                         .getLocalName());
             }
         }
-        // TODO: add throw exception when we will be able to resolve ALL yang
-        // types!
-        // if (returnType == null) {
-        // throw new IllegalArgumentException("Type Provider can't resolve " +
-        // "type for specified Type Definition " + typedefName);
-        // }
         return returnType;
     }
 
+    private GeneratedTransferObject shadedTOWithRestrictions(final GeneratedTransferObject gto, final Restrictions r) {
+        GeneratedTOBuilder gtob = new GeneratedTOBuilderImpl(gto.getPackageName(), gto.getName());
+        GeneratedTransferObject parent = gto.getSuperType();
+        if (parent != null) {
+            gtob.setExtendsType(parent);
+        }
+        gtob.setRestrictions(r);
+        for (GeneratedProperty gp : gto.getProperties()) {
+            GeneratedPropertyBuilder gpb = gtob.addProperty(gp.getName());
+            gpb.setValue(gp.getValue());
+            gpb.setReadOnly(gp.isReadOnly());
+            gpb.setAccessModifier(gp.getAccessModifier());
+            gpb.setReturnType(gp.getReturnType());
+            gpb.setFinal(gp.isFinal());
+            gpb.setStatic(gp.isStatic());
+        }
+        return gtob.toInstance();
+    }
+
     /**
      * Returns JAVA <code>Type</code> for instances of the type
      * <code>LeafrefTypeDefinition</code> or
@@ -191,7 +245,7 @@ public final class TypeProviderImpl implements TypeProvider {
      *            type definition which is converted to JAVA <code>Type</code>
      * @return JAVA <code>Type</code> instance for <code>typeDefinition</code>
      */
-    private Type javaTypeForLeafrefOrIdentityRef(TypeDefinition<?> typeDefinition, SchemaNode parentNode) {
+    private Type javaTypeForLeafrefOrIdentityRef(final TypeDefinition<?> typeDefinition, final SchemaNode parentNode) {
         if (typeDefinition instanceof LeafrefTypeDefinition) {
             final LeafrefTypeDefinition leafref = (LeafrefTypeDefinition) typeDefinition;
             return provideTypeForLeafref(leafref, parentNode);
@@ -211,11 +265,10 @@ public final class TypeProviderImpl implements TypeProvider {
      *            type definition which is converted to JAVA <code>Type</code>
      * @return JAVA <code>Type</code> instance for <code>typeDefinition</code>
      */
-    private Type javaTypeForExtendedType(TypeDefinition<?> typeDefinition) {
+    private Type javaTypeForExtendedType(final TypeDefinition<?> typeDefinition) {
         final String typedefName = typeDefinition.getQName().getLocalName();
         final TypeDefinition<?> baseTypeDef = baseTypeDefForExtendedType(typeDefinition);
-        Type returnType = null;
-        returnType = javaTypeForLeafrefOrIdentityRef(baseTypeDef, typeDefinition);
+        Type returnType = javaTypeForLeafrefOrIdentityRef(baseTypeDef, typeDefinition);
         if (returnType == null) {
             if (baseTypeDef instanceof EnumTypeDefinition) {
                 final EnumTypeDefinition enumTypeDef = (EnumTypeDefinition) baseTypeDef;
@@ -237,12 +290,6 @@ public final class TypeProviderImpl implements TypeProvider {
             }
         }
         return returnType;
-        // TODO: add throw exception when we will be able to resolve ALL yang
-        // types!
-        // if (returnType == null) {
-        // throw new IllegalArgumentException("Type Provider can't resolve " +
-        // "type for specified Type Definition " + typedefName);
-        // }
     }
 
     /**
@@ -260,7 +307,7 @@ public final class TypeProviderImpl implements TypeProvider {
      * @return JAVA <code>Type</code> of the identity which is refrenced through
      *         <code>idref</code>
      */
-    private Type provideTypeForIdentityref(IdentityrefTypeDefinition idref) {
+    private Type provideTypeForIdentityref(final IdentityrefTypeDefinition idref) {
         QName baseIdQName = idref.getIdentity().getQName();
         Module module = schemaContext.findModuleByNamespaceAndRevision(baseIdQName.getNamespace(),
                 baseIdQName.getRevision());
@@ -272,7 +319,7 @@ public final class TypeProviderImpl implements TypeProvider {
         }
         Preconditions.checkArgument(identity != null, "Target identity '" + baseIdQName + "' do not exists");
 
-        final String basePackageName = moduleNamespaceToPackageName(module);
+        final String basePackageName = BindingMapping.getRootPackageName(module.getQNameModule());
         final String packageName = packageNameForGeneratedType(basePackageName, identity.getPath());
         final String genTypeName = BindingMapping.getClassName(identity.getQName());
 
@@ -337,7 +384,7 @@ public final class TypeProviderImpl implements TypeProvider {
      *             if <code>extendTypeDef</code> equal null
      */
     private TypeDefinition<?> baseTypeDefForExtendedType(final TypeDefinition<?> extendTypeDef) {
-        Preconditions.checkArgument(extendTypeDef != null, "Type Definiition reference cannot be NULL!");
+        Preconditions.checkArgument(extendTypeDef != null, "Type Definition reference cannot be NULL!");
         final TypeDefinition<?> baseTypeDef = extendTypeDef.getBaseType();
         if (baseTypeDef == null) {
             return extendTypeDef;
@@ -377,9 +424,7 @@ public final class TypeProviderImpl implements TypeProvider {
         final String strXPath = xpath.toString();
 
         if (strXPath != null) {
-            if (strXPath.contains("[")) {
-                returnType = Types.typeForClass(Object.class);
-            } else {
+            if (strXPath.indexOf('[') == -1) {
                 final Module module = findParentModule(schemaContext, parentNode);
                 if (module != null) {
                     final SchemaNode dataNode;
@@ -397,6 +442,8 @@ public final class TypeProviderImpl implements TypeProvider {
                         returnType = resolveTypeFromDataSchemaNode(dataNode);
                     }
                 }
+            } else {
+                returnType = Types.typeForClass(Object.class);
             }
         }
         if (returnType == null) {
@@ -483,9 +530,13 @@ public final class TypeProviderImpl implements TypeProvider {
         final String enumerationName = BindingMapping.getClassName(enumName);
 
         Module module = findParentModule(schemaContext, parentNode);
-        final String basePackageName = moduleNamespaceToPackageName(module);
+        final String basePackageName = BindingMapping.getRootPackageName(module.getQNameModule());
 
-        final EnumBuilder enumBuilder = new EnumerationBuilderImpl(basePackageName, enumerationName);
+        final EnumerationBuilderImpl enumBuilder = new EnumerationBuilderImpl(basePackageName, enumerationName);
+        enumBuilder.setDescription(enumTypeDef.getDescription());
+        enumBuilder.setReference(enumTypeDef.getReference());
+        enumBuilder.setModuleName(module.getName());
+        enumBuilder.setSchemaPath(enumTypeDef.getPath().getPathFromRoot());
         enumBuilder.updateEnumPairsFromEnumTypeDef(enumTypeDef);
         return enumBuilder.toInstance(null);
     }
@@ -526,6 +577,7 @@ public final class TypeProviderImpl implements TypeProvider {
         final String enumerationName = BindingMapping.getClassName(enumName);
 
         final EnumBuilder enumBuilder = typeBuilder.addEnumeration(enumerationName);
+        enumBuilder.setDescription(enumTypeDef.getDescription());
         enumBuilder.updateEnumPairsFromEnumTypeDef(enumTypeDef);
         return enumBuilder.toInstance(enumBuilder);
     }
@@ -567,21 +619,21 @@ public final class TypeProviderImpl implements TypeProvider {
      */
     private void resolveTypeDefsFromContext() {
         final Set<Module> modules = schemaContext.getModules();
-        Preconditions.checkArgument(modules != null, "Sef of Modules cannot be NULL!");
+        Preconditions.checkArgument(modules != null, "Set of Modules cannot be NULL!");
         final Module[] modulesArray = new Module[modules.size()];
         int i = 0;
         for (Module modul : modules) {
             modulesArray[i++] = modul;
         }
-        final List<Module> modulesSortedByDependency = ModuleDependencySort.sort(modulesArray);
+        final List<Module> modulesSortedByDependency = org.opendaylight.yangtools.yang.parser.util.ModuleDependencySort
+                .sort(modulesArray);
 
         for (final Module module : modulesSortedByDependency) {
             Map<Date, Map<String, Type>> dateTypeMap = genTypeDefsContextMap.get(module.getName());
             if (dateTypeMap == null) {
                 dateTypeMap = new HashMap<>();
             }
-            final Map<String, Type> typeMap = new HashMap<>();
-            dateTypeMap.put(module.getRevision(), typeMap);
+            dateTypeMap.put(module.getRevision(), Collections.<String, Type>emptyMap());
             genTypeDefsContextMap.put(module.getName(), dateTypeMap);
         }
 
@@ -589,7 +641,7 @@ public final class TypeProviderImpl implements TypeProvider {
             if (module == null) {
                 continue;
             }
-            final String basePackageName = moduleNamespaceToPackageName(module);
+            final String basePackageName = BindingMapping.getRootPackageName(module.getQNameModule());
 
             final DataNodeIterator it = new DataNodeIterator(module);
             final List<TypeDefinition<?>> typeDefinitions = it.allTypedefs();
@@ -607,7 +659,7 @@ public final class TypeProviderImpl implements TypeProvider {
      *
      * @param basePackageName
      *            string with name of package to which the module belongs
-     * @param moduleName
+     * @param module
      *            string with the name of the module for to which the
      *            <code>typedef</code> belongs
      * @param typedef
@@ -623,7 +675,6 @@ public final class TypeProviderImpl implements TypeProvider {
         final String moduleName = module.getName();
         final Date moduleRevision = module.getRevision();
         if ((basePackageName != null) && (moduleName != null) && (typedef != null) && (typedef.getQName() != null)) {
-
             final String typedefName = typedef.getQName().getLocalName();
             final TypeDefinition<?> innerTypeDefinition = typedef.getBaseType();
             if (!(innerTypeDefinition instanceof LeafrefTypeDefinition)
@@ -631,13 +682,15 @@ public final class TypeProviderImpl implements TypeProvider {
                 Type returnType = null;
                 if (innerTypeDefinition instanceof ExtendedType) {
                     ExtendedType innerExtendedType = (ExtendedType) innerTypeDefinition;
-                    returnType = provideGeneratedTOFromExtendedType(typedef, innerExtendedType, basePackageName);
+                    returnType = provideGeneratedTOFromExtendedType(typedef, innerExtendedType, basePackageName,
+                            module.getName());
                 } else if (innerTypeDefinition instanceof UnionTypeDefinition) {
                     final GeneratedTOBuilder genTOBuilder = provideGeneratedTOBuilderForUnionTypeDef(basePackageName,
                             (UnionTypeDefinition) innerTypeDefinition, typedefName, typedef);
                     genTOBuilder.setTypedef(true);
                     genTOBuilder.setIsUnion(true);
                     addUnitsToGenTO(genTOBuilder, typedef.getUnits());
+                    makeSerializable((GeneratedTOBuilderImpl) genTOBuilder);
                     returnType = genTOBuilder.toInstance();
                     // union builder
                     GeneratedTOBuilder unionBuilder = new GeneratedTOBuilderImpl(genTOBuilder.getPackageName(),
@@ -656,25 +709,31 @@ public final class TypeProviderImpl implements TypeProvider {
                         types.add(unionBuilder.toInstance());
                     }
                 } else if (innerTypeDefinition instanceof EnumTypeDefinition) {
+                    // enums are automatically Serializable
                     final EnumTypeDefinition enumTypeDef = (EnumTypeDefinition) innerTypeDefinition;
                     // TODO units for typedef enum
                     returnType = provideTypeForEnum(enumTypeDef, typedefName, typedef);
                 } else if (innerTypeDefinition instanceof BitsTypeDefinition) {
                     final BitsTypeDefinition bitsTypeDefinition = (BitsTypeDefinition) innerTypeDefinition;
                     final GeneratedTOBuilder genTOBuilder = provideGeneratedTOBuilderForBitsTypeDefinition(
-                            basePackageName, bitsTypeDefinition, typedefName);
+                            basePackageName, bitsTypeDefinition, typedefName, module.getName());
                     genTOBuilder.setTypedef(true);
                     addUnitsToGenTO(genTOBuilder, typedef.getUnits());
+                    makeSerializable((GeneratedTOBuilderImpl) genTOBuilder);
                     returnType = genTOBuilder.toInstance();
                 } else {
                     final Type javaType = BaseYangTypes.BASE_YANG_TYPES_PROVIDER.javaTypeForSchemaDefinitionType(
                             innerTypeDefinition, typedef);
-                    returnType = wrapJavaTypeIntoTO(basePackageName, typedef, javaType);
+                    returnType = wrapJavaTypeIntoTO(basePackageName, typedef, javaType, module.getName());
                 }
                 if (returnType != null) {
                     final Map<Date, Map<String, Type>> modulesByDate = genTypeDefsContextMap.get(moduleName);
-                    final Map<String, Type> typeMap = modulesByDate.get(moduleRevision);
+                    Map<String, Type> typeMap = modulesByDate.get(moduleRevision);
                     if (typeMap != null) {
+                        if (typeMap.isEmpty()) {
+                            typeMap = new HashMap<>(4);
+                            modulesByDate.put(moduleRevision, typeMap);
+                        }
                         typeMap.put(typedefName, returnType);
                     }
                     return returnType;
@@ -696,11 +755,11 @@ public final class TypeProviderImpl implements TypeProvider {
      * @return generated transfer object which represent<code>javaType</code>
      */
     private GeneratedTransferObject wrapJavaTypeIntoTO(final String basePackageName, final TypeDefinition<?> typedef,
-            final Type javaType) {
+            final Type javaType, final String moduleName) {
         Preconditions.checkNotNull(javaType, "javaType cannot be null");
         final String propertyName = "value";
 
-        final GeneratedTOBuilder genTOBuilder = typedefToTransferObject(basePackageName, typedef);
+        final GeneratedTOBuilder genTOBuilder = typedefToTransferObject(basePackageName, typedef, moduleName);
         genTOBuilder.setRestrictions(BindingGeneratorUtil.getRestrictions(typedef));
         final GeneratedPropertyBuilder genPropBuilder = genTOBuilder.addProperty(propertyName);
         genPropBuilder.setReturnType(javaType);
@@ -713,6 +772,7 @@ public final class TypeProviderImpl implements TypeProvider {
         }
         addUnitsToGenTO(genTOBuilder, typedef.getUnits());
         genTOBuilder.setTypedef(true);
+        makeSerializable((GeneratedTOBuilderImpl) genTOBuilder);
         return genTOBuilder.toInstance();
     }
 
@@ -731,19 +791,21 @@ public final class TypeProviderImpl implements TypeProvider {
      *         builders
      */
     public GeneratedTOBuilder provideGeneratedTOBuilderForUnionTypeDef(final String basePackageName,
-            final UnionTypeDefinition typedef, String typeDefName, SchemaNode parentNode) {
+            final UnionTypeDefinition typedef, final String typeDefName, final SchemaNode parentNode) {
         final List<GeneratedTOBuilder> genTOBuilders = provideGeneratedTOBuildersForUnionTypeDef(basePackageName,
                 typedef, typeDefName, parentNode);
         GeneratedTOBuilder resultTOBuilder = null;
-        if (!genTOBuilders.isEmpty()) {
-            resultTOBuilder = genTOBuilders.remove(0);
-            for (GeneratedTOBuilder genTOBuilder : genTOBuilders) {
-                resultTOBuilder.addEnclosingTransferObject(genTOBuilder);
-            }
+        if (genTOBuilders.isEmpty()) {
+            throw new IllegalStateException("No GeneratedTOBuilder objects generated from union " + typedef);
+        }
+
+        resultTOBuilder = genTOBuilders.remove(0);
+        for (GeneratedTOBuilder genTOBuilder : genTOBuilders) {
+            resultTOBuilder.addEnclosingTransferObject(genTOBuilder);
         }
 
         final GeneratedPropertyBuilder genPropBuilder = resultTOBuilder.addProperty("value");
-        genPropBuilder.setReturnType(Types.primitiveType("char[]", null));
+        genPropBuilder.setReturnType(Types.CHAR_ARRAY);
         resultTOBuilder.addEqualsIdentity(genPropBuilder);
         resultTOBuilder.addHashIdentity(genPropBuilder);
         resultTOBuilder.addToStringProperty(genPropBuilder);
@@ -779,13 +841,18 @@ public final class TypeProviderImpl implements TypeProvider {
 
         final List<GeneratedTOBuilder> generatedTOBuilders = new ArrayList<>();
         final List<TypeDefinition<?>> unionTypes = typedef.getTypes();
+        final Module module = findParentModule(schemaContext, parentNode);
 
-        final GeneratedTOBuilder unionGenTOBuilder;
+        final GeneratedTOBuilderImpl unionGenTOBuilder;
         if (typeDefName != null && !typeDefName.isEmpty()) {
             final String typeName = BindingMapping.getClassName(typeDefName);
             unionGenTOBuilder = new GeneratedTOBuilderImpl(basePackageName, typeName);
+            unionGenTOBuilder.setDescription(typedef.getDescription());
+            unionGenTOBuilder.setReference(typedef.getReference());
+            unionGenTOBuilder.setSchemaPath(typedef.getPath().getPathFromRoot());
+            unionGenTOBuilder.setModuleName(module.getName());
         } else {
-            unionGenTOBuilder = typedefToTransferObject(basePackageName, typedef);
+            unionGenTOBuilder = typedefToTransferObject(basePackageName, typedef, module.getName());
         }
 
         generatedTOBuilders.add(unionGenTOBuilder);
@@ -824,7 +891,8 @@ public final class TypeProviderImpl implements TypeProvider {
      *
      * In this case the new generated TO is created for union subtype (recursive
      * call of method
-     * {@link #provideGeneratedTOBuildersForUnionTypeDef(String, TypeDefinition, String)
+     * {@link #provideGeneratedTOBuildersForUnionTypeDef(String, UnionTypeDefinition,
+     * String, SchemaNode)}
      * provideGeneratedTOBuilderForUnionTypeDef} and in parent TO builder
      * <code>parentUnionGenTOBuilder</code> is created property which type is
      * equal to new generated TO.
@@ -847,8 +915,7 @@ public final class TypeProviderImpl implements TypeProvider {
                 basePackageName, unionSubtype, newTOBuilderName, parentNode);
 
         final GeneratedPropertyBuilder propertyBuilder;
-        propertyBuilder = parentUnionGenTOBuilder.addProperty(BindingGeneratorUtil
-                .parseToValidParamName(newTOBuilderName));
+        propertyBuilder = parentUnionGenTOBuilder.addProperty(BindingMapping.getPropertyName(newTOBuilderName));
         propertyBuilder.setReturnType(subUnionGenTOBUilders.get(0));
         parentUnionGenTOBuilder.addEqualsIdentity(propertyBuilder);
         parentUnionGenTOBuilder.addToStringProperty(propertyBuilder);
@@ -869,14 +936,14 @@ public final class TypeProviderImpl implements TypeProvider {
      * @param unionSubtype
      *            type definition of the <code>ExtendedType</code> type which
      *            represents union subtype
-     * @param unionTypeName
-     *            string with the name for <code>unionSubtype</code>
      * @param regularExpressions
      *            list of strings with the regular expressions
+     * @param parentNode
+     *            parent Schema Node for Extended Subtype
+     *
      */
     private void resolveExtendedSubtypeAsUnion(final GeneratedTOBuilder parentUnionGenTOBuilder,
-            final ExtendedType unionSubtype, final List<String> regularExpressions,
-            final SchemaNode parentNode) {
+            final ExtendedType unionSubtype, final List<String> regularExpressions, final SchemaNode parentNode) {
         final String unionTypeName = unionSubtype.getQName().getLocalName();
         final Type genTO = findGenTO(unionTypeName, unionSubtype);
         if (genTO != null) {
@@ -928,7 +995,8 @@ public final class TypeProviderImpl implements TypeProvider {
      *            generated TO builder which is converted to generated TO and
      *            stored
      */
-    private void storeGenTO(TypeDefinition<?> newTypeDef, GeneratedTOBuilder genTOBuilder, SchemaNode parentNode) {
+    private void storeGenTO(final TypeDefinition<?> newTypeDef, final GeneratedTOBuilder genTOBuilder,
+            final SchemaNode parentNode) {
         if (!(newTypeDef instanceof UnionType)) {
 
             final Module parentModule = findParentModule(schemaContext, parentNode);
@@ -957,7 +1025,7 @@ public final class TypeProviderImpl implements TypeProvider {
             final String propertyName) {
         if (unionGenTransObject != null && type != null && !unionGenTransObject.containsProperty(propertyName)) {
             final GeneratedPropertyBuilder propBuilder = unionGenTransObject
-                    .addProperty(parseToValidParamName(propertyName));
+                    .addProperty(BindingMapping.getPropertyName(propertyName));
             propBuilder.setReturnType(type);
 
             unionGenTransObject.addEqualsIdentity(propBuilder);
@@ -976,15 +1044,21 @@ public final class TypeProviderImpl implements TypeProvider {
      * @return generated TO builder which contains data from
      *         <code>typedef</code> and <code>basePackageName</code>
      */
-    private GeneratedTOBuilder typedefToTransferObject(final String basePackageName, final TypeDefinition<?> typedef) {
+    private GeneratedTOBuilderImpl typedefToTransferObject(final String basePackageName,
+            final TypeDefinition<?> typedef, final String moduleName) {
 
         final String packageName = packageNameForGeneratedType(basePackageName, typedef.getPath());
         final String typeDefTOName = typedef.getQName().getLocalName();
 
-        if ((packageName != null) && (typedef != null) && (typeDefTOName != null)) {
+        if ((packageName != null) && (typeDefTOName != null)) {
             final String genTOName = BindingMapping.getClassName(typeDefTOName);
-            final GeneratedTOBuilder newType = new GeneratedTOBuilderImpl(packageName, genTOName);
-            newType.addComment(typedef.getDescription());
+            final GeneratedTOBuilderImpl newType = new GeneratedTOBuilderImpl(packageName, genTOName);
+
+            newType.setDescription(typedef.getDescription());
+            newType.setReference(typedef.getReference());
+            newType.setSchemaPath(typedef.getPath().getPathFromRoot());
+            newType.setModuleName(moduleName);
+
             return newType;
         }
         return null;
@@ -1011,7 +1085,7 @@ public final class TypeProviderImpl implements TypeProvider {
      *             </ul>
      */
     public GeneratedTOBuilder provideGeneratedTOBuilderForBitsTypeDefinition(final String basePackageName,
-            final TypeDefinition<?> typeDef, String typeDefName) {
+            final TypeDefinition<?> typeDef, final String typeDefName, final String moduleName) {
 
         Preconditions.checkArgument(typeDef != null, "typeDef cannot be NULL!");
         Preconditions.checkArgument(basePackageName != null, "Base Package Name cannot be NULL!");
@@ -1020,13 +1094,19 @@ public final class TypeProviderImpl implements TypeProvider {
             BitsTypeDefinition bitsTypeDefinition = (BitsTypeDefinition) typeDef;
 
             final String typeName = BindingMapping.getClassName(typeDefName);
-            final GeneratedTOBuilder genTOBuilder = new GeneratedTOBuilderImpl(basePackageName, typeName);
+            final GeneratedTOBuilderImpl genTOBuilder = new GeneratedTOBuilderImpl(basePackageName, typeName);
+
+            genTOBuilder.setDescription(typeDef.getDescription());
+            genTOBuilder.setReference(typeDef.getReference());
+            genTOBuilder.setSchemaPath(typeDef.getPath().getPathFromRoot());
+            genTOBuilder.setModuleName(moduleName);
+            genTOBuilder.setBaseType(typeDef);
 
             final List<Bit> bitList = bitsTypeDefinition.getBits();
             GeneratedPropertyBuilder genPropertyBuilder;
             for (final Bit bit : bitList) {
                 String name = bit.getName();
-                genPropertyBuilder = genTOBuilder.addProperty(parseToValidParamName(name));
+                genPropertyBuilder = genTOBuilder.addProperty(BindingMapping.getPropertyName(name));
                 genPropertyBuilder.setReadOnly(true);
                 genPropertyBuilder.setReturnType(BaseYangTypes.BOOLEAN_TYPE);
 
@@ -1051,7 +1131,7 @@ public final class TypeProviderImpl implements TypeProvider {
      *             if <code>typedef</code> equals null
      *
      */
-    private List<String> resolveRegExpressionsFromTypedef(ExtendedType typedef) {
+    private List<String> resolveRegExpressionsFromTypedef(final ExtendedType typedef) {
         final List<String> regExps = new ArrayList<String>();
         Preconditions.checkArgument(typedef != null, "typedef can't be null");
         final TypeDefinition<?> strTypeDef = baseTypeDefForExtendedType(typedef);
@@ -1086,7 +1166,7 @@ public final class TypeProviderImpl implements TypeProvider {
      *             <li>if <code>regularExpressions</code> equals null</li>
      *             </ul>
      */
-    private void addStringRegExAsConstant(GeneratedTOBuilder genTOBuilder, List<String> regularExpressions) {
+    private void addStringRegExAsConstant(final GeneratedTOBuilder genTOBuilder, final List<String> regularExpressions) {
         if (genTOBuilder == null) {
             throw new IllegalArgumentException("Generated transfer object builder can't be null");
         }
@@ -1109,12 +1189,14 @@ public final class TypeProviderImpl implements TypeProvider {
      * {@link TypeProviderImpl#genTypeDefsContextMap genTypeDefsContextMap} to
      * be possible set it as extended type for the returning generated TO.
      *
+     * @param typedef
+     *            Type Definition
      * @param innerExtendedType
      *            extended type which is part of some other extended type
      * @param basePackageName
      *            string with the package name of the module
-     * @param typedefName
-     *            string with the name for the generated TO
+     * @param moduleName
+     *            Module Name
      * @return generated TO which extends generated TO for
      *         <code>innerExtendedType</code>
      * @throws IllegalArgumentException
@@ -1125,14 +1207,19 @@ public final class TypeProviderImpl implements TypeProvider {
      *             </ul>
      */
     private GeneratedTransferObject provideGeneratedTOFromExtendedType(final TypeDefinition<?> typedef,
-            final ExtendedType innerExtendedType, final String basePackageName) {
+            final ExtendedType innerExtendedType, final String basePackageName, final String moduleName) {
         Preconditions.checkArgument(innerExtendedType != null, "Extended type cannot be NULL!");
         Preconditions.checkArgument(basePackageName != null, "String with base package name cannot be NULL!");
 
         final String typedefName = typedef.getQName().getLocalName();
         final String classTypedefName = BindingMapping.getClassName(typedefName);
         final String innerTypeDef = innerExtendedType.getQName().getLocalName();
-        final GeneratedTOBuilder genTOBuilder = new GeneratedTOBuilderImpl(basePackageName, classTypedefName);
+        final GeneratedTOBuilderImpl genTOBuilder = new GeneratedTOBuilderImpl(basePackageName, classTypedefName);
+
+        genTOBuilder.setDescription(typedef.getDescription());
+        genTOBuilder.setReference(typedef.getReference());
+        genTOBuilder.setSchemaPath(typedef.getPath().getPathFromRoot());
+        genTOBuilder.setModuleName(moduleName);
         genTOBuilder.setTypedef(true);
         Restrictions r = BindingGeneratorUtil.getRestrictions(typedef);
         genTOBuilder.setRestrictions(r);
@@ -1156,10 +1243,25 @@ public final class TypeProviderImpl implements TypeProvider {
             }
         }
         addUnitsToGenTO(genTOBuilder, typedef.getUnits());
+        makeSerializable(genTOBuilder);
 
         return genTOBuilder.toInstance();
     }
 
+    /**
+     * Add {@link Serializable} to implemented interfaces of this TO. Also
+     * compute and add serialVersionUID property.
+     *
+     * @param gto
+     *            transfer object which needs to be serializable
+     */
+    private void makeSerializable(final GeneratedTOBuilderImpl gto) {
+        gto.addImplementsType(Types.typeForClass(Serializable.class));
+        GeneratedPropertyBuilder prop = new GeneratedPropertyBuilderImpl("serialVersionUID");
+        prop.setValue(Long.toString(BindingGeneratorUtil.computeDefaultSUID(gto)));
+        gto.setSUID(prop);
+    }
+
     /**
      * Finds out for each type definition how many immersion (depth) is
      * necessary to get to the base type. Every type definition is inserted to
@@ -1188,10 +1290,10 @@ public final class TypeProviderImpl implements TypeProvider {
             }
             typeDefinitionsConcreteDepth.add(unsortedTypeDefinition);
         }
-        // keys are in ascending order
-        Set<Integer> depths = typeDefinitionsDepths.keySet();
-        for (Integer depth : depths) {
-            sortedTypeDefinition.addAll(typeDefinitionsDepths.get(depth));
+
+        // SortedMap guarantees order corresponding to keys in ascending order
+        for (List<TypeDefinition<?>> v : typeDefinitionsDepths.values()) {
+            sortedTypeDefinition.addAll(v);
         }
 
         return sortedTypeDefinition;
@@ -1239,9 +1341,8 @@ public final class TypeProviderImpl implements TypeProvider {
      *            string with name of augmented node
      * @return string with the number suffix incremented by one (or 1 is added)
      */
-    private String provideAvailableNameForGenTOBuilder(String name) {
-        Pattern searchedPattern = Pattern.compile("[0-9]+\\z");
-        Matcher mtch = searchedPattern.matcher(name);
+    private String provideAvailableNameForGenTOBuilder(final String name) {
+        Matcher mtch = NUMBERS_PATTERN.matcher(name);
         if (mtch.find()) {
             final int newSuffix = Integer.valueOf(name.substring(mtch.start())) + 1;
             return name.substring(0, mtch.start()) + newSuffix;
@@ -1250,7 +1351,7 @@ public final class TypeProviderImpl implements TypeProvider {
         }
     }
 
-    public void addUnitsToGenTO(GeneratedTOBuilder to, String units) {
+    public void addUnitsToGenTO(final GeneratedTOBuilder to, final String units) {
         if (units != null && !units.isEmpty()) {
             to.addConstant(Types.STRING, "_UNITS", "\"" + units + "\"");
             GeneratedPropertyBuilder prop = new GeneratedPropertyBuilderImpl("UNITS");
@@ -1260,11 +1361,11 @@ public final class TypeProviderImpl implements TypeProvider {
     }
 
     @Override
-    public String getTypeDefaultConstruction(LeafSchemaNode node) {
+    public String getTypeDefaultConstruction(final LeafSchemaNode node) {
         return getTypeDefaultConstruction(node, node.getDefault());
     }
 
-    public String getTypeDefaultConstruction(LeafSchemaNode node, String defaultValue) {
+    public String getTypeDefaultConstruction(final LeafSchemaNode node, final String defaultValue) {
         TypeDefinition<?> type = node.getType();
         QName typeQName = type.getQName();
         TypeDefinition<?> base = baseTypeDefForExtendedType(type);
@@ -1279,16 +1380,17 @@ public final class TypeProviderImpl implements TypeProvider {
         } else if (base instanceof BitsTypeDefinition) {
             String parentName;
             String className;
-            SchemaPath nodePath = node.getPath();
             Module parent = getParentModule(node);
-            if (nodePath.getPath().size() == 1) {
-                parentName = BindingMapping.getClassName((parent).getName()) + "Data";
-                String basePackageName = BindingGeneratorUtil.moduleNamespaceToPackageName(parent);
+            Iterator<QName> path = node.getPath().getPathFromRoot().iterator();
+            path.next();
+            if (!(path.hasNext())) {
+                parentName = BindingMapping.getClassName(parent.getName()) + "Data";
+                String basePackageName = BindingMapping.getRootPackageName(parent.getQNameModule());
                 className = basePackageName + "." + parentName + "." + BindingMapping.getClassName(node.getQName());
             } else {
-                String basePackageName = BindingGeneratorUtil.moduleNamespaceToPackageName(parent);
+                String basePackageName = BindingMapping.getRootPackageName(parent.getQNameModule());
                 String packageName = packageNameForGeneratedType(basePackageName, type.getPath());
-                parentName = BindingMapping.getClassName(((SchemaNode) parent).getQName());
+                parentName = BindingMapping.getClassName(parent.getName());
                 className = packageName + "." + parentName + "." + BindingMapping.getClassName(node.getQName());
             }
             result = bitsToDef((BitsTypeDefinition) base, className, defaultValue, type instanceof ExtendedType);
@@ -1306,12 +1408,12 @@ public final class TypeProviderImpl implements TypeProvider {
             String className;
             if (type instanceof ExtendedType) {
                 Module m = getParentModule(type);
-                String basePackageName = BindingGeneratorUtil.moduleNamespaceToPackageName(m);
+                String basePackageName = BindingMapping.getRootPackageName(m.getQNameModule());
                 String packageName = packageNameForGeneratedType(basePackageName, type.getPath());
                 className = packageName + "." + BindingMapping.getClassName(typeQName);
             } else {
                 Module parentModule = getParentModule(node);
-                String basePackageName = BindingGeneratorUtil.moduleNamespaceToPackageName(parentModule);
+                String basePackageName = BindingMapping.getRootPackageName(parentModule.getQNameModule());
                 String packageName = packageNameForGeneratedType(basePackageName, node.getPath());
                 className = packageName + "." + BindingMapping.getClassName(node.getQName());
             }
@@ -1329,7 +1431,7 @@ public final class TypeProviderImpl implements TypeProvider {
         } else if (base instanceof Int64) {
             result = typeToDef(Long.class, defaultValue);
         } else if (base instanceof LeafrefTypeDefinition) {
-            result = leafrefToDef(node, (LeafrefTypeDefinition) base);
+            result = leafrefToDef(node, (LeafrefTypeDefinition) base, defaultValue);
         } else if (base instanceof StringTypeDefinition) {
             result = "\"" + defaultValue + "\"";
         } else if (base instanceof Uint8) {
@@ -1350,21 +1452,21 @@ public final class TypeProviderImpl implements TypeProvider {
         if (type instanceof ExtendedType && !(base instanceof LeafrefTypeDefinition)
                 && !(base instanceof EnumerationType) && !(base instanceof UnionTypeDefinition)) {
             Module m = getParentModule(type);
-            String basePackageName = BindingGeneratorUtil.moduleNamespaceToPackageName(m);
+            String basePackageName = BindingMapping.getRootPackageName(m.getQNameModule());
             String packageName = packageNameForGeneratedType(basePackageName, type.getPath());
             String className = packageName + "." + BindingMapping.getClassName(typeQName);
             sb.insert(0, "new " + className + "(");
-            sb.insert(sb.length(), ")");
+            sb.insert(sb.length(), ')');
         }
 
         return sb.toString();
     }
 
-    private String typeToDef(Class<?> clazz, String defaultValue) {
+    private String typeToDef(final Class<?> clazz, final String defaultValue) {
         return "new " + clazz.getName() + "(\"" + defaultValue + "\")";
     }
 
-    private String binaryToDef(String defaultValue) {
+    private String binaryToDef(final String defaultValue) {
         StringBuilder sb = new StringBuilder();
         BaseEncoding en = BaseEncoding.base64();
         byte[] encoded = en.decode(defaultValue);
@@ -1375,20 +1477,25 @@ public final class TypeProviderImpl implements TypeProvider {
                 sb.append(", ");
             }
         }
-        sb.append("}");
+        sb.append('}');
         return sb.toString();
     }
 
-    private String bitsToDef(BitsTypeDefinition type, String className, String defaultValue, boolean isExt) {
+    private String bitsToDef(final BitsTypeDefinition type, final String className, final String defaultValue,
+            final boolean isExt) {
         List<Bit> bits = new ArrayList<>(type.getBits());
         Collections.sort(bits, new Comparator<Bit>() {
             @Override
-            public int compare(Bit o1, Bit o2) {
+            public int compare(final Bit o1, final Bit o2) {
                 return o1.getName().compareTo(o2.getName());
             }
         });
         StringBuilder sb = new StringBuilder();
-        sb.append(isExt ? "" : "new " + className + "(");
+        if (!isExt) {
+            sb.append("new ");
+            sb.append(className);
+            sb.append('(');
+        }
         for (int i = 0; i < bits.size(); i++) {
             if (bits.get(i).getName().equals(defaultValue)) {
                 sb.append(true);
@@ -1399,18 +1506,20 @@ public final class TypeProviderImpl implements TypeProvider {
                 sb.append(", ");
             }
         }
-        sb.append(isExt ? "" : ")");
+        if (!isExt) {
+            sb.append(')');
+        }
         return sb.toString();
     }
 
-    private Module getParentModule(SchemaNode node) {
-        QName qname = node.getPath().getPath().get(0);
+    private Module getParentModule(final SchemaNode node) {
+        QName qname = node.getPath().getPathFromRoot().iterator().next();
         URI namespace = qname.getNamespace();
         Date revision = qname.getRevision();
         return schemaContext.findModuleByNamespaceAndRevision(namespace, revision);
     }
 
-    private String leafrefToDef(LeafSchemaNode parentNode, LeafrefTypeDefinition leafrefType) {
+    private String leafrefToDef(final LeafSchemaNode parentNode, final LeafrefTypeDefinition leafrefType, final String defaultValue) {
         Preconditions.checkArgument(leafrefType != null, "Leafref Type Definition reference cannot be NULL!");
         Preconditions.checkArgument(leafrefType.getPathStatement() != null,
                 "The Path Statement for Leafref Type Definition cannot be NULL!");
@@ -1419,9 +1528,7 @@ public final class TypeProviderImpl implements TypeProvider {
         final String strXPath = xpath.toString();
 
         if (strXPath != null) {
-            if (strXPath.contains("[")) {
-                return "new java.lang.Object()";
-            } else {
+            if (strXPath.indexOf('[') == -1) {
                 final Module module = findParentModule(schemaContext, parentNode);
                 if (module != null) {
                     final SchemaNode dataNode;
@@ -1430,16 +1537,18 @@ public final class TypeProviderImpl implements TypeProvider {
                     } else {
                         dataNode = findDataSchemaNodeForRelativeXPath(schemaContext, module, parentNode, xpath);
                     }
-                    String result = getTypeDefaultConstruction((LeafSchemaNode) dataNode, parentNode.getDefault());
+                    String result = getTypeDefaultConstruction((LeafSchemaNode) dataNode, defaultValue);
                     return result;
                 }
+            } else {
+                return "new java.lang.Object()";
             }
         }
 
         return null;
     }
 
-    private String unionToDef(LeafSchemaNode node) {
+    private String unionToDef(final LeafSchemaNode node) {
         String parentName;
         String className;
 
@@ -1459,7 +1568,7 @@ public final class TypeProviderImpl implements TypeProvider {
                     List<Module> modulesList = new ArrayList<>(modules);
                     Collections.sort(modulesList, new Comparator<Module>() {
                         @Override
-                        public int compare(Module o1, Module o2) {
+                        public int compare(final Module o1, final Module o2) {
                             return o1.getRevision().compareTo(o2.getRevision());
                         }
                     });
@@ -1469,24 +1578,23 @@ public final class TypeProviderImpl implements TypeProvider {
                 module = modules.iterator().next();
             }
 
-            String basePackageName = BindingGeneratorUtil.moduleNamespaceToPackageName(module);
+            String basePackageName = BindingMapping.getRootPackageName(module.getQNameModule());
             className = basePackageName + "." + BindingMapping.getClassName(typeQName);
         } else {
-            SchemaPath nodePath = node.getPath();
-            if (nodePath.getPath().size() == 1) {
-                QName first = nodePath.getPath().get(0);
+            Iterator<QName> path = node.getPath().getPathFromRoot().iterator();
+            QName first = path.next();
+            if (!(path.hasNext())) {
                 URI namespace = first.getNamespace();
                 Date revision = first.getRevision();
                 Module parent = schemaContext.findModuleByNamespaceAndRevision(namespace, revision);
                 parentName = BindingMapping.getClassName((parent).getName()) + "Data";
-                String basePackageName = BindingGeneratorUtil.moduleNamespaceToPackageName(parent);
+                String basePackageName = BindingMapping.getRootPackageName(parent.getQNameModule());
                 className = basePackageName + "." + parentName + "." + BindingMapping.getClassName(node.getQName());
             } else {
-                QName first = node.getPath().getPath().get(0);
                 URI namespace = first.getNamespace();
                 Date revision = first.getRevision();
                 Module parentModule = schemaContext.findModuleByNamespaceAndRevision(namespace, revision);
-                String basePackageName = BindingGeneratorUtil.moduleNamespaceToPackageName(parentModule);
+                String basePackageName = BindingMapping.getRootPackageName(parentModule.getQNameModule());
                 String packageName = packageNameForGeneratedType(basePackageName, node.getType().getPath());
                 className = packageName + "." + BindingMapping.getClassName(node.getQName());
             }
@@ -1494,19 +1602,18 @@ public final class TypeProviderImpl implements TypeProvider {
         return union(className, node.getDefault(), node);
     }
 
-    private String union(String className, String defaultValue, LeafSchemaNode node) {
+    private String union(final String className, final String defaultValue, final LeafSchemaNode node) {
         StringBuilder sb = new StringBuilder();
-        sb.append("new " + className + "(");
-        sb.append("\"");
+        sb.append("new ");
+        sb.append(className);
+        sb.append("(\"");
         sb.append(defaultValue);
-        sb.append("\"");
-        sb.append(".toCharArray()");
-        sb.append(")");
+        sb.append("\".toCharArray())");
         return sb.toString();
     }
 
     @Override
-    public String getConstructorPropertyName(SchemaNode node) {
+    public String getConstructorPropertyName(final SchemaNode node) {
         if (node instanceof TypeDefinition<?>) {
             return "value";
         } else {
@@ -1515,8 +1622,8 @@ public final class TypeProviderImpl implements TypeProvider {
     }
 
     @Override
-    public String getParamNameFromType(TypeDefinition<?> type) {
-        return BindingGeneratorUtil.parseToValidParamName(type.getQName().getLocalName());
+    public String getParamNameFromType(final TypeDefinition<?> type) {
+        return BindingMapping.getPropertyName(type.getQName().getLocalName());
     }
 
 }