public boolean equals(Object other) {
        if (other instanceof TypeName) {
            if (super.equals(other)) {
                // check types
                boolean valid = false;
                if (mType == null) {
                    valid = (null == ((TypeName)other).getType());
                }
                else {
                    valid = mType.equals(((TypeName)other).getType());
                }

                if (!valid) { return false; }

                // check generics
                TypeName[] genericTypes = ((TypeName)other).getGenericTypes();
                if (mGenericTypes == null) {
                    valid = (null == genericTypes);
                }
                else if (genericTypes == null) {
                    valid = false;
                }
                else if (genericTypes.length != mGenericTypes.length) {
                    valid = false;
                }
                else {
                    valid = true;
                    for (int i = 0; i < genericTypes.length; i++) {
                        valid = mGenericTypes[i].equals(genericTypes[i]);
                        if (!valid) { break; }
                    }
                }

                // return state
                return valid;
            }
        }

        return false;
    }