microsoft-azure-storage/src/com/microsoft/azure/storage/table/PropertyPair.java
private static HashMap<String, PropertyPair> generatePropertyPairsHelper(final Class<?> clazzType) {
        final Method[] methods = clazzType.getMethods();
        final HashMap<String, PropertyPair> propMap = new HashMap<String, PropertyPair>();

        String propName = null;
        PropertyPair currProperty = null;

        for (final Method m : methods) {
            if (m.getName().length() < 4 || (!m.getName().startsWith("get") && !m.getName().startsWith("set"))) {
                continue;
            }

            propName = m.getName().substring(3);

            // Skip interface methods, these will be called explicitly
            if (propName.equals(TableConstants.PARTITION_KEY) || propName.equals(TableConstants.ROW_KEY)
                    || propName.equals(TableConstants.TIMESTAMP) || propName.equals("Etag")
                    || propName.equals("LastModified")) {
                continue;
            }

            if (propMap.containsKey(propName)) {
                currProperty = propMap.get(propName);
            }
            else {
                currProperty = new PropertyPair();
                currProperty.name = propName;
                propMap.put(propName, currProperty);
            }

            if (m.getName().startsWith("get") && m.getParameterTypes().length == 0) {
                currProperty.type = m.getReturnType();
                currProperty.getter = m;
            }
            else if (m.getName().startsWith("set") && m.getParameterTypes().length == 1
                    && void.class.equals(m.getReturnType())) {
                currProperty.setter = m;
            }

            // Check for StoreAs Annotation
            final StoreAs storeAsInstance = m.getAnnotation(StoreAs.class);
            if (storeAsInstance != null) {
                if (Utility.isNullOrEmpty(storeAsInstance.name())) {
                    throw new IllegalArgumentException(String.format(SR.STOREAS_USED_ON_EMPTY_PROPERTY,
                            currProperty.name));
                }

                if (currProperty.effectiveName != null && !currProperty.effectiveName.equals(currProperty.name)
                        && !currProperty.effectiveName.equals(storeAsInstance.name())) {
                    throw new IllegalArgumentException(String.format(SR.STOREAS_DIFFERENT_FOR_GETTER_AND_SETTER,
                            currProperty.name));
                }

                if (!currProperty.name.equals(storeAsInstance.name())) {
                    currProperty.effectiveName = storeAsInstance.name();
                }
            }
        }

        // Return only processable pairs
        final ArrayList<String> keysToRemove = new ArrayList<String>();
        final ArrayList<String> keysToAlter = new ArrayList<String>();

        for (final Entry<String, PropertyPair> e : propMap.entrySet()) {
            if (!e.getValue().shouldProcess()) {
                keysToRemove.add(e.getKey());
                continue;
            }

            if (!Utility.isNullOrEmpty(e.getValue().effectiveName)) {
                keysToAlter.add(e.getKey());
            }
            else {
                e.getValue().effectiveName = e.getValue().name;
            }
        }

        // remove all entries for keys that should not process
        for (final String key : keysToRemove) {
            propMap.remove(key);
        }

        // Any store as properties should be re-stored into the hash under the efective name.
        for (final String key : keysToAlter) {
            final PropertyPair p = propMap.get(key);
            propMap.remove(key);
            propMap.put(p.effectiveName, p);
        }

        return propMap;
    }
private static HashMap<String, PropertyPair> generatePropertyPairsHelper(final Class<?> clazzType) {
        final Method[] methods = clazzType.getMethods();
        final HashMap<String, PropertyPair> propMap = new HashMap<String, PropertyPair>();

        String propName = null;
        PropertyPair currProperty = null;

        for (final Method m : methods) {
            if (m.getName().length() < 4 || (!m.getName().startsWith("get") && !m.getName().startsWith("set"))) {
                continue;
            }

            propName = m.getName().substring(3);

            // Skip interface methods, these will be called explicitly
            if (propName.equals(TableConstants.PARTITION_KEY) || propName.equals(TableConstants.ROW_KEY)
                    || propName.equals(TableConstants.TIMESTAMP) || propName.equals("Etag")
                    || propName.equals("LastModified")) {
                continue;
            }

            if (propMap.containsKey(propName)) {
                currProperty = propMap.get(propName);
            }
            else {
                currProperty = new PropertyPair();
                currProperty.name = propName;
                propMap.put(propName, currProperty);
            }

            if (m.getName().startsWith("get") && m.getParameterTypes().length == 0) {
                currProperty.type = m.getReturnType();
                currProperty.getter = m;
            }
            else if (m.getName().startsWith("set") && m.getParameterTypes().length == 1
                    && void.class.equals(m.getReturnType())) {
                currProperty.setter = m;
            }

            // Check for StoreAs Annotation
            final StoreAs storeAsInstance = m.getAnnotation(StoreAs.class);
            if (storeAsInstance != null) {
                if (Utility.isNullOrEmpty(storeAsInstance.name())) {
                    throw new IllegalArgumentException(String.format(SR.STOREAS_USED_ON_EMPTY_PROPERTY,
                            currProperty.name));
                }

                if (currProperty.effectiveName != null && !currProperty.effectiveName.equals(currProperty.name)
                        && !currProperty.effectiveName.equals(storeAsInstance.name())) {
                    throw new IllegalArgumentException(String.format(SR.STOREAS_DIFFERENT_FOR_GETTER_AND_SETTER,
                            currProperty.name));
                }

                if (!currProperty.name.equals(storeAsInstance.name())) {
                    currProperty.effectiveName = storeAsInstance.name();
                }
            }
        }

        // Return only processable pairs
        final ArrayList<String> keysToRemove = new ArrayList<String>();
        final ArrayList<String> keysToAlter = new ArrayList<String>();

        for (final Entry<String, PropertyPair> e : propMap.entrySet()) {
            if (!e.getValue().shouldProcess()) {
                keysToRemove.add(e.getKey());
                continue;
            }

            if (!Utility.isNullOrEmpty(e.getValue().effectiveName)) {
                keysToAlter.add(e.getKey());
            }
            else {
                e.getValue().effectiveName = e.getValue().name;
            }
        }

        // remove all entries for keys that should not process
        for (final String key : keysToRemove) {
            propMap.remove(key);
        }

        // Any store as properties should be re-stored into the hash under the efective name.
        for (final String key : keysToAlter) {
            final PropertyPair p = propMap.get(key);
            propMap.remove(key);
            propMap.put(p.effectiveName, p);
        }

        return propMap;
    }
Reserved for internal use. A static factory method to generate a map of property names to {@link PropertyPair}
instances for the specified class type. Uses reflection to find pairs of getter and setter methods that are
annotated with {@link StoreAs} with a common property name, or of the form <code>get<em>PropertyName</em></code>
and <code>set<em>PropertyName</em></code>, with a common type for the getter return value and the
setter parameter, and stores the methods and the property name for each pair found in a map for use in
serializing and deserializing entity data.

@param clazzType
The class type to check for matching getter and setter methods with a common return and parameter
type, respectively.