public static <B> BeanPropertyMapFactory<B> forClass(Class<B> clazz) {
        synchronized (cFactories) {
            BeanPropertyMapFactory factory;
            SoftReference<BeanPropertyMapFactory> ref = cFactories.get(clazz);
            if (ref != null) {
                factory = ref.get();
                if (factory != null) {
                    return factory;
                }
            }

            final Map<String, BeanProperty> properties = BeanIntrospector.getAllProperties(clazz);
            Map<String, BeanProperty> supportedProperties = properties;

            // Determine which properties are to be excluded.
            for (Map.Entry<String, BeanProperty> entry : properties.entrySet()) {
                BeanProperty property = entry.getValue();
                if (property.getReadMethod() == null ||
                    property.getWriteMethod() == null ||
                    BeanPropertyAccessor.throwsCheckedException(property.getReadMethod()) ||
                    BeanPropertyAccessor.throwsCheckedException(property.getWriteMethod()))
                {
                    // Exclude property.
                    if (supportedProperties == properties) {
                        supportedProperties = new HashMap<String, BeanProperty>(properties);
                    }
                    supportedProperties.remove(entry.getKey());
                }
            }

            if (supportedProperties.size() == 0) {
                factory = Empty.INSTANCE;
            } else {
                factory = new Standard<B>
                    (BeanPropertyAccessor.forClass
                     (clazz, BeanPropertyAccessor.PropertySet.READ_WRITE_UNCHECKED_EXCEPTIONS),
                     supportedProperties);
            }

            cFactories.put(clazz, new SoftReference<BeanPropertyMapFactory>(factory));
            return factory;
        }
    }