internal static DynamicPropertyDescriptorByField GetPopulateCache(
            CopyOnWriteList <DynamicPropertyDescriptorByField> cache,
            DynamicPropertyGetterByFieldBase dynamicPropertyGetterBase,
            object obj,
            EventBeanTypedEventFactory eventBeanTypedEventFactory)
        {
            var desc = DynamicPropertyCacheCheck(cache, obj);

            if (desc != null)
            {
                return(desc);
            }

            // need to add it
            lock (dynamicPropertyGetterBase) {
                desc = DynamicPropertyCacheCheck(cache, obj);
                if (desc != null)
                {
                    return(desc);
                }

                // Lookup method to use
                var field = dynamicPropertyGetterBase.DetermineField(obj.GetType());

                // Cache descriptor and create field
                desc = DynamicPropertyCacheAdd(obj.GetType(), field, cache);
                return(desc);
            }
        }
        /// <summary>
        /// NOTE: Code-generation-invoked method, method name and parameter order matters
        /// </summary>
        /// <param name="cache">cache</param>
        /// <param name="getter">getter</param>
        /// <param name="object">object</param>
        /// <param name="eventBeanTypedEventFactory">event server</param>
        /// <returns>exists-flag</returns>
        public static bool CacheAndExists(
            CopyOnWriteList <DynamicPropertyDescriptorByField> cache,
            DynamicPropertyGetterByFieldBase getter,
            object @object,
            EventBeanTypedEventFactory eventBeanTypedEventFactory)
        {
            var desc = GetPopulateCache(cache, getter, @object, eventBeanTypedEventFactory);

            if (desc.Field == null)
            {
                return(false);
            }

            return(true);
        }
        /// <summary>
        /// NOTE: Code-generation-invoked method, method name and parameter order matters
        /// </summary>
        /// <param name="cache">cache</param>
        /// <param name="getter">getter</param>
        /// <param name="object">object</param>
        /// <param name="eventBeanTypedEventFactory">event server</param>
        /// <param name="beanEventTypeFactory">bean factory</param>
        /// <returns>property</returns>
        public static object CacheAndCall(
            CopyOnWriteList <DynamicPropertyDescriptorByField> cache,
            DynamicPropertyGetterByFieldBase getter,
            object @object,
            EventBeanTypedEventFactory eventBeanTypedEventFactory,
            BeanEventTypeFactory beanEventTypeFactory)
        {
            var desc = GetPopulateCache(cache, getter, @object, eventBeanTypedEventFactory);

            if (desc.Field == null)
            {
                return(null);
            }

            return(getter.Call(desc, @object));
        }