private static void LoadTable(Type type)
        {
            lock (cachePropertiesEx)
            {
                if (cachePropertiesEx.ContainsKey(type))
                {
                    return;
                }



                PropertiesExDictionary properties;
                var ancestorProperties = GetAncestorProperties(type);
                properties = ancestorProperties != null ? new PropertiesExDictionary(ancestorProperties) : new PropertiesExDictionary();

                //Use to asign a IndexParameter field when don't have index parameters for the property
                int numberOfParentProperties = 0;
                if (ALIAS_ENABLED)
                {
                    //Determine how many properties the parent has
                    var baseType = type.BaseType;
                    while (baseType != null)
                    {
                        numberOfParentProperties += baseType.GetProperties(BindingFlags.Public | BindingFlags.Instance).Count();
                        baseType = baseType.BaseType;
                    }
                }
                //short i = 0;
                var aliasIndex = numberOfParentProperties;
                //TODO: should we exclude properties here? like non-virtual or stateobject false?
                var  assemblyAttribute = (StateManagementDefaultValue)type.Assembly.GetCustomAttribute(typeof(StateManagementDefaultValue));
                var  typeName          = type.Name;
                bool flag = false;
                foreach (PropertyInfo prop in type.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly))
                {
                    var    propName      = prop.Name;
                    string propertyAlias = aliasIndex.ToBase48ToString();
                    aliasIndex++;
                    var typeAttribute = (StateManagementDefaultValue)Attribute.GetCustomAttribute(prop.DeclaringType, typeof(StateManagementDefaultValue), false);
                    var attr          = (StateManagement)prop.GetCustomAttributes(typeof(StateManagement), true).FirstOrDefault();

                    if (attr != null && !attr.RequiresStateManagement())
                    {
                        properties.RemoveProperty(propName);
                        continue;
                    }

                    bool isStrongReference = false;
                    bool isWeakReference   = false;
                    bool onlyHasGetter     = false;
                    bool isAssignableFromIModel;
                    bool isAssignableFromITopLevelStateObject;
                    bool isAssignableFromIViewManager;
                    bool isAssignableFromIIocContainer;
                    bool isAssignableFromILogicWithViewModel_IViewModel;
                    bool isVisibleStateFlag = false;
                    bool hasIndexParameters = false;
                    bool isAssignableFromIDependantViewModel = false;
                    //if (HasNoGetter(prop))
                    //{
                    //    //It will not be added to the list of propertyInfoEx
                    //    continue;
                    //}
                    //else if (HasNoSetter(prop))
                    //{
                    //    //It will not added to the list of propertyInfoEx but we will keep the flag
                    //    if (attr == null)
                    //        attr = new StateManagement(StateManagementValues.ClientOnly);
                    //    onlyHasGetter = true;
                    //}

                    /*if (!prop.CanRead)
                     * {
                     *  attr = new StateManagement(StateManagementValues.None);
                     * }*/
                    //We should exclude ViewManager and Container
                    if ((propName == "ViewManager" && prop.PropertyType == typeof(IViewManager)) ||
                        (propName == "Container" && prop.PropertyType == typeof(IIocContainer)))
                    {
                        continue;
                    }

                    var isStateObject  = typeof(IStateObject).IsAssignableFrom(prop.PropertyType);
                    var propertyType   = prop.PropertyType;
                    var propertyInfoEx = new PropertyInfoEx();
                    propertyInfoEx.OnlyHasGetter = onlyHasGetter;
                    if (ALIAS_ENABLED)
                    {
                        var aliasAttribute = (StateManagementAlias)prop.GetCustomAttributes(typeof(StateManagementAlias), true).FirstOrDefault();
                        if (aliasAttribute != null)
                        {
                            propertyInfoEx.alias = aliasAttribute.Value;
                        }
                        else
                        {
                            propertyInfoEx.alias = propertyAlias;
                        }
                    }
                    propertyInfoEx.prop         = prop;
                    propertyInfoEx.hasSurrogate = SurrogatesDirectory.IsSurrogateRegistered(propertyType);
                    var attrRef = prop.GetCustomAttributes(typeof(Reference), true).FirstOrDefault() as Reference;
                    propertyInfoEx.hasReferenceAttribute = attrRef != null;
                    if (propertyInfoEx.hasReferenceAttribute)
                    {
                        isStrongReference = attrRef.Value == ReferenceTypeValues.Strong;
                        isWeakReference   = attrRef.Value == ReferenceTypeValues.Weak;
                    }
                    isAssignableFromIModel = typeof(IModel).IsAssignableFrom(propertyType);
                    propertyInfoEx.isAssignableFromIDependantStateObject = typeof(IDependentStateObject).IsAssignableFrom(propertyType);
                    isAssignableFromIDependantViewModel  = typeof(IDependentViewModel).IsAssignableFrom(propertyType);
                    isAssignableFromITopLevelStateObject = typeof(ITopLevelStateObject).IsAssignableFrom(propertyType);
                    isAssignableFromIIocContainer        = typeof(IIocContainer).IsAssignableFrom(propertyType);
                    isAssignableFromIViewManager         = typeof(IViewManager).IsAssignableFrom(propertyType);

                    propertyInfoEx.isAnIDictionary = TypeCacheUtils.IsAnIDictionary(propertyType);
                    propertyInfoEx.isAnIList       = TypeCacheUtils.IsAnIList(propertyType);
                    if (prop.Name.Equals("VisibleState", StringComparison.Ordinal) && prop.PropertyType == typeof(VisibleState))
                    {
                        isVisibleStateFlag = true;
                    }
                    StateManagementValues stateManagementAttribute = StateManagementValues.Both;
                    if (attr != null)
                    {
                        stateManagementAttribute = attr.Value;
                    }
                    else if (typeAttribute != null)
                    {
                        if (!propertyInfoEx.isAnIList && !isAssignableFromIDependantViewModel)
                        {
                            stateManagementAttribute = typeAttribute.Value;
                        }
                    }
                    else if (assemblyAttribute != null)
                    {
                        if (!propertyInfoEx.isAnIList && !isAssignableFromIDependantViewModel)
                        {
                            stateManagementAttribute = assemblyAttribute.Value;
                        }
                    }

                    propertyInfoEx.stateManagementAttribute = stateManagementAttribute;
                    var indexParameters = prop.GetIndexParameters();
                    hasIndexParameters = (indexParameters != null) && (indexParameters.Length > 0);
                    //propertyInfoEx.propertyPositionIndex = i;

                    propertyInfoEx.mustIgnoreMemberForClient =
                        StateManagementUtils.MustIgnoreMember(true, prop) /*check the statemanagement attribute*/ ||
                        TypeCacheUtils.IsExcludedProperty(prop) ||
                        propertyInfoEx.hasSurrogate || isAssignableFromIDependantViewModel;

                    // propertyInfoEx.CanRead = prop.CanRead && prop.GetGetMethod(false) != null;
                    //	propertyInfoEx.CanWrite = prop.CanWrite && prop.GetGetMethod(false) != null;

                    //Read JsonNet attributes

                    //propertyInfoEx.jsonPropertyAttribute = Attribute.GetCustomAttribute(prop, typeof(Newtonsoft.Json.Serialization.JsonProperty), false);

                    //propertyInfoEx.defaultValueAttribute = Attribute.GetCustomAttribute(prop, typeof(System.ComponentModel.DefaultValueAttribute), false) as System.

                    //Validate if this is an IList of object
                    bool isASupportedValueTypeForIList = false;
                    if (propertyInfoEx.isAnIList && !propertyInfoEx.isAnIList)
                    {
                        //It could be an IList<object>, but it need to have the statemanagement attribute Generict
                        //var collAtt =
                        //	(GenericCollectionTypeInfo)prop.GetCustomAttributes(typeof(GenericCollectionTypeInfo), true).FirstOrDefault();
                        //if (collAtt != null && collAtt.RuntimeType == typeof(IList<IStateObject>))
                        //{
                        //	propertyInfoEx.isAnIListOfSomethingThatImplementsIStateObject = true;
                        //}
                        //else
                        //{
                        var listItemType = propertyType.GetGenericArguments()[0];
                        isASupportedValueTypeForIList = interceptionDelegates.isASupportedValueTypeForIListDelegate(listItemType);
                        TraceUtil.TraceError("invalid IList<object> possible statemanagement issues");
                        //}
                    }

                    isAssignableFromILogicWithViewModel_IViewModel =
                        typeof(ILogicWithViewModel <IViewModel>).IsAssignableFrom(propertyType);
                    propertyInfoEx.isStateObject             = isStateObject;
                    propertyInfoEx.isNonStateObjectFixedType = propertyType.IsValueType || typeof(string) == propertyType ||
                                                               typeof(Type) == propertyType;
                    propertyInfoEx.isObjectPropertyType = typeof(Object) == propertyType;
                    //We Assign the corresponding getter Action
                    if (isStrongReference || propertyInfoEx.isObjectPropertyType)
                    {
                        propertyInfoEx.ProcessGetter = interceptionDelegates.ProcessGetterStrongReference;
                    }
                    else if (isWeakReference)
                    {
                        propertyInfoEx.ProcessGetter = interceptionDelegates.ProcessGetterWeakReference;
                    }
                    else if (propertyInfoEx.hasSurrogate)
                    {
                        propertyInfoEx.ProcessGetter = interceptionDelegates.ProcessGetterSurrogate;
                    }
                    else if (propertyInfoEx.isAssignableFromIDependantStateObject ||
                             propertyInfoEx.isAnIList ||
                             propertyInfoEx.isAnIDictionary || isASupportedValueTypeForIList)
                    {
                        propertyInfoEx.ProcessGetter = interceptionDelegates.ProcessGetterNonTopLevelIStateObject;
                    }
                    else if (isAssignableFromITopLevelStateObject)
                    {
                        propertyInfoEx.ProcessGetter = interceptionDelegates.ProcessGetterTopLevelIStateObject;
                    }
                    else if (isAssignableFromILogicWithViewModel_IViewModel)
                    {
                        propertyInfoEx.ProcessGetter = interceptionDelegates.ProcessGetterNoAction;
                    }
                    else
                    {
                        propertyInfoEx.ProcessGetter = interceptionDelegates.ProcessGetterNoAction;
                    }

                    //We Assign the corresponding setter Action

                    if (isVisibleStateFlag)
                    {
                        //This is a special process setter for handling property VisibleState of ControlBase or FormBase
                        propertyInfoEx.ProcessSetter = interceptionDelegates.ProcessSetterVisibleState;
                    }
                    else if (propertyInfoEx.isObjectPropertyType)
                    {
                        propertyInfoEx.ProcessSetter = interceptionDelegates.ProcessSetterObjectReference;
                    }
                    else if (propertyInfoEx.hasSurrogate)
                    {
                        propertyInfoEx.ProcessSetter = interceptionDelegates.ProcessSetterSurrogate;
                    }
                    else if (isStrongReference)
                    {
                        propertyInfoEx.ProcessSetter = interceptionDelegates.ProcessSetterStrongReference;
                    }
                    else if (propertyInfoEx.hasReferenceAttribute)
                    {
                        propertyInfoEx.ProcessSetter = interceptionDelegates.ProcessSetterWeakReference;
                    }
                    else if (!propertyInfoEx.hasReferenceAttribute && !propertyInfoEx.hasSurrogate)
                    {
                        if (propertyInfoEx.prop.PropertyType.IsValueType || propertyInfoEx.prop.PropertyType == typeof(string))
                        {
                            propertyInfoEx.ProcessSetter = interceptionDelegates.ProcessSetterSimpleTypes;
                        }
                        else if (isAssignableFromILogicWithViewModel_IViewModel)
                        {
                            propertyInfoEx.ProcessSetter = interceptionDelegates.ProcessSetterSimpleTypes;
                        }
                        else
                        {
                            if (propertyInfoEx.prop.PropertyType.IsClass && !typeof(IStateObject).IsAssignableFrom(propertyInfoEx.prop.PropertyType))
                            {
                                propertyInfoEx.ProcessSetter = interceptionDelegates.ProcessSetterSimpleTypes;
                            }
                            else
                            {
                                propertyInfoEx.ProcessSetter = interceptionDelegates.ProcessSetterMostCases;
                            }
                        }
                    }
                    RegisterProperty(propertyInfoEx, properties, hasIndexParameters);

#if DEBUG
                    if (ViewModelAnalysis)
                    {
                        if (!typeof(IInternalData).IsAssignableFrom(type))
                        {
                            if (propertyType.IsInterface &&
                                //!propertyInfoEx.isAnIListOfSomethingThatImplementsIStateObject &&
                                !isAssignableFromIIocContainer &&
                                !isAssignableFromIViewManager &&
                                !propertyInfoEx.isAssignableFromIDependantStateObject &&
                                !(propertyInfoEx.isAnIList && isASupportedValueTypeForIList) &&
                                !isAssignableFromIModel &&
                                !typeof(IViewModel).IsAssignableFrom(propertyType))
                            {
                                var improperType = type;
                                if (improperType.Assembly.IsDynamic)
                                {
                                    improperType = improperType.BaseType;
                                }
                                Dictionary <string, Type> improperTypeTable;
                                if (!ImproperTypes.TryGetValue(improperType, out improperTypeTable))
                                {
                                    ImproperTypes[improperType] = improperTypeTable = new Dictionary <string, Type>();
                                }
                                improperTypeTable[prop.Name] = propertyType;
                            }
                            else if (propertyType == typeof(object) && !propertyInfoEx.hasReferenceAttribute)
                            {
                                var warningType = type;
                                if (warningType.Assembly.IsDynamic)
                                {
                                    warningType = warningType.BaseType;
                                }
                                Dictionary <string, Type> warningTypeTable;
                                if (!WarningTypes.TryGetValue(warningType, out warningTypeTable))
                                {
                                    WarningTypes[warningType] = warningTypeTable = new Dictionary <string, Type>();
                                }
                                warningTypeTable[prop.Name] = propertyType;
                            }
                        }
                    }
#endif
                }
                ////for loop is faster, but cannot iterate on the dictionary
                //foreach (var item in properties)
                //{
                //    tuple2.Add(item.Key, item.Value.propertyPositionIndex);

                //    bitArrayMappedTable[item.Value.propertyPositionIndex] = item.Value;
                //}
                //cache with position
                properties.PropertiesList = properties.PropertiesList.ToArray();
                cachePropertiesEx.Add(type, properties);
            }
        }