public List<Field> findOrderedFields(final Class<?> clazz) {
        List<Field> fields = orderedFields.get(clazz);

        if (fields == null) {
            fields = new ArrayList<Field>();

            Set<String> allFieldNames = new HashSet<String>();
            for (Class<?> c = clazz; c != null; c = c.getSuperclass()) {

                List<Field> newFields = new ArrayList<Field>();

                for (Field field : c.getDeclaredFields()) {
                    if (!allFieldNames.contains(field.getName()) &&
                        !Modifier.isTransient(field.getModifiers()) &&
                        !Modifier.isStatic(field.getModifiers()))
                        newFields.add(field);
                    allFieldNames.add(field.getName());
                }

                Collections.sort(newFields, new Comparator<Field>() {
                    public int compare(Field o1, Field o2) {
                        return o1.getName().compareTo(o2.getName());
                    }
                });

                fields.addAll(0, newFields);
            }

            List<Field> previousFields = orderedFields.putIfAbsent(clazz, fields);
            if (previousFields != null)
                fields = previousFields;
        }

        return fields;
    }