private static Tuple <ReflectNamespace, ReflectAssembly> FindNamespaceAndAssembly(Type type)
        {
            var asm = FindAssembly(type.Assembly.GetName().Name);

            if (asm == null)
            {
                asm = new ReflectAssembly
                {
                    Name     = type.Assembly.GetName().Name,
                    FullName = type.Assembly.GetName().FullName,
                    Version  = type.Assembly.ImageRuntimeVersion,
                    //Namespaces = new Tree<string, ReflectNamespace>(),
                    PublicKey =
                        PublicKeyToString(
                            type.Assembly.GetName().GetPublicKey()),
                    Context = new ReflectContext()
                    {
                        Assemblies = new Dictionary <string, ReflectAssembly>(),
                        Folder     = "NotFound",
                        Name       = "NotFound",
                        Namespaces = new Tree <string, ReflectNamespace>()
                    }
                }
            }
            ;

            var ns = FindNamespace(type.Namespace);

            if (ns == null)
            {
                ns = new ReflectNamespace()
                {
                    Assembly = asm,
                    Name     = type.Namespace,
                    Types    = new Dictionary <string, Lazy <ReflectType> >()
                }
            }
            ;
            return(new Tuple <ReflectNamespace, ReflectAssembly>(ns, asm));
        }
        public static void AddContext(string context, string path)
        {
            if (AssemblyModel.Contexts.ContainsKey(context))
            {
                return;
            }

            var directoryInfo = new DirectoryInfo(path);

            if (!directoryInfo.Exists)
            {
                throw new InvalidPathAssemblyModelException(path);
            }

            var newCtx = new ReflectContext()
            {
                Name       = context,
                Folder     = path,
                Assemblies = new Dictionary <string, ReflectAssembly>(),
                Namespaces = new Tree <string, ReflectNamespace>()
            };

            Contexts.Add(context, newCtx);

            foreach (var file in directoryInfo.GetFiles("*.dll"))
            {
                Assembly asm = null;

                try { asm = Assembly.LoadFrom(file.FullName); }
                catch
                {
                    continue;
                } //Ignores Invalid type of Exception


                var newassembly = new ReflectAssembly
                {
                    Context  = newCtx,
                    Name     = asm.GetName().Name,
                    FullName = asm.GetName().FullName,
                    Version  = asm.ImageRuntimeVersion,
                    //Namespaces = new Tree<string, ReflectNamespace>(),
                    PublicKey = PublicKeyToString(asm.GetName().GetPublicKey())
                };

                newCtx.Assemblies.Add(newassembly.Name, newassembly);


                try
                {
                    foreach (var type in asm.GetTypes())
                    {
                    }
                }
                catch
                {
                    //Inheritance security rules violated by type: 'System.Web.DynamicData.ControlFilterExpression'. Derived types must either match the security accessibility of the base type or be less accessible.":"System.Web.DynamicData.ControlFilterExpression"}
                    continue;
                }

                foreach (var type in asm.GetTypes())
                {
                    //adds to context namespace list
                    if (type.Namespace != null && type.IsPublic)
                    {
                        ReflectNamespace newNamesspace;

                        if (!newCtx.Namespaces.ContainsKey(type.Namespace.Split('.')))
                        {
                            newNamesspace =
                                new ReflectNamespace()
                            {
                                Name     = type.Namespace,
                                Assembly = newassembly,
                                Types    = new Dictionary <string, Lazy <ReflectType> >()
                            };

                            if (!newCtx.Namespaces.ContainsKey(newNamesspace.Name.Split('.')))
                            {
                                newCtx.Namespaces.Add(newNamesspace.Name.Split('.'), newNamesspace);
                                //fills null Objects with Namespaces must be on reverse order
                                var namespaceStack = new Stack <string>(newNamesspace.Name.Split('.').Reverse());
                                var namespaceList  = new StringBuilder();
                                //namespaceList.Append(namespaceStack.Pop());

                                foreach (var name in namespaceStack)
                                {
                                    if (namespaceList.Length == 0)
                                    {
                                        namespaceList.Append(name);
                                    }
                                    else
                                    {
                                        namespaceList.Append(".").Append(name);
                                    }

                                    var value = newCtx.Namespaces.GetValue(namespaceList.ToString().Split('.'));
                                    if (value == null)
                                    {
                                        newCtx.Namespaces.SetValue(namespaceList.ToString().Split('.'),
                                                                   new ReflectNamespace()
                                        {
                                            Assembly = newassembly,
                                            Name     = namespaceList.ToString(),
                                            Types    =
                                                new Dictionary <string, Lazy <ReflectType> >()
                                        });
                                    }
                                }
                            }
                        }
                        else
                        {
                            newNamesspace = newCtx.Namespaces.GetValue(type.Namespace.Split('.'));
                        }
                        // Adds to List
                        if (!newNamesspace.Types.ContainsKey(type.Name))
                        {
                            var reflectionType = type;
                            newNamesspace.Types.Add(type.Name,
                                                    new Lazy <ReflectType>(() => AddNewReflectType(reflectionType,
                                                                                                   newassembly,
                                                                                                   newNamesspace)));
                        }
                    }
                }
            }
        }
        private static void FillConstructors(Type type, ReflectType newType, ReflectAssembly newassembly, ReflectNamespace currNamespace)
        {
            foreach (var constructorInfo in type.GetConstructors())
            {
                var newMethod =
                    new ReflectMethod()
                {
                    Name       = constructorInfo.Name,
                    Parameters = new List <ReflectParameter>(),
                    Return     = null
                };

                foreach (var parameterInfo in constructorInfo.GetParameters())
                {
                    Tuple <ReflectNamespace, ReflectAssembly> asmns2 = FindNamespaceAndAssembly(parameterInfo.ParameterType);

                    newMethod.Parameters.Add(new ReflectParameter()
                    {
                        Name = parameterInfo.Name,
                        Type = AddNewSimpleReflectType(parameterInfo.ParameterType, asmns2.Item2, asmns2.Item1)
                    });
                }

                newType.Contructors.Add(newMethod);
            }
        }
        private static void FillMethods(Type type, ReflectType newType, ReflectAssembly newassembly, ReflectNamespace currNamespace)
        {
            foreach (var methodInfo in type.GetMethods())
            {
                // Finds or crates a new Type on this assembly
                Tuple <ReflectNamespace, ReflectAssembly> asmns = FindNamespaceAndAssembly(methodInfo.ReturnType);

                var newMethod =
                    new ReflectMethod()
                {
                    Name       = methodInfo.Name,
                    Parameters = new List <ReflectParameter>(),
                    Return     =
                        AddNewSimpleReflectType(methodInfo.ReturnType, asmns.Item2, asmns.Item1)
                };
                foreach (var parameterInfo in methodInfo.GetParameters())
                {
                    Tuple <ReflectNamespace, ReflectAssembly> asmns2 = FindNamespaceAndAssembly(parameterInfo.ParameterType);

                    newMethod.Parameters.Add(new ReflectParameter()
                    {
                        Name = parameterInfo.Name,
                        Type = AddNewSimpleReflectType(parameterInfo.ParameterType, asmns2.Item2, asmns2.Item1)
                    });
                }

                newType.Methods.Add(newMethod);
            }
        }
        private static void FillFields(Type type, ReflectType newType, ReflectAssembly newassembly, ReflectNamespace currNamespace)
        {
            foreach (var fieldInfo in type.GetFields())
            {
                // Finds or crates a new Type on this assembly
                Tuple <ReflectNamespace, ReflectAssembly> asmns = FindNamespaceAndAssembly(fieldInfo.FieldType);


                newType.Fields.Add(new ReflectField()
                {
                    Name = fieldInfo.Name,
                    Type =
                        AddNewSimpleReflectType(fieldInfo.FieldType, asmns.Item2, asmns.Item1)
                });
            }
        }
        private static void FillProperties(Type type, ReflectType newType, ReflectAssembly newassembly, ReflectNamespace currNamespace)
        {
            foreach (var propertyInfo in type.GetProperties())
            {
                // Finds or crates a new Type on this assembly
                Tuple <ReflectNamespace, ReflectAssembly> asmns = FindNamespaceAndAssembly(propertyInfo.PropertyType);

                newType.Properties.Add(new ReflectProperty()
                {
                    Name = propertyInfo.Name,
                    Type =
                        AddNewSimpleReflectType(propertyInfo.PropertyType, asmns.Item2, asmns.Item1)
                });
            }
        }
        private static ReflectType AddNewReflectType(Type type, ReflectAssembly newassembly, ReflectNamespace currNamespace)
        {
            var newType = new ReflectType()
            {
                Name        = type.Name,
                FullName    = type.FullName,
                Namespace   = currNamespace,
                Assembly    = newassembly,
                Contructors = new List <ReflectMethod>(),
                Methods     = new List <ReflectMethod>(),
                Fields      = new List <ReflectField>(),
                Properties  = new List <ReflectProperty>(),
                Events      = new List <ReflectEvent>(),
                CSharpName  = ToGenericTypeString(type)
            };

            FillConstructors(type, newType, newassembly, currNamespace);
            FillMethods(type, newType, newassembly, currNamespace);
            FillFields(type, newType, newassembly, currNamespace);
            FillProperties(type, newType, newassembly, currNamespace);
            FillEvents(type, newType);

            return(newType);
        }