/**
   * Returns the adapter corresponding to a specific type.
   *
   * @param type
   * @return
   */
  public Class<? extends IAdapter> getAdapter(Class<?> type) throws AdapterInitializationException {
    // match adapter
    if (!this.adapterMap.containsKey(type)) {
      for (Map.Entry<Class<?>, Class<? extends IAdapter>> adapterEntry :
          this.adapterMap.entrySet()) {
        if (!this.isWildcardAdapter(adapterEntry.getValue())) continue;

        // get definition
        AdapterDefinition definition =
            adapterEntry.getValue().getAnnotation(AdapterDefinition.class);

        // check input
        if (definition.input().isAssignableFrom(type)) return adapterEntry.getValue();
      }
    }

    // get fallback adapter
    if (!type.isPrimitive() && !this.adapterMap.containsKey(type)) return ObjectAdapter.class;

    // verify
    if (!this.adapterMap.containsKey(type))
      throw new AdapterInitializationException(
          "Could not find the appropriate adapter for type " + type.getName());

    // return explicit adapter
    return this.adapterMap.get(type);
  }
  /** {@inheritDoc} */
  @Override
  public void registerAdapter(Class<? extends IAdapter> adapter) throws ConfigurationException {
    this.verifyAdapter(adapter);

    // get annotation
    AdapterDefinition definition = adapter.getAnnotation(AdapterDefinition.class);

    // register adapter
    this.adapterMap.put(definition.input(), adapter);
  }