Merge "Add IfNewHostNotify to DeviceManager"
[controller.git] / opendaylight / sal / yang-prototype / code-generator / binding-generator-impl / src / main / java / org / opendaylight / controller / sal / binding / generator / impl / BindingGeneratorImpl.java
index 3a9398a13a1ff0dc01ca1d419de48d93ed65bd49..b89dbb44ac786756b60d866c02459097bbe615b4 100644 (file)
-/*\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
- */\r
-package org.opendaylight.controller.sal.binding.generator.impl;\r
-\r
-import java.net.URI;\r
-import java.util.ArrayList;\r
-import java.util.Calendar;\r
-import java.util.GregorianCalendar;\r
-import java.util.HashMap;\r
-import java.util.List;\r
-import java.util.Map;\r
-import java.util.Set;\r
-\r
-import org.opendaylight.controller.binding.generator.util.CodeGeneratorHelper;\r
-import org.opendaylight.controller.binding.generator.util.Types;\r
-import org.opendaylight.controller.sal.binding.generator.api.BindingGenerator;\r
-import org.opendaylight.controller.sal.binding.generator.spi.TypeProvider;\r
-import org.opendaylight.controller.sal.binding.model.api.GeneratedTransferObject;\r
-import org.opendaylight.controller.sal.binding.model.api.GeneratedType;\r
-import org.opendaylight.controller.sal.binding.model.api.Type;\r
-import org.opendaylight.controller.sal.binding.model.api.type.builder.GeneratedPropertyBuilder;\r
-import org.opendaylight.controller.sal.binding.model.api.type.builder.GeneratedTOBuilder;\r
-import org.opendaylight.controller.sal.binding.model.api.type.builder.GeneratedTypeBuilder;\r
-import org.opendaylight.controller.sal.binding.model.api.type.builder.MethodSignatureBuilder;\r
-import org.opendaylight.controller.sal.binding.yang.types.TypeProviderImpl;\r
-import org.opendaylight.controller.yang.common.QName;\r
-import org.opendaylight.controller.yang.model.api.ContainerSchemaNode;\r
-import org.opendaylight.controller.yang.model.api.DataNodeContainer;\r
-import org.opendaylight.controller.yang.model.api.DataSchemaNode;\r
-import org.opendaylight.controller.yang.model.api.LeafListSchemaNode;\r
-import org.opendaylight.controller.yang.model.api.LeafSchemaNode;\r
-import org.opendaylight.controller.yang.model.api.ListSchemaNode;\r
-import org.opendaylight.controller.yang.model.api.Module;\r
-import org.opendaylight.controller.yang.model.api.SchemaContext;\r
-import org.opendaylight.controller.yang.model.api.SchemaPath;\r
-import org.opendaylight.controller.yang.model.api.TypeDefinition;\r
-\r
-public class BindingGeneratorImpl implements BindingGenerator {\r
-\r
-    private static Calendar calendar = new GregorianCalendar();\r
-    private Map<String, Map<String, GeneratedTypeBuilder>> genTypeBuilders;\r
-    private List<ContainerSchemaNode> schemaContainers;\r
-    private List<ListSchemaNode> schemaLists;\r
-    private TypeProvider typeProvider;\r
-    private String basePackageName;\r
-\r
-    public BindingGeneratorImpl() {\r
-        super();\r
-    }\r
-\r
-    @Override\r
-    public List<Type> generateTypes(final SchemaContext context) {\r
-        final List<Type> genTypes = new ArrayList<Type>();\r
-        \r
-        typeProvider = new TypeProviderImpl(context);\r
-        if (context != null) {\r
-            final Set<Module> modules = context.getModules();\r
-            \r
-            if (modules != null) {\r
-                for (final Module module : modules) {\r
-                    genTypeBuilders = new HashMap<String, Map<String, GeneratedTypeBuilder>>();\r
-                    schemaContainers = new ArrayList<ContainerSchemaNode>();\r
-                    schemaLists = new ArrayList<ListSchemaNode>();\r
-                    \r
-                    basePackageName = resolveBasePackageName(module.getNamespace(),\r
-                            module.getYangVersion());\r
-\r
-                    traverseModule(module);\r
-                    if (schemaContainers.size() > 0) {\r
-                        for (final ContainerSchemaNode container : schemaContainers) {\r
-                            genTypes.add(containerToGenType(container));\r
-                        }\r
-                    }\r
-\r
-                    if (schemaLists.size() > 0) {\r
-                        for (final ListSchemaNode list : schemaLists) {\r
-                            genTypes.addAll(listToGenType(list));\r
-                        }\r
-                    }\r
-                }\r
-            }\r
-        }\r
-\r
-        return genTypes;\r
-    }\r
-    \r
-    private String resolveGeneratedTypePackageName(final SchemaPath schemaPath) {\r
-        final StringBuilder builder = new StringBuilder();\r
-        builder.append(basePackageName);\r
-        if ((schemaPath != null) && (schemaPath.getPath() != null)) {\r
-            final List<QName> pathToNode = schemaPath.getPath();\r
-            final int traversalSteps = (pathToNode.size() - 1); \r
-            for (int i = 0; i < traversalSteps; ++i) {\r
-                builder.append(".");\r
-                String nodeLocalName = pathToNode.get(i).getLocalName();\r
-\r
-                // TODO: create method\r
-                nodeLocalName = nodeLocalName.replace(":", ".");\r
-                nodeLocalName = nodeLocalName.replace("-", ".");\r
-                builder.append(nodeLocalName);\r
-            }\r
-            return builder.toString();\r
-        }\r
-        return null;\r
-    }\r
-\r
-    private GeneratedType containerToGenType(ContainerSchemaNode container) {\r
-        if (container == null) {\r
-            return null;\r
-        }\r
-        final Set<DataSchemaNode> schemaNodes = container.getChildNodes();\r
-        final GeneratedTypeBuilder typeBuilder = addRawInterfaceDefinition(container);\r
-\r
-        for (final DataSchemaNode node : schemaNodes) {\r
-            if (node instanceof LeafSchemaNode) {\r
-                resolveLeafSchemaNodeAsMethod(typeBuilder,\r
-                        (LeafSchemaNode) node);\r
-            } else if (node instanceof LeafListSchemaNode) {\r
-                resolveLeafListSchemaNode(typeBuilder,\r
-                        (LeafListSchemaNode) node);\r
-\r
-            } else if (node instanceof ContainerSchemaNode) {\r
-                resolveContainerSchemaNode(typeBuilder,\r
-                        (ContainerSchemaNode) node);\r
-            } else if (node instanceof ListSchemaNode) {\r
-                resolveListSchemaNode(typeBuilder, (ListSchemaNode) node);\r
-            }\r
-        }\r
-        return typeBuilder.toInstance();\r
-    }\r
-\r
-    private boolean resolveLeafSchemaNodeAsMethod(\r
-            final GeneratedTypeBuilder typeBuilder, final LeafSchemaNode leaf) {\r
-        if ((leaf != null) && (typeBuilder != null)) {\r
-            final String leafName = leaf.getQName().getLocalName();\r
-            String leafDesc = leaf.getDescription();\r
-            if (leafDesc == null) {\r
-                leafDesc = "";\r
-            }\r
-\r
-            if (leafName != null) {\r
-                final TypeDefinition<?> typeDef = leaf.getType();\r
-                final Type javaType = typeProvider\r
-                        .javaTypeForSchemaDefinitionType(typeDef);\r
-\r
-                constructGetter(typeBuilder, leafName, leafDesc, javaType);\r
-                if (!leaf.isConfiguration()) {\r
-                    constructSetter(typeBuilder, leafName, leafDesc, javaType);\r
-                }\r
-                return true;\r
-            }\r
-        }\r
-        return false;\r
-    }\r
-\r
-    private boolean resolveLeafSchemaNodeAsProperty(\r
-            final GeneratedTOBuilder toBuilder, final LeafSchemaNode leaf,\r
-            boolean isReadOnly) {\r
-        if ((leaf != null) && (toBuilder != null)) {\r
-            final String leafName = leaf.getQName().getLocalName();\r
-            String leafDesc = leaf.getDescription();\r
-            if (leafDesc == null) {\r
-                leafDesc = "";\r
-            }\r
-\r
-            if (leafName != null) {\r
-                final TypeDefinition<?> typeDef = leaf.getType();\r
-                \r
-                //TODO: properly resolve enum types\r
-                final Type javaType = typeProvider\r
-                        .javaTypeForSchemaDefinitionType(typeDef);\r
-\r
-                final GeneratedPropertyBuilder propBuilder = toBuilder\r
-                        .addProperty(CodeGeneratorHelper\r
-                                .parseToClassName(leafName));\r
-\r
-                propBuilder.setReadOnly(isReadOnly);\r
-                propBuilder.addReturnType(javaType);\r
-                propBuilder.addComment(leafDesc);\r
-\r
-                toBuilder.addEqualsIdentity(propBuilder);\r
-                toBuilder.addHashIdentity(propBuilder);\r
-                toBuilder.addToStringProperty(propBuilder);\r
-\r
-                return true;\r
-            }\r
-        }\r
-        return false;\r
-    }\r
-\r
-    private boolean resolveLeafListSchemaNode(\r
-            final GeneratedTypeBuilder typeBuilder,\r
-            final LeafListSchemaNode node) {\r
-        if ((node != null) && (typeBuilder != null)) {\r
-            final String nodeName = node.getQName().getLocalName();\r
-            String nodeDesc = node.getDescription();\r
-            if (nodeDesc == null) {\r
-                nodeDesc = "";\r
-            }\r
-\r
-            if (nodeName != null) {\r
-                final TypeDefinition<?> type = node.getType();\r
-                final Type listType = Types.listTypeFor(typeProvider\r
-                        .javaTypeForSchemaDefinitionType(type));\r
-\r
-                constructGetter(typeBuilder, nodeName, nodeDesc, listType);\r
-                if (!node.isConfiguration()) {\r
-                    constructSetter(typeBuilder, nodeName, nodeDesc, listType);\r
-                }\r
-                return true;\r
-            }\r
-        }\r
-        return false;\r
-    }\r
-\r
-    private boolean resolveContainerSchemaNode(\r
-            final GeneratedTypeBuilder typeBuilder,\r
-            final ContainerSchemaNode node) {\r
-        if ((node != null) && (typeBuilder != null)) {\r
-            final String nodeName = node.getQName().getLocalName();\r
-\r
-            if (nodeName != null) {\r
-                final GeneratedTypeBuilder rawGenType = addRawInterfaceDefinition(node);\r
-                constructGetter(typeBuilder, nodeName, "", rawGenType);\r
-\r
-                return true;\r
-            }\r
-        }\r
-        return false;\r
-    }\r
-\r
-    private boolean resolveListSchemaNode(\r
-            final GeneratedTypeBuilder typeBuilder, final ListSchemaNode node) {\r
-        if ((node != null) && (typeBuilder != null)) {\r
-            final String nodeName = node.getQName().getLocalName();\r
-\r
-            if (nodeName != null) {\r
-                final GeneratedTypeBuilder rawGenType = addRawInterfaceDefinition(node);\r
-                constructGetter(typeBuilder, nodeName, "",\r
-                        Types.listTypeFor(rawGenType));\r
-                if (!node.isConfiguration()) {\r
-                    constructSetter(typeBuilder, nodeName, "",\r
-                            Types.listTypeFor(rawGenType));\r
-                }\r
-                return true;\r
-            }\r
-        }\r
-        return false;\r
-    }\r
-\r
-    private GeneratedTypeBuilder addRawInterfaceDefinition(\r
-            final DataSchemaNode schemaNode) {\r
-        if (schemaNode == null) {\r
-            return null;\r
-        }\r
-\r
-        final String packageName = resolveGeneratedTypePackageName(schemaNode\r
-                .getPath());\r
-        final String schemaNodeName = schemaNode.getQName().getLocalName();\r
-\r
-        if ((packageName != null) && (schemaNode != null)\r
-                && (schemaNodeName != null)) {\r
-            final String genTypeName = CodeGeneratorHelper\r
-                    .parseToClassName(schemaNodeName);\r
-            final GeneratedTypeBuilder newType = new GeneratedTypeBuilderImpl(\r
-                    packageName, genTypeName);\r
-\r
-            if (!genTypeBuilders.containsKey(packageName)) {\r
-                final Map<String, GeneratedTypeBuilder> builders = new HashMap<String, GeneratedTypeBuilder>();\r
-                builders.put(genTypeName, newType);\r
-                genTypeBuilders.put(packageName, builders);\r
-            } else {\r
-                final Map<String, GeneratedTypeBuilder> builders = genTypeBuilders\r
-                        .get(packageName);\r
-                if (!builders.containsKey(genTypeName)) {\r
-                    builders.put(genTypeName, newType);\r
-                }\r
-            }\r
-            return newType;\r
-        }\r
-        return null;\r
-    }\r
-\r
-    private String getterMethodName(final String methodName) {\r
-        final StringBuilder method = new StringBuilder();\r
-        method.append("get");\r
-        method.append(CodeGeneratorHelper.parseToClassName(methodName));\r
-        return method.toString();\r
-    }\r
-\r
-    private String setterMethodName(final String methodName) {\r
-        final StringBuilder method = new StringBuilder();\r
-        method.append("set");\r
-        method.append(CodeGeneratorHelper.parseToClassName(methodName));\r
-        return method.toString();\r
-    }\r
-\r
-    private MethodSignatureBuilder constructGetter(\r
-            final GeneratedTypeBuilder interfaceBuilder,\r
-            final String schemaNodeName, final String comment,\r
-            final Type returnType) {\r
-        final MethodSignatureBuilder getMethod = interfaceBuilder\r
-                .addMethod(getterMethodName(schemaNodeName));\r
-\r
-        getMethod.addComment(comment);\r
-        getMethod.addReturnType(returnType);\r
-\r
-        return getMethod;\r
-    }\r
-\r
-    private MethodSignatureBuilder constructSetter(\r
-            final GeneratedTypeBuilder interfaceBuilder,\r
-            final String schemaNodeName, final String comment,\r
-            final Type parameterType) {\r
-        final MethodSignatureBuilder setMethod = interfaceBuilder\r
-                .addMethod(setterMethodName(schemaNodeName));\r
-\r
-        setMethod.addComment(comment);\r
-        setMethod.addParameter(parameterType,\r
-                CodeGeneratorHelper.parseToParamName(schemaNodeName));\r
-        setMethod.addReturnType(Types.voidType());\r
-\r
-        return setMethod;\r
-    }\r
-\r
-    private String resolveBasePackageName(final URI moduleNamespace,\r
-            final String yangVersion) {\r
-        final StringBuilder packageNameBuilder = new StringBuilder();\r
-\r
-        packageNameBuilder.append("org.opendaylight.yang.gen.v");\r
-        packageNameBuilder.append(yangVersion);\r
-        packageNameBuilder.append(".rev");\r
-        packageNameBuilder.append(calendar.get(Calendar.YEAR));\r
-        packageNameBuilder.append((calendar.get(Calendar.MONTH) + 1));\r
-        packageNameBuilder.append(calendar.get(Calendar.DAY_OF_MONTH));\r
-        packageNameBuilder.append(".");\r
-\r
-        String namespace = moduleNamespace.toString();\r
-        namespace = namespace.replace(":", ".");\r
-        namespace = namespace.replace("-", ".");\r
-\r
-        packageNameBuilder.append(namespace);\r
-\r
-        return packageNameBuilder.toString();\r
-    }\r
-\r
-    private List<Type> listToGenType(final ListSchemaNode list) {\r
-        if (list == null) {\r
-            return null;\r
-        }\r
-        final GeneratedTypeBuilder typeBuilder = resolveListTypeBuilder(list);\r
-        final List<String> listKeys = listKeys(list);\r
-        GeneratedTOBuilder genTOBuilder = null;\r
-        if (listKeys.size() > 0) {\r
-            genTOBuilder = resolveListKey(list);\r
-        }\r
-\r
-        final Set<DataSchemaNode> schemaNodes = list.getChildNodes();\r
-        for (final DataSchemaNode node : schemaNodes) {\r
-\r
-            if (node instanceof LeafSchemaNode) {\r
-                final LeafSchemaNode leaf = (LeafSchemaNode) node;\r
-                if (!isPartOfListKey(leaf, listKeys)) {\r
-                    resolveLeafSchemaNodeAsMethod(typeBuilder, leaf);\r
-                } else {\r
-                    resolveLeafSchemaNodeAsProperty(genTOBuilder, leaf, true);\r
-                }\r
-            } else if (node instanceof LeafListSchemaNode) {\r
-                resolveLeafListSchemaNode(typeBuilder,\r
-                        (LeafListSchemaNode) node);\r
-            } else if (node instanceof ContainerSchemaNode) {\r
-                resolveContainerSchemaNode(typeBuilder,\r
-                        (ContainerSchemaNode) node);\r
-            } else if (node instanceof ListSchemaNode) {\r
-                resolveListSchemaNode(typeBuilder, (ListSchemaNode) node);\r
-            }\r
-        }\r
-\r
-        final List<Type> genTypes = new ArrayList<Type>();\r
-        if (genTOBuilder != null) {\r
-            final GeneratedTransferObject genTO = genTOBuilder.toInstance();\r
-            constructGetter(typeBuilder, genTO.getName(), "Returns Primary Key of Yang List Type", genTO);\r
-            genTypes.add(genTO);\r
-        }\r
-        genTypes.add(typeBuilder.toInstance());\r
-        return genTypes;\r
-    }\r
-\r
-    /**\r
-     * @param list\r
-     * @return\r
-     */\r
-    private GeneratedTOBuilder resolveListKey(final ListSchemaNode list) {\r
-        final String packageName = resolveGeneratedTypePackageName(list\r
-                .getPath());\r
-        final String listName = list.getQName().getLocalName() + "Key";\r
-\r
-        if ((packageName != null) && (list != null) && (listName != null)) {\r
-            final String genTOName = CodeGeneratorHelper\r
-                    .parseToClassName(listName);\r
-            final GeneratedTOBuilder newType = new GeneratedTOBuilderImpl(\r
-                    packageName, genTOName);\r
-\r
-            return newType;\r
-        }\r
-        return null;\r
-    }\r
-\r
-    private boolean isPartOfListKey(final LeafSchemaNode leaf,\r
-            final List<String> keys) {\r
-        if ((leaf != null) && (keys != null) && (leaf.getQName() != null)) {\r
-            final String leafName = leaf.getQName().getLocalName();\r
-            if (keys.contains(leafName)) {\r
-                return true;\r
-            }\r
-        }\r
-        return false;\r
-    }\r
-\r
-    private List<String> listKeys(final ListSchemaNode list) {\r
-        final List<String> listKeys = new ArrayList<String>();\r
-\r
-        if (list.getKeyDefinition() != null) {\r
-            final List<QName> keyDefinitions = list.getKeyDefinition();\r
-            \r
-            for (final QName keyDefinition : keyDefinitions) {\r
-                listKeys.add(keyDefinition.getLocalName());\r
-            }\r
-        }\r
-        return listKeys;\r
-    }\r
-\r
-    private GeneratedTypeBuilder resolveListTypeBuilder(\r
-            final ListSchemaNode list) {\r
-        final String packageName = resolveGeneratedTypePackageName(list\r
-                .getPath());\r
-        final String schemaNodeName = list.getQName().getLocalName();\r
-        final String genTypeName = CodeGeneratorHelper\r
-                .parseToClassName(schemaNodeName);\r
-\r
-        GeneratedTypeBuilder typeBuilder = null;\r
-        if (genTypeBuilders.containsKey(packageName)) {\r
-            final Map<String, GeneratedTypeBuilder> builders = new HashMap<String, GeneratedTypeBuilder>();\r
-            typeBuilder = builders.get(genTypeName);\r
-\r
-            if (null == typeBuilder) {\r
-                typeBuilder = addRawInterfaceDefinition(list);\r
-            }\r
-        }\r
-        return typeBuilder;\r
-    }\r
-\r
-    private void traverseModule(final Module module) {\r
-        final Set<DataSchemaNode> schemaNodes = module.getChildNodes();\r
-\r
-        for (DataSchemaNode node : schemaNodes) {\r
-            if (node instanceof ContainerSchemaNode) {\r
-                schemaContainers.add((ContainerSchemaNode) node);\r
-                traverse((ContainerSchemaNode) node);\r
-            }\r
-        }\r
-    }\r
-\r
-    private void traverse(final DataNodeContainer dataNode) {\r
-        if (!containChildDataNodeContainer(dataNode)) {\r
-            return;\r
-        }\r
-\r
-        final Set<DataSchemaNode> childs = dataNode.getChildNodes();\r
-        if (childs != null) {\r
-            for (DataSchemaNode childNode : childs) {\r
-                if (childNode instanceof ContainerSchemaNode) {\r
-                    final ContainerSchemaNode container = (ContainerSchemaNode) childNode;\r
-                    schemaContainers.add(container);\r
-                    traverse(container);\r
-                }\r
-\r
-                if (childNode instanceof ListSchemaNode) {\r
-                    final ListSchemaNode list = (ListSchemaNode) childNode;\r
-                    schemaLists.add(list);\r
-                    traverse(list);\r
-                }\r
-            }\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Returns <code>true</code> if and only if the child node contain at least\r
-     * one child container schema node or child list schema node, otherwise will\r
-     * always returns <code>false</code>\r
-     * \r
-     * @param container\r
-     * @return <code>true</code> if and only if the child node contain at least\r
-     *         one child container schema node or child list schema node,\r
-     *         otherwise will always returns <code>false</code>\r
-     */\r
-    private boolean containChildDataNodeContainer(\r
-            final DataNodeContainer container) {\r
-        if (container != null) {\r
-            final Set<DataSchemaNode> childs = container.getChildNodes();\r
-            if ((childs != null) && (childs.size() > 0)) {\r
-                for (final DataSchemaNode childNode : childs) {\r
-                    if (childNode instanceof DataNodeContainer) {\r
-                        return true;\r
-                    }\r
-                }\r
-            }\r
-        }\r
-        return false;\r
-    }\r
-}\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.controller.sal.binding.generator.impl;
+
+import org.opendaylight.controller.binding.generator.util.ReferencedTypeImpl;
+import org.opendaylight.controller.binding.generator.util.Types;
+import org.opendaylight.controller.binding.generator.util.generated.type.builder.GeneratedTOBuilderImpl;
+import org.opendaylight.controller.binding.generator.util.generated.type.builder.GeneratedTypeBuilderImpl;
+import org.opendaylight.controller.sal.binding.generator.api.BindingGenerator;
+import org.opendaylight.controller.sal.binding.generator.spi.TypeProvider;
+import org.opendaylight.controller.sal.binding.model.api.*;
+import org.opendaylight.controller.sal.binding.model.api.type.builder.*;
+import org.opendaylight.controller.sal.binding.yang.types.TypeProviderImpl;
+import org.opendaylight.controller.yang.binding.Notification;
+import org.opendaylight.controller.yang.common.QName;
+import org.opendaylight.controller.yang.common.RpcResult;
+import org.opendaylight.controller.yang.model.api.*;
+import org.opendaylight.controller.yang.model.api.type.EnumTypeDefinition;
+import org.opendaylight.controller.yang.model.api.type.EnumTypeDefinition.EnumPair;
+import org.opendaylight.controller.yang.model.util.DataNodeIterator;
+import org.opendaylight.controller.yang.model.util.ExtendedType;
+import org.opendaylight.controller.yang.model.util.SchemaContextUtil;
+
+import java.util.*;
+import java.util.concurrent.Future;
+
+import static org.opendaylight.controller.binding.generator.util.BindingGeneratorUtil.*;
+import static org.opendaylight.controller.yang.model.util.SchemaContextUtil.findDataSchemaNode;
+import static org.opendaylight.controller.yang.model.util.SchemaContextUtil.findParentModule;
+
+public final class BindingGeneratorImpl implements BindingGenerator {
+
+    private Map<String, Map<String, GeneratedTypeBuilder>> genTypeBuilders;
+    private TypeProvider typeProvider;
+    private SchemaContext schemaContext;
+
+    public BindingGeneratorImpl() {
+        super();
+    }
+
+    @Override
+    public List<Type> generateTypes(final SchemaContext context) {
+        if (context == null) {
+            throw new IllegalArgumentException("Schema Context reference "
+                    + "cannot be NULL!");
+        }
+        if (context.getModules() == null) {
+            throw new IllegalStateException("Schema Context does not contain "
+                    + "defined modules!");
+        }
+
+        final List<Type> generatedTypes = new ArrayList<>();
+        schemaContext = context;
+        typeProvider = new TypeProviderImpl(context);
+        final Set<Module> modules = context.getModules();
+        genTypeBuilders = new HashMap<>();
+        for (final Module module : modules) {
+            generatedTypes.add(moduleToDataType(module));
+            generatedTypes.addAll(allTypeDefinitionsToGenTypes(module));
+            generatedTypes.addAll(allContainersToGenTypes(module));
+            generatedTypes.addAll(allListsToGenTypes(module));
+            generatedTypes.addAll(allAugmentsToGenTypes(module));
+            generatedTypes.addAll(allRPCMethodsToGenType(module));
+            generatedTypes.addAll(allNotificationsToGenType(module));
+            generatedTypes.addAll(allIdentitiesToGenTypes(module, context));
+            generatedTypes.addAll(allGroupingsToGenTypes(module));
+        }
+        return generatedTypes;
+    }
+
+    @Override
+    public List<Type> generateTypes(final SchemaContext context,
+            final Set<Module> modules) {
+        if (context == null) {
+            throw new IllegalArgumentException("Schema Context reference "
+                    + "cannot be NULL!");
+        }
+        if (context.getModules() == null) {
+            throw new IllegalStateException("Schema Context does not contain "
+                    + "defined modules!");
+        }
+        if (modules == null) {
+            throw new IllegalArgumentException("Sef of Modules cannot be "
+                    + "NULL!");
+        }
+
+        final List<Type> filteredGenTypes = new ArrayList<>();
+        schemaContext = context;
+        typeProvider = new TypeProviderImpl(context);
+        final Set<Module> contextModules = context.getModules();
+        genTypeBuilders = new HashMap<>();
+        for (final Module contextModule : contextModules) {
+            final List<Type> generatedTypes = new ArrayList<>();
+
+            generatedTypes.add(moduleToDataType(contextModule));
+            generatedTypes.addAll(allTypeDefinitionsToGenTypes(contextModule));
+            generatedTypes.addAll(allContainersToGenTypes(contextModule));
+            generatedTypes.addAll(allListsToGenTypes(contextModule));
+            generatedTypes.addAll(allAugmentsToGenTypes(contextModule));
+            generatedTypes.addAll(allRPCMethodsToGenType(contextModule));
+            generatedTypes.addAll(allNotificationsToGenType(contextModule));
+            generatedTypes.addAll(allIdentitiesToGenTypes(contextModule,
+                    context));
+            generatedTypes.addAll(allGroupingsToGenTypes(contextModule));
+
+            if (modules.contains(contextModule)) {
+                filteredGenTypes.addAll(generatedTypes);
+            }
+        }
+        return filteredGenTypes;
+    }
+
+    private List<Type> allTypeDefinitionsToGenTypes(final Module module) {
+        if (module == null) {
+            throw new IllegalArgumentException(
+                    "Module reference cannot be NULL!");
+        }
+        if (module.getName() == null) {
+            throw new IllegalArgumentException("Module name cannot be NULL!");
+        }
+        if (module.getTypeDefinitions() == null) {
+            throw new IllegalArgumentException("Type Definitions for module "
+                    + module.getName() + " cannot be NULL!");
+        }
+
+        final Set<TypeDefinition<?>> typeDefinitions = module
+                .getTypeDefinitions();
+        final List<Type> generatedTypes = new ArrayList<>();
+        for (final TypeDefinition<?> typedef : typeDefinitions) {
+            if (typedef != null) {
+                final Type type = ((TypeProviderImpl) typeProvider)
+                        .generatedTypeForExtendedDefinitionType(typedef);
+                if ((type != null) && !generatedTypes.contains(type)) {
+                    generatedTypes.add(type);
+                }
+            }
+        }
+        return generatedTypes;
+    }
+
+    private List<Type> allContainersToGenTypes(final Module module) {
+        if (module == null) {
+            throw new IllegalArgumentException(
+                    "Module reference cannot be NULL!");
+        }
+
+        if (module.getName() == null) {
+            throw new IllegalArgumentException("Module name cannot be NULL!");
+        }
+
+        if (module.getChildNodes() == null) {
+            throw new IllegalArgumentException("Reference to Set of Child "
+                    + "Nodes in module " + module.getName() + " cannot be "
+                    + "NULL!");
+        }
+
+        final List<Type> generatedTypes = new ArrayList<>();
+        final DataNodeIterator it = new DataNodeIterator(module);
+        final List<ContainerSchemaNode> schemaContainers = it.allContainers();
+        final String basePackageName = moduleNamespaceToPackageName(module);
+        for (final ContainerSchemaNode container : schemaContainers) {
+            generatedTypes.add(containerToGenType(basePackageName, container));
+        }
+        return generatedTypes;
+    }
+
+    private List<Type> allListsToGenTypes(final Module module) {
+        if (module == null) {
+            throw new IllegalArgumentException(
+                    "Module reference cannot be NULL!");
+        }
+
+        if (module.getName() == null) {
+            throw new IllegalArgumentException("Module name cannot be NULL!");
+        }
+
+        if (module.getChildNodes() == null) {
+            throw new IllegalArgumentException("Reference to Set of Child "
+                    + "Nodes in module " + module.getName() + " cannot be "
+                    + "NULL!");
+        }
+
+        final List<Type> generatedTypes = new ArrayList<>();
+        final DataNodeIterator it = new DataNodeIterator(module);
+        final List<ListSchemaNode> schemaLists = it.allLists();
+        final String basePackageName = moduleNamespaceToPackageName(module);
+        if (schemaLists != null) {
+            for (final ListSchemaNode list : schemaLists) {
+                generatedTypes.addAll(listToGenType(basePackageName, list));
+            }
+        }
+        return generatedTypes;
+    }
+
+    private List<Type> allAugmentsToGenTypes(final Module module) {
+        if (module == null) {
+            throw new IllegalArgumentException(
+                    "Module reference cannot be NULL!");
+        }
+
+        if (module.getName() == null) {
+            throw new IllegalArgumentException("Module name cannot be NULL!");
+        }
+
+        if (module.getChildNodes() == null) {
+            throw new IllegalArgumentException("Reference to Set of "
+                    + "Augmentation Definitions in module " + module.getName()
+                    + " cannot be NULL!");
+        }
+
+        final List<Type> generatedTypes = new ArrayList<>();
+        final String basePackageName = moduleNamespaceToPackageName(module);
+        final List<AugmentationSchema> augmentations = resolveAugmentations(module);
+        for (final AugmentationSchema augment : augmentations) {
+            generatedTypes.addAll(augmentationToGenTypes(basePackageName,
+                    augment));
+        }
+        return generatedTypes;
+    }
+
+    private List<AugmentationSchema> resolveAugmentations(final Module module) {
+        if (module == null) {
+            throw new IllegalArgumentException(
+                    "Module reference cannot be NULL!");
+        }
+        if (module.getAugmentations() == null) {
+            throw new IllegalStateException("Augmentations Set cannot be NULL!");
+        }
+
+        final Set<AugmentationSchema> augmentations = module.getAugmentations();
+        final List<AugmentationSchema> sortedAugmentations = new ArrayList<>(
+                augmentations);
+        Collections.sort(sortedAugmentations,
+                new Comparator<AugmentationSchema>() {
+
+                    @Override
+                    public int compare(AugmentationSchema augSchema1,
+                            AugmentationSchema augSchema2) {
+
+                        if (augSchema1.getTargetPath().getPath().size() > augSchema2
+                                .getTargetPath().getPath().size()) {
+                            return 1;
+                        } else if (augSchema1.getTargetPath().getPath().size() < augSchema2
+                                .getTargetPath().getPath().size()) {
+                            return -1;
+                        }
+                        return 0;
+
+                    }
+                });
+
+        return sortedAugmentations;
+    }
+
+    private GeneratedType moduleToDataType(final Module module) {
+        if (module == null) {
+            throw new IllegalArgumentException(
+                    "Module reference cannot be NULL!");
+        }
+
+        final GeneratedTypeBuilder moduleDataTypeBuilder = moduleTypeBuilder(
+                module, "Data");
+
+        final String basePackageName = moduleNamespaceToPackageName(module);
+        if (moduleDataTypeBuilder != null) {
+            final Set<DataSchemaNode> dataNodes = module.getChildNodes();
+            resolveDataSchemaNodes(basePackageName, moduleDataTypeBuilder,
+                    dataNodes);
+        }
+        return moduleDataTypeBuilder.toInstance();
+    }
+
+    private List<Type> allRPCMethodsToGenType(final Module module) {
+        if (module == null) {
+            throw new IllegalArgumentException(
+                    "Module reference cannot be NULL!");
+        }
+
+        if (module.getName() == null) {
+            throw new IllegalArgumentException("Module name cannot be NULL!");
+        }
+
+        if (module.getChildNodes() == null) {
+            throw new IllegalArgumentException("Reference to Set of "
+                    + "RPC Method Definitions in module " + module.getName()
+                    + " cannot be NULL!");
+        }
+
+        final String basePackageName = moduleNamespaceToPackageName(module);
+        final Set<RpcDefinition> rpcDefinitions = module.getRpcs();
+        final List<Type> genRPCTypes = new ArrayList<>();
+        final GeneratedTypeBuilder interfaceBuilder = moduleTypeBuilder(module,
+                "Service");
+        final Type future = Types.typeForClass(Future.class);
+        for (final RpcDefinition rpc : rpcDefinitions) {
+            if (rpc != null) {
+
+                String rpcName = parseToClassName(rpc.getQName()
+                        .getLocalName());
+                MethodSignatureBuilder method = interfaceBuilder
+                        .addMethod(rpcName);
+
+                final List<DataNodeIterator> rpcInOut = new ArrayList<>();
+
+                ContainerSchemaNode input = rpc.getInput();
+                ContainerSchemaNode output = rpc.getOutput();
+
+                if (input != null) {
+                    rpcInOut.add(new DataNodeIterator(input));
+                    GeneratedTypeBuilder inType = addRawInterfaceDefinition(
+                            basePackageName, input, rpcName);
+                    resolveDataSchemaNodes(basePackageName, inType, input.getChildNodes());
+                    Type inTypeInstance = inType.toInstance();
+                    genRPCTypes.add(inTypeInstance);
+                    method.addParameter(inTypeInstance, "input");
+                }
+
+                Type outTypeInstance = Types.typeForClass(Void.class);
+                if (output != null) {
+                    rpcInOut.add(new DataNodeIterator(output));
+
+                    GeneratedTypeBuilder outType = addRawInterfaceDefinition(
+                            basePackageName, output, rpcName);
+                    resolveDataSchemaNodes(basePackageName, outType, output.getChildNodes());
+                    outTypeInstance = outType.toInstance();
+                    genRPCTypes.add(outTypeInstance);
+
+                }
+
+                final Type rpcRes = Types.parameterizedTypeFor(
+                        Types.typeForClass(RpcResult.class), outTypeInstance);
+                method.addReturnType(Types.parameterizedTypeFor(future, rpcRes));
+                for (DataNodeIterator it : rpcInOut) {
+                    List<ContainerSchemaNode> nContainers = it.allContainers();
+                    if ((nContainers != null) && !nContainers.isEmpty()) {
+                        for (final ContainerSchemaNode container : nContainers) {
+                            genRPCTypes.add(containerToGenType(basePackageName,
+                                    container));
+                        }
+                    }
+                    List<ListSchemaNode> nLists = it.allLists();
+                    if ((nLists != null) && !nLists.isEmpty()) {
+                        for (final ListSchemaNode list : nLists) {
+                            genRPCTypes.addAll(listToGenType(basePackageName,
+                                    list));
+                        }
+                    }
+                }
+            }
+        }
+        genRPCTypes.add(interfaceBuilder.toInstance());
+        return genRPCTypes;
+    }
+
+    private List<Type> allNotificationsToGenType(final Module module) {
+        if (module == null) {
+            throw new IllegalArgumentException(
+                    "Module reference cannot be NULL!");
+        }
+
+        if (module.getName() == null) {
+            throw new IllegalArgumentException("Module name cannot be NULL!");
+        }
+
+        if (module.getChildNodes() == null) {
+            throw new IllegalArgumentException("Reference to Set of "
+                    + "Notification Definitions in module " + module.getName()
+                    + " cannot be NULL!");
+        }
+
+        final String basePackageName = moduleNamespaceToPackageName(module);
+        final List<Type> genNotifyTypes = new ArrayList<>();
+        final Set<NotificationDefinition> notifications = module
+                .getNotifications();
+
+        for (final NotificationDefinition notification : notifications) {
+            if (notification != null) {
+                DataNodeIterator it = new DataNodeIterator(notification);
+
+                // Containers
+                for (ContainerSchemaNode node : it.allContainers()) {
+                    genNotifyTypes
+                            .add(containerToGenType(basePackageName, node));
+                }
+                // Lists
+                for (ListSchemaNode node : it.allLists()) {
+                    genNotifyTypes.addAll(listToGenType(basePackageName, node));
+                }
+                final GeneratedTypeBuilder notificationTypeBuilder = addRawInterfaceDefinition(
+                        basePackageName, notification);
+                notificationTypeBuilder.addImplementsType(Types
+                        .typeForClass(Notification.class));
+                // Notification object
+                resolveDataSchemaNodes(basePackageName,
+                        notificationTypeBuilder, notification.getChildNodes());
+                genNotifyTypes.add(notificationTypeBuilder.toInstance());
+            }
+        }
+        return genNotifyTypes;
+    }
+
+    private List<Type> allIdentitiesToGenTypes(final Module module,
+            final SchemaContext context) {
+        List<Type> genTypes = new ArrayList<Type>();
+
+        final Set<IdentitySchemaNode> schemaIdentities = module.getIdentities();
+
+        final String basePackageName = moduleNamespaceToPackageName(module);
+
+        if (schemaIdentities != null && !schemaIdentities.isEmpty()) {
+            for (final IdentitySchemaNode identity : schemaIdentities) {
+                genTypes.add(identityToGenType(basePackageName, identity,
+                        context));
+            }
+        }
+        return genTypes;
+    }
+
+    private GeneratedType identityToGenType(final String basePackageName,
+            IdentitySchemaNode identity, SchemaContext context) {
+        if (identity == null) {
+            return null;
+        }
+
+        final String packageName = packageNameForGeneratedType(basePackageName,
+                identity.getPath());
+
+        final String genTypeName = parseToClassName(identity.getQName()
+                .getLocalName());
+        final GeneratedTOBuilderImpl newType = new GeneratedTOBuilderImpl(
+                packageName, genTypeName);
+
+        IdentitySchemaNode baseIdentity = identity.getBaseIdentity();
+        if (baseIdentity != null) {
+            Module baseIdentityParentModule = SchemaContextUtil.findParentModule(
+                    context, baseIdentity);
+
+            final String returnTypePkgName = moduleNamespaceToPackageName(baseIdentityParentModule);
+            final String returnTypeName = parseToClassName(baseIdentity
+                    .getQName().getLocalName());
+
+            GeneratedTransferObject gto = new GeneratedTOBuilderImpl(
+                    returnTypePkgName, returnTypeName).toInstance();
+            newType.addExtendsType(gto);
+        } else {
+            newType.addExtendsType(Types.getBaseIdentityTO());
+        }
+
+        return newType.toIdentityInstance();
+    }
+
+    private List<Type> allGroupingsToGenTypes(Module module) {
+        final List<Type> genTypes = new ArrayList<Type>();
+        final String basePackageName = moduleNamespaceToPackageName(module);
+        Set<GroupingDefinition> groupings = module.getGroupings();
+        if (groupings != null && !groupings.isEmpty()) {
+            for (final GroupingDefinition grouping : groupings) {
+                genTypes.add(groupingToGenType(basePackageName, grouping));
+            }
+        }
+        return genTypes;
+    }
+
+    private GeneratedType groupingToGenType(final String basePackageName,
+            GroupingDefinition grouping) {
+        if (grouping == null) {
+            return null;
+        }
+
+        final String packageName = packageNameForGeneratedType(basePackageName,
+                grouping.getPath());
+        final Set<DataSchemaNode> schemaNodes = grouping.getChildNodes();
+        final GeneratedTypeBuilder typeBuilder = addRawInterfaceDefinition(
+                packageName, grouping);
+
+        resolveDataSchemaNodes(basePackageName, typeBuilder, schemaNodes);
+        return typeBuilder.toInstance();
+    }
+
+    private EnumTypeDefinition enumTypeDefFromExtendedType(
+            final TypeDefinition<?> typeDefinition) {
+        if (typeDefinition != null) {
+            if (typeDefinition.getBaseType() instanceof EnumTypeDefinition) {
+                return (EnumTypeDefinition) typeDefinition.getBaseType();
+            } else if (typeDefinition.getBaseType() instanceof ExtendedType) {
+                return enumTypeDefFromExtendedType(typeDefinition.getBaseType());
+            }
+        }
+        return null;
+    }
+
+    private EnumBuilder resolveInnerEnumFromTypeDefinition(
+            final EnumTypeDefinition enumTypeDef, final String enumName,
+            final GeneratedTypeBuilder typeBuilder) {
+        if ((enumTypeDef != null) && (typeBuilder != null)
+                && (enumTypeDef.getQName() != null)
+                && (enumTypeDef.getQName().getLocalName() != null)) {
+
+            final String enumerationName = parseToClassName(enumName);
+            final EnumBuilder enumBuilder = typeBuilder
+                    .addEnumeration(enumerationName);
+
+            if (enumBuilder != null) {
+                final List<EnumPair> enums = enumTypeDef.getValues();
+                if (enums != null) {
+                    int listIndex = 0;
+                    for (final EnumPair enumPair : enums) {
+                        if (enumPair != null) {
+                            final String enumPairName = parseToClassName(enumPair
+                                    .getName());
+                            Integer enumPairValue = enumPair.getValue();
+
+                            if (enumPairValue == null) {
+                                enumPairValue = listIndex;
+                            }
+                            enumBuilder.addValue(enumPairName, enumPairValue);
+                            listIndex++;
+                        }
+                    }
+                }
+                return enumBuilder;
+            }
+        }
+        return null;
+    }
+
+    private GeneratedTypeBuilder moduleTypeBuilder(final Module module,
+            final String postfix) {
+        if (module == null) {
+            throw new IllegalArgumentException(
+                    "Module reference cannot be NULL!");
+        }
+        String packageName = moduleNamespaceToPackageName(module);
+        final String moduleName = parseToClassName(module.getName()) + postfix;
+
+        return new GeneratedTypeBuilderImpl(packageName, moduleName);
+
+    }
+
+    private List<Type> augmentationToGenTypes(final String augmentPackageName,
+            final AugmentationSchema augSchema) {
+        if (augmentPackageName == null) {
+            throw new IllegalArgumentException("Package Name cannot be NULL!");
+        }
+        if (augSchema == null) {
+            throw new IllegalArgumentException(
+                    "Augmentation Schema cannot be NULL!");
+        }
+        if (augSchema.getTargetPath() == null) {
+            throw new IllegalStateException(
+                    "Augmentation Schema does not contain Target Path (Target Path is NULL).");
+        }
+
+        final List<Type> genTypes = new ArrayList<>();
+
+        // EVERY augmented interface will extends Augmentation<T> interface
+        // and DataObject interface!!!
+        final SchemaPath targetPath = augSchema.getTargetPath();
+        final DataSchemaNode targetSchemaNode = findDataSchemaNode(
+                schemaContext, targetPath);
+        if ((targetSchemaNode != null) && (targetSchemaNode.getQName() != null)
+                && (targetSchemaNode.getQName().getLocalName() != null)) {
+            final Module targetModule = findParentModule(schemaContext,
+                    targetSchemaNode);
+
+            final String targetBasePackage = moduleNamespaceToPackageName(targetModule);
+            final String targetPackageName = packageNameForGeneratedType(
+                    targetBasePackage, targetSchemaNode.getPath());
+
+            final String targetSchemaNodeName = targetSchemaNode.getQName()
+                    .getLocalName();
+            final Set<DataSchemaNode> augChildNodes = augSchema.getChildNodes();
+            final GeneratedTypeBuilder augTypeBuilder = addRawAugmentGenTypeDefinition(
+                    augmentPackageName, targetPackageName,
+                    targetSchemaNodeName, augSchema);
+            if (augTypeBuilder != null) {
+                genTypes.add(augTypeBuilder.toInstance());
+            }
+            genTypes.addAll(augmentationBodyToGenTypes(augmentPackageName,
+                    augChildNodes));
+
+        }
+        return genTypes;
+    }
+
+    private GeneratedTypeBuilder addRawAugmentGenTypeDefinition(
+            final String augmentPackageName, final String targetPackageName,
+            final String targetSchemaNodeName,
+            final AugmentationSchema augSchema) {
+        final String targetTypeName = parseToClassName(targetSchemaNodeName);
+        Map<String, GeneratedTypeBuilder> augmentBuilders = genTypeBuilders
+                .get(augmentPackageName);
+        if (augmentBuilders == null) {
+            augmentBuilders = new HashMap<>();
+            genTypeBuilders.put(augmentPackageName, augmentBuilders);
+        }
+
+        final String augTypeName = augGenTypeName(augmentBuilders,
+                targetTypeName);
+        final Type targetTypeRef = new ReferencedTypeImpl(targetPackageName,
+                targetTypeName);
+        final Set<DataSchemaNode> augChildNodes = augSchema.getChildNodes();
+
+        final GeneratedTypeBuilder augTypeBuilder = new GeneratedTypeBuilderImpl(
+                augmentPackageName, augTypeName);
+
+        augTypeBuilder.addImplementsType(Types.DATA_OBJECT);
+        augTypeBuilder.addImplementsType(Types
+                .augmentationTypeFor(targetTypeRef));
+
+        augSchemaNodeToMethods(augmentPackageName, augTypeBuilder,
+                augChildNodes);
+        augmentBuilders.put(augTypeName, augTypeBuilder);
+        return augTypeBuilder;
+    }
+
+    private List<Type> augmentationBodyToGenTypes(
+            final String augBasePackageName,
+            final Set<DataSchemaNode> augChildNodes) {
+        final List<Type> genTypes = new ArrayList<>();
+        final List<DataNodeIterator> augSchemaIts = new ArrayList<>();
+        for (final DataSchemaNode childNode : augChildNodes) {
+            if (childNode instanceof DataNodeContainer) {
+                augSchemaIts.add(new DataNodeIterator(
+                        (DataNodeContainer) childNode));
+
+                if (childNode instanceof ContainerSchemaNode) {
+                    genTypes.add(containerToGenType(augBasePackageName,
+                            (ContainerSchemaNode) childNode));
+                } else if (childNode instanceof ListSchemaNode) {
+                    genTypes.addAll(listToGenType(augBasePackageName,
+                            (ListSchemaNode) childNode));
+                }
+            }
+        }
+
+        for (final DataNodeIterator it : augSchemaIts) {
+            final List<ContainerSchemaNode> augContainers = it.allContainers();
+            final List<ListSchemaNode> augLists = it.allLists();
+
+            if ((augContainers != null) && !augContainers.isEmpty()) {
+                for (final ContainerSchemaNode container : augContainers) {
+                    genTypes.add(containerToGenType(augBasePackageName,
+                            container));
+                }
+            }
+            if ((augLists != null) && !augLists.isEmpty()) {
+                for (final ListSchemaNode list : augLists) {
+                    genTypes.addAll(listToGenType(augBasePackageName, list));
+                }
+            }
+        }
+        return genTypes;
+    }
+
+    private String augGenTypeName(
+            final Map<String, GeneratedTypeBuilder> builders,
+            final String genTypeName) {
+        String augTypeName = genTypeName;
+
+        int index = 1;
+        while ((builders != null) && builders.containsKey(genTypeName + index)) {
+            index++;
+        }
+        augTypeName += index;
+        return augTypeName;
+    }
+
+    private GeneratedType containerToGenType(final String basePackageName,
+            ContainerSchemaNode containerNode) {
+        if (containerNode == null) {
+            return null;
+        }
+
+        final String packageName = packageNameForGeneratedType(basePackageName,
+                containerNode.getPath());
+        final Set<DataSchemaNode> schemaNodes = containerNode.getChildNodes();
+        final GeneratedTypeBuilder typeBuilder = addRawInterfaceDefinition(
+                packageName, containerNode);
+
+        resolveDataSchemaNodes(basePackageName, typeBuilder, schemaNodes);
+        return typeBuilder.toInstance();
+    }
+
+    private GeneratedTypeBuilder resolveDataSchemaNodes(
+            final String basePackageName,
+            final GeneratedTypeBuilder typeBuilder,
+            final Set<DataSchemaNode> schemaNodes) {
+
+        if ((schemaNodes != null) && (typeBuilder != null)) {
+            for (final DataSchemaNode schemaNode : schemaNodes) {
+                if (schemaNode.isAugmenting()) {
+                    continue;
+                }
+                addSchemaNodeToBuilderAsMethod(basePackageName, schemaNode,
+                        typeBuilder);
+            }
+        }
+        return typeBuilder;
+    }
+
+    private GeneratedTypeBuilder augSchemaNodeToMethods(
+            final String basePackageName,
+            final GeneratedTypeBuilder typeBuilder,
+            final Set<DataSchemaNode> schemaNodes) {
+
+        if ((schemaNodes != null) && (typeBuilder != null)) {
+            for (final DataSchemaNode schemaNode : schemaNodes) {
+                if (schemaNode.isAugmenting()) {
+                    addSchemaNodeToBuilderAsMethod(basePackageName, schemaNode,
+                            typeBuilder);
+                }
+            }
+        }
+        return typeBuilder;
+    }
+
+    private void addSchemaNodeToBuilderAsMethod(final String basePackageName,
+            final DataSchemaNode schemaNode,
+            final GeneratedTypeBuilder typeBuilder) {
+        if (schemaNode != null && typeBuilder != null) {
+            if (schemaNode instanceof LeafSchemaNode) {
+                resolveLeafSchemaNodeAsMethod(typeBuilder,
+                        (LeafSchemaNode) schemaNode);
+            } else if (schemaNode instanceof LeafListSchemaNode) {
+                resolveLeafListSchemaNode(typeBuilder,
+                        (LeafListSchemaNode) schemaNode);
+            } else if (schemaNode instanceof ContainerSchemaNode) {
+                resolveContainerSchemaNode(basePackageName, typeBuilder,
+                        (ContainerSchemaNode) schemaNode);
+            } else if (schemaNode instanceof ListSchemaNode) {
+                resolveListSchemaNode(basePackageName, typeBuilder,
+                        (ListSchemaNode) schemaNode);
+            }
+        }
+    }
+
+    private boolean resolveLeafSchemaNodeAsMethod(
+            final GeneratedTypeBuilder typeBuilder, final LeafSchemaNode leaf) {
+        if ((leaf != null) && (typeBuilder != null)) {
+            final String leafName = leaf.getQName().getLocalName();
+            String leafDesc = leaf.getDescription();
+            if (leafDesc == null) {
+                leafDesc = "";
+            }
+
+            if (leafName != null) {
+                final TypeDefinition<?> typeDef = leaf.getType();
+
+                Type returnType = null;
+                if (!(typeDef instanceof EnumTypeDefinition)) {
+                    returnType = typeProvider
+                            .javaTypeForSchemaDefinitionType(typeDef);
+                } else {
+                    final EnumTypeDefinition enumTypeDef = enumTypeDefFromExtendedType(typeDef);
+                    final EnumBuilder enumBuilder = resolveInnerEnumFromTypeDefinition(
+                            enumTypeDef, leafName, typeBuilder);
+
+                    if (enumBuilder != null) {
+                        returnType = new ReferencedTypeImpl(
+                                enumBuilder.getPackageName(),
+                                enumBuilder.getName());
+                    }
+                    ((TypeProviderImpl) typeProvider).putReferencedType(
+                            leaf.getPath(), returnType);
+                }
+                if (returnType != null) {
+                    constructGetter(typeBuilder, leafName, leafDesc, returnType);
+                    if (!leaf.isConfiguration()) {
+                        constructSetter(typeBuilder, leafName, leafDesc,
+                                returnType);
+                    }
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    private boolean resolveLeafSchemaNodeAsProperty(
+            final GeneratedTOBuilder toBuilder, final LeafSchemaNode leaf,
+            boolean isReadOnly) {
+        if ((leaf != null) && (toBuilder != null)) {
+            final String leafName = leaf.getQName().getLocalName();
+            String leafDesc = leaf.getDescription();
+            if (leafDesc == null) {
+                leafDesc = "";
+            }
+
+            if (leafName != null) {
+                final TypeDefinition<?> typeDef = leaf.getType();
+
+                // TODO: properly resolve enum types
+                final Type returnType = typeProvider
+                        .javaTypeForSchemaDefinitionType(typeDef);
+
+                if (returnType != null) {
+                    final GeneratedPropertyBuilder propBuilder = toBuilder
+                            .addProperty(parseToClassName(leafName));
+
+                    propBuilder.setReadOnly(isReadOnly);
+                    propBuilder.addReturnType(returnType);
+                    propBuilder.addComment(leafDesc);
+
+                    toBuilder.addEqualsIdentity(propBuilder);
+                    toBuilder.addHashIdentity(propBuilder);
+                    toBuilder.addToStringProperty(propBuilder);
+
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    private boolean resolveLeafListSchemaNode(
+            final GeneratedTypeBuilder typeBuilder,
+            final LeafListSchemaNode node) {
+        if ((node != null) && (typeBuilder != null)) {
+            final String nodeName = node.getQName().getLocalName();
+            String nodeDesc = node.getDescription();
+            if (nodeDesc == null) {
+                nodeDesc = "";
+            }
+
+            if (nodeName != null) {
+                final TypeDefinition<?> type = node.getType();
+                final Type listType = Types.listTypeFor(typeProvider
+                        .javaTypeForSchemaDefinitionType(type));
+
+                constructGetter(typeBuilder, nodeName, nodeDesc, listType);
+                if (!node.isConfiguration()) {
+                    constructSetter(typeBuilder, nodeName, nodeDesc, listType);
+                }
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private boolean resolveContainerSchemaNode(final String basePackageName,
+            final GeneratedTypeBuilder typeBuilder,
+            final ContainerSchemaNode containerNode) {
+        if ((containerNode != null) && (typeBuilder != null)) {
+            final String nodeName = containerNode.getQName().getLocalName();
+
+            if (nodeName != null) {
+                final String packageName = packageNameForGeneratedType(
+                        basePackageName, containerNode.getPath());
+
+                final GeneratedTypeBuilder rawGenType = addRawInterfaceDefinition(
+                        packageName, containerNode);
+                constructGetter(typeBuilder, nodeName, "", rawGenType);
+
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private boolean resolveListSchemaNode(final String basePackageName,
+            final GeneratedTypeBuilder typeBuilder,
+            final ListSchemaNode schemaNode) {
+        if ((schemaNode != null) && (typeBuilder != null)) {
+            final String listName = schemaNode.getQName().getLocalName();
+
+            if (listName != null) {
+                final String packageName = packageNameForGeneratedType(
+                        basePackageName, schemaNode.getPath());
+                final GeneratedTypeBuilder rawGenType = addRawInterfaceDefinition(
+                        packageName, schemaNode);
+                constructGetter(typeBuilder, listName, "",
+                        Types.listTypeFor(rawGenType));
+                if (!schemaNode.isConfiguration()) {
+                    constructSetter(typeBuilder, listName, "",
+                            Types.listTypeFor(rawGenType));
+                }
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private GeneratedTypeBuilder addRawInterfaceDefinition(
+            final String packageName, final SchemaNode schemaNode) {
+        return addRawInterfaceDefinition(packageName, schemaNode, "");
+    }
+
+    private GeneratedTypeBuilder addRawInterfaceDefinition(
+            final String packageName, final SchemaNode schemaNode,
+            final String prefix) {
+        if (schemaNode == null) {
+            return null;
+        }
+
+        final String schemaNodeName = schemaNode.getQName().getLocalName();
+
+        if ((packageName != null) && (schemaNodeName != null)) {
+            final String genTypeName = prefix + parseToClassName(schemaNodeName)
+                    ;
+            final GeneratedTypeBuilder newType = new GeneratedTypeBuilderImpl(
+                    packageName, genTypeName);
+
+            newType.addImplementsType(Types.DATA_OBJECT);
+            newType.addImplementsType(Types.augmentableTypeFor(newType));
+
+            if (!genTypeBuilders.containsKey(packageName)) {
+                final Map<String, GeneratedTypeBuilder> builders = new HashMap<>();
+                builders.put(genTypeName, newType);
+                genTypeBuilders.put(packageName, builders);
+            } else {
+                final Map<String, GeneratedTypeBuilder> builders = genTypeBuilders
+                        .get(packageName);
+                if (!builders.containsKey(genTypeName)) {
+                    builders.put(genTypeName, newType);
+                }
+            }
+            return newType;
+        }
+        return null;
+    }
+
+    private String getterMethodName(final String methodName) {
+        final StringBuilder method = new StringBuilder();
+        method.append("get");
+        method.append(parseToClassName(methodName));
+        return method.toString();
+    }
+
+    private String setterMethodName(final String methodName) {
+        final StringBuilder method = new StringBuilder();
+        method.append("set");
+        method.append(parseToClassName(methodName));
+        return method.toString();
+    }
+
+    private MethodSignatureBuilder constructGetter(
+            final GeneratedTypeBuilder interfaceBuilder,
+            final String schemaNodeName, final String comment,
+            final Type returnType) {
+        final MethodSignatureBuilder getMethod = interfaceBuilder
+                .addMethod(getterMethodName(schemaNodeName));
+
+        getMethod.addComment(comment);
+        getMethod.addReturnType(returnType);
+
+        return getMethod;
+    }
+
+    private MethodSignatureBuilder constructSetter(
+            final GeneratedTypeBuilder interfaceBuilder,
+            final String schemaNodeName, final String comment,
+            final Type parameterType) {
+        final MethodSignatureBuilder setMethod = interfaceBuilder
+                .addMethod(setterMethodName(schemaNodeName));
+
+        setMethod.addComment(comment);
+        setMethod.addParameter(parameterType,
+                parseToValidParamName(schemaNodeName));
+        setMethod.addReturnType(Types.voidType());
+
+        return setMethod;
+    }
+
+    private List<Type> listToGenType(final String basePackageName,
+            final ListSchemaNode list) {
+        if (basePackageName == null) {
+            throw new IllegalArgumentException(
+                    "Package Name for Generated Type cannot be NULL!");
+        }
+        if (list == null) {
+            throw new IllegalArgumentException(
+                    "List Schema Node cannot be NULL!");
+        }
+
+        final String packageName = packageNameForGeneratedType(basePackageName,
+                list.getPath());
+        final GeneratedTypeBuilder typeBuilder = resolveListTypeBuilder(
+                packageName, list);
+        final List<String> listKeys = listKeys(list);
+        GeneratedTOBuilder genTOBuilder = resolveListKeyTOBuilder(packageName,
+                list, listKeys);
+
+        final Set<DataSchemaNode> schemaNodes = list.getChildNodes();
+
+        for (final DataSchemaNode schemaNode : schemaNodes) {
+            if (schemaNode.isAugmenting()) {
+                continue;
+            }
+            addSchemaNodeToListBuilders(basePackageName, schemaNode,
+                    typeBuilder, genTOBuilder, listKeys);
+        }
+        return typeBuildersToGenTypes(typeBuilder, genTOBuilder);
+    }
+
+    private void addSchemaNodeToListBuilders(final String basePackageName,
+            final DataSchemaNode schemaNode,
+            final GeneratedTypeBuilder typeBuilder,
+            final GeneratedTOBuilder genTOBuilder, final List<String> listKeys) {
+        if (schemaNode == null) {
+            throw new IllegalArgumentException(
+                    "Data Schema Node cannot be NULL!");
+        }
+
+        if (typeBuilder == null) {
+            throw new IllegalArgumentException(
+                    "Generated Type Builder cannot be NULL!");
+        }
+
+        if (schemaNode instanceof LeafSchemaNode) {
+            final LeafSchemaNode leaf = (LeafSchemaNode) schemaNode;
+            if (!isPartOfListKey(leaf, listKeys)) {
+                resolveLeafSchemaNodeAsMethod(typeBuilder, leaf);
+            } else {
+                resolveLeafSchemaNodeAsProperty(genTOBuilder, leaf, true);
+            }
+        } else if (schemaNode instanceof LeafListSchemaNode) {
+            resolveLeafListSchemaNode(typeBuilder,
+                    (LeafListSchemaNode) schemaNode);
+        } else if (schemaNode instanceof ContainerSchemaNode) {
+            resolveContainerSchemaNode(basePackageName, typeBuilder,
+                    (ContainerSchemaNode) schemaNode);
+        } else if (schemaNode instanceof ListSchemaNode) {
+            resolveListSchemaNode(basePackageName, typeBuilder,
+                    (ListSchemaNode) schemaNode);
+        }
+    }
+
+    private List<Type> typeBuildersToGenTypes(
+            final GeneratedTypeBuilder typeBuilder,
+            GeneratedTOBuilder genTOBuilder) {
+        final List<Type> genTypes = new ArrayList<>();
+        if (typeBuilder == null) {
+            throw new IllegalArgumentException(
+                    "Generated Type Builder cannot be NULL!");
+        }
+
+        if (genTOBuilder != null) {
+            final GeneratedTransferObject genTO = genTOBuilder.toInstance();
+            constructGetter(typeBuilder, genTO.getName(),
+                    "Returns Primary Key of Yang List Type", genTO);
+            genTypes.add(genTO);
+        }
+        genTypes.add(typeBuilder.toInstance());
+        return genTypes;
+    }
+
+    /**
+     * @param list
+     * @return
+     */
+    private GeneratedTOBuilder resolveListKey(final String packageName,
+            final ListSchemaNode list) {
+        final String listName = list.getQName().getLocalName() + "Key";
+        return schemaNodeToTransferObjectBuilder(packageName, list, listName);
+    }
+
+    private boolean isPartOfListKey(final LeafSchemaNode leaf,
+            final List<String> keys) {
+        if ((leaf != null) && (keys != null) && (leaf.getQName() != null)) {
+            final String leafName = leaf.getQName().getLocalName();
+            if (keys.contains(leafName)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private List<String> listKeys(final ListSchemaNode list) {
+        final List<String> listKeys = new ArrayList<>();
+
+        if (list.getKeyDefinition() != null) {
+            final List<QName> keyDefinitions = list.getKeyDefinition();
+
+            for (final QName keyDefinition : keyDefinitions) {
+                listKeys.add(keyDefinition.getLocalName());
+            }
+        }
+        return listKeys;
+    }
+
+    private GeneratedTypeBuilder resolveListTypeBuilder(
+            final String packageName, final ListSchemaNode list) {
+        if (packageName == null) {
+            throw new IllegalArgumentException(
+                    "Package Name for Generated Type cannot be NULL!");
+        }
+        if (list == null) {
+            throw new IllegalArgumentException(
+                    "List Schema Node cannot be NULL!");
+        }
+
+        final String schemaNodeName = list.getQName().getLocalName();
+        final String genTypeName = parseToClassName(schemaNodeName);
+
+        GeneratedTypeBuilder typeBuilder = null;
+        final Map<String, GeneratedTypeBuilder> builders = genTypeBuilders
+                .get(packageName);
+        if (builders != null) {
+            typeBuilder = builders.get(genTypeName);
+        }
+        if (typeBuilder == null) {
+            typeBuilder = addRawInterfaceDefinition(packageName, list);
+        }
+        return typeBuilder;
+    }
+
+    private GeneratedTOBuilder resolveListKeyTOBuilder(
+            final String packageName, final ListSchemaNode list,
+            final List<String> listKeys) {
+        GeneratedTOBuilder genTOBuilder = null;
+        if (listKeys.size() > 0) {
+            genTOBuilder = resolveListKey(packageName, list);
+        }
+        return genTOBuilder;
+    }
+}