private static Map<String, Method> getGetters(Method[] methods) {
        Map<String, List<Method>> getters = new HashMap<>();
        Map<String, List<Method>> setters = new HashMap<>();

        for (Method m : methods) {
            String name = m.getName();
            if (name.startsWith("get") && name.length() > 3 && Character.isUpperCase(name.charAt(3))) {
                String param = getParam(GET, name);
                add(param, m, getters);
            } else if (name.startsWith("is") && name.length() > 2 && Character.isUpperCase(name.charAt(2))) {
                String param = getParam(IS, name);
                add(param, m, getters);
            } else if (name.startsWith("set") && name.length() > 3 && Character.isUpperCase(name.charAt(3))) {
                //take only single param setters
                if (m.getParameters().length == 1) {
                    String param = getParam(SET, name);
                    add(param, m, setters);
                }
            }
        }
        //this strictly looks for classA.equals(classB)
        //this does not look for instance of, nor does it look for boxed vs. primitives
        //Also, TODO -- this should favor getters and setters with Strings over those
        //with complex types
        Map<String, Method> ret = new HashMap<>();
        for (Map.Entry<String, List<Method>> e : getters.entrySet()) {
            String paramName = e.getKey();
            //figure out how to skip Class level setters/getters
            if ("class".equals(paramName)) {
                continue;
            }
            List<Method> setterList = setters.get(paramName);
            if (setterList == null || setterList.size() == 0) {
                LOG.debug("Couldn't find setter for getter: " + paramName);
                continue;
            }
            for (Method getter : e.getValue()) {
                for (Method setter : setterList) {
                    Class setClass = setter.getParameters()[0].getType();
                    if (getter
                            .getReturnType()
                            .equals(setClass)) {
                        ret.put(paramName, getter);
                    }
                }
            }
        }
        return ret;
    }
@param fieldName     can be null -- used only for logging and debugging
@param obj
@param jsonGenerator
@throws TikaSerializationException
tika-serialization/src/main/java/org/apache/tika/serialization/TikaJsonSerializer.java