class BeanQueryMapEncoder implements QueryMapEncoder {

  @Override
  public Map<String, Object> encode(Object object) throws EncodeException {
    try {
      ObjectParamMetadata metadata = getMetadata(object.getClass());
      Map<String, Object> propertyNameToValue = new HashMap<String, Object>();
      for (PropertyDescriptor pd : metadata.objectProperties) {
        Method method = pd.getReadMethod();
        Object value = method.invoke(object);
        if (value != null && value != object) {
          Param alias = method.getAnnotation(Param.class);
          String name = alias != null ? alias.value() : pd.getName();
          propertyNameToValue.put(name, value);
        }
      }
      return propertyNameToValue;
    } catch (IllegalAccessException | IntrospectionException | InvocationTargetException e) {
      throw new EncodeException("Failure encoding object into query map", e);
    }
  }

}