/// <summary>
        /// Builds the view model.
        /// </summary>
        /// <param name="type">The type.</param>
        /// <param name="nameFactory">The name factory.</param>
        public static void BuildViewModel(Type type, Func<Type, string> nameFactory = null)
        {
            if (type == null || ViewModelDictionary.ContainsKey(type))
                return;
            var typeProperties = GetOrderedProperties(type);

            var vmClass = new ViewModelClass
            {
                Name = nameFactory == null ? type.Name : nameFactory(type),
                Properties = new List<ViewModelProperty>()
            };

            foreach (var property in typeProperties)
            {
                var vmProperty = new ViewModelProperty
                {
                    Name = property.Name,
                    UnderlyingType = property.PropertyType,
                    IsClass = property.PropertyType.IsClass,
                    IsArray = property.PropertyType.IsArray,
                    IsGenericType = property.PropertyType.IsGenericType,
                };

                vmProperty.UnderlyingType = vmProperty.IsGenericType
                    ? property.PropertyType.GetGenericTypeArgumentsTypes()[0]
                    : property.PropertyType;

                if (vmProperty.UnderlyingType.IsPrimitive ||
                    BindableNonPrimitiveTypes.Contains(vmProperty.UnderlyingType))
                {
                    vmProperty.IsClass = false;
                    //do nothing to avoid another mapping.
                }
                    //List or collection
                else if (typeof(IEnumerable).IsAssignableFrom(property.PropertyType))
                {
                    vmProperty.IsArray = true;
                    if (property.PropertyType.HasElementType)
                    {
                        vmProperty.UnderlyingType = property.PropertyType.GetElementType();
                        if (!property.PropertyType.IsPrimitive &&
                            !BindableNonPrimitiveTypes.Contains(vmProperty.UnderlyingType))
                        {
                            BuildViewModel(vmProperty.UnderlyingType, nameFactory);
                        }
                        else
                        {
                            vmProperty.IsClass = false;
                        }
                    }
                    else if (vmProperty.IsGenericType &&
                             !property.PropertyType.IsPrimitive &&
                             !BindableNonPrimitiveTypes.Contains(vmProperty.UnderlyingType))
                    {
                        BuildViewModel(vmProperty.UnderlyingType, nameFactory);
                    }
                    else
                    {
                        vmProperty.IsClass = false;
                    }
                }
                    // classes or interface
                else if (property.PropertyType.IsClass)
                {
                    BuildViewModel(vmProperty.UnderlyingType, nameFactory);
                }
                else if (!vmProperty.UnderlyingType.IsPrimitive &&
                         !BindableNonPrimitiveTypes.Contains(vmProperty.UnderlyingType))
                {
                    vmProperty.IsUnknown = true;
                }

                vmClass.Properties.Add(vmProperty);
            }

            ViewModelDictionary.TryAdd(type, vmClass);
        }
 private void GenerateProperties(ViewModelClass generatedVm, StringBuilder stringBuilder, int currentTabs)
 {
     var propertyTabls = currentTabs + 1;
     foreach (var property in generatedVm.Properties)
     {
         if (property.IsArray)
         {
             stringBuilder.Append(_viewModelGenerator.GetArrayProperty(property.Name, propertyTabls));
         }
         else if (property.IsClass)
         {
             var propertVm = ViewModelDictionary[property.UnderlyingType];
             stringBuilder.Append(_viewModelGenerator.GetClassProperty(property.Name, propertVm.Name, propertyTabls));
         }
         else
         {
             stringBuilder.Append(_viewModelGenerator.GetProperty(property.Name, propertyTabls));
         }
     }
 }
        private void GenerateUpdateMethod(ViewModelClass generatedVm, StringBuilder stringBuilder, int noOfTabs)
        {
            stringBuilder.Append(_viewModelGenerator.GetUpdatePropertiesStart(noOfTabs));

            var updatePropertyTabls = noOfTabs + 1;

            foreach (var property in generatedVm.Properties)
            {
                if (property.IsArray)
                {
                    stringBuilder.Append(_viewModelGenerator.GetArrayPropertyUpdate(property.Name, updatePropertyTabls));
                }
                else if (property.IsClass)
                {
                    stringBuilder.Append(_viewModelGenerator.GetClassPropertyUpdate(property.Name, updatePropertyTabls));
                }
                else
                {
                    var defaultValue = _viewModelGenerator.GetDefaultValue(property.UnderlyingType);
                    stringBuilder.Append(_viewModelGenerator.GetPropertyUpdate(property.Name, defaultValue,
                        updatePropertyTabls));
                }
            }

            stringBuilder.Append(_viewModelGenerator.GetUpdatePropertiesEnd(noOfTabs));
        }
        private void GenerateCrudMethods(ViewModelClass generatedVm, StringBuilder stringBuilder, int noOfTabs)
        {
            foreach (var property in generatedVm.Properties.Where(x => x.IsArray))
            {
                var generatedSubVm = ViewModelDictionary[property.UnderlyingType];

                stringBuilder.Append(_viewModelGenerator.GetAddFunction(property.Name, generatedSubVm.Name, noOfTabs));
                stringBuilder.Append(_viewModelGenerator.GetArrayPropertyUpdateMethod(property.Name, generatedSubVm.Name, noOfTabs));
                stringBuilder.Append(_viewModelGenerator.GetRemoveFunction(property.Name, generatedSubVm.Name, noOfTabs));
            }
        }