class NoConstructor {
        /** Constructor for NoConstructor class. */
        @SuppressWarnings("unused")
        public NoConstructor() {
            // Empty
        }
    }

    /**
     * Create a class field cache.
     * 
     * @param forDeserialization
     *            Set this to true if the cache will be used for deserialization (or both serialization and
     *            deserialization), or false if just used for serialization (for speed).
     * @param onlySerializePublicFields
     *            Set this to true if you only want to serialize public fields (ignored for deserialization).
     */
    ClassFieldCache(final boolean forDeserialization, final boolean onlySerializePublicFields,
            final ReflectionUtils reflectionUtils) {
        this.resolveTypes = forDeserialization;
        this.onlySerializePublicFields = !forDeserialization && onlySerializePublicFields;
        this.reflectionUtils = reflectionUtils;
    }

    /**
     * For a given resolved type, find the visible and accessible fields, resolve the types of any generically typed
     * fields, and return the resolved fields.
     *
     * @param cls
     *            the cls
     * @return the class fields
     */
    ClassFields get(final Class<?> cls) {
        ClassFields classFields = classToClassFields.get(cls);
        if (classFields == null) {
            classToClassFields.put(cls, classFields = new ClassFields(cls, resolveTypes, onlySerializePublicFields,
                    this, reflectionUtils));
        }
        return classFields;
    }

    /**
     * Get the concrete type for a map or collection whose raw type is an interface or abstract class.
     *
     * @param rawType
     *            the raw type
     * @param returnNullIfNotMapOrCollection
     *            return null if not map or collection
     * @return the concrete type
     */
    private static Class<?> getConcreteType(final Class<?> rawType, final boolean returnNullIfNotMapOrCollection) {
        // This list is not complete (e.g. EnumMap cannot be instantiated directly, you need to pass the
        // enum key type into a factory method), but this should cover a lot of the common types
        if (rawType == Map.class || rawType == AbstractMap.class || rawType == HashMap.class) {
            return HashMap.class;
        } else if (rawType == ConcurrentMap.class || rawType == ConcurrentHashMap.class) {
            return ConcurrentHashMap.class;
        } else if (rawType == SortedMap.class || rawType == NavigableMap.class || rawType == TreeMap.class) {
            return TreeMap.class;
        } else if (rawType == ConcurrentNavigableMap.class || rawType == ConcurrentSkipListMap.class) {
            return ConcurrentSkipListMap.class;
        } else if (rawType == List.class || rawType == AbstractList.class || rawType == ArrayList.class
                || rawType == Collection.class) {
            return ArrayList.class;
        } else if (rawType == AbstractSequentialList.class || rawType == LinkedList.class) {
            return LinkedList.class;
        } else if (rawType == Set.class || rawType == AbstractSet.class || rawType == HashSet.class) {
            return HashSet.class;
        } else if (rawType == SortedSet.class || rawType == TreeSet.class) {
            return TreeSet.class;
        } else if (rawType == Queue.class || rawType == AbstractQueue.class || rawType == Deque.class
                || rawType == ArrayDeque.class) {
            return ArrayDeque.class;
        } else if (rawType == BlockingQueue.class || rawType == LinkedBlockingQueue.class) {
            return LinkedBlockingQueue.class;
        } else if (rawType == BlockingDeque.class || rawType == LinkedBlockingDeque.class) {
            return LinkedBlockingDeque.class;
        } else if (rawType == TransferQueue.class || rawType == LinkedTransferQueue.class) {
            return LinkedTransferQueue.class;
        } else {
            return returnNullIfNotMapOrCollection ? null : rawType;
        }
    }

    /**
     * Get the concrete type of the given class, then return the default constructor for that type.
     *
     * @param cls
     *            the class
     * @return the default constructor for concrete type of class
     * @throws IllegalArgumentException
     *             if no default constructor is both found and accessible.
     */
    Constructor<?> getDefaultConstructorForConcreteTypeOf(final Class<?> cls) {<FILL_FUNCTION_BODY>

        if (cls == null) {
            throw new IllegalArgumentException("Class reference cannot be null");
        }
        // Check cache
        final Constructor<?> constructor = defaultConstructorForConcreteType.get(cls);
        if (constructor != null) {
            return constructor;
        }
        final Class<?> concreteType = getConcreteType(cls, /* returnNullIfNotMapOrCollection = */ false);
        for (Class<?> c = concreteType; c != null
                && (c != Object.class || cls == Object.class); c = c.getSuperclass()) {
            try {
                final Constructor<?> defaultConstructor = c.getDeclaredConstructor();
                JSONUtils.makeAccessible(defaultConstructor, reflectionUtils);
                // Store found constructor in cache
                defaultConstructorForConcreteType.put(cls, defaultConstructor);
                return defaultConstructor;
            } catch (final ReflectiveOperationException | SecurityException e) {
                // Ignore
            }
        }
        throw new IllegalArgumentException("Class " + cls.getName() //
                + " does not have an accessible default (no-arg) constructor");
    
<no_super_class>