@Override
 public PropertyWidget<?> create(String propertyName) {
   ComponentDescriptor<?> descriptor = _componentBuilder.getDescriptor();
   ConfiguredPropertyDescriptor propertyDescriptor =
       descriptor.getConfiguredProperty(propertyName);
   if (propertyDescriptor == null) {
     throw new IllegalArgumentException("No such property: " + propertyName);
   }
   return create(propertyDescriptor);
 }
  @Inject
  protected PropertyWidgetFactoryImpl(ComponentBuilder componentBuilder, DCModule dcModule) {
    _componentBuilder = componentBuilder;
    _dcModule = dcModule;
    _propertyWidgetCollection = new PropertyWidgetCollection(componentBuilder);

    final Set<ConfiguredPropertyDescriptor> mappedProperties =
        componentBuilder.getDescriptor().getConfiguredPropertiesByAnnotation(MappedProperty.class);
    for (ConfiguredPropertyDescriptor mappedProperty : mappedProperties) {
      MappedProperty annotation = mappedProperty.getAnnotation(MappedProperty.class);
      String mappedToName = annotation.value();
      ConfiguredPropertyDescriptor mappedToProperty =
          componentBuilder.getDescriptor().getConfiguredProperty(mappedToName);

      PropertyWidgetMapping propertyWidgetMapping =
          buildMappedPropertyWidget(mappedProperty, mappedToProperty);

      _propertyWidgetCollection.putMappedPropertyWidget(mappedProperty, propertyWidgetMapping);
      _propertyWidgetCollection.putMappedPropertyWidget(mappedToProperty, propertyWidgetMapping);
    }
  }
  /**
   * Creates (and registers) a widget that fits the specified configured property.
   *
   * @param propertyDescriptor
   * @return
   */
  @Override
  public PropertyWidget<?> create(ConfiguredPropertyDescriptor propertyDescriptor) {
    // first check if there is a mapping created for this property
    // descriptor
    PropertyWidget<?> propertyWidget =
        _propertyWidgetCollection.getMappedPropertyWidget(propertyDescriptor);
    if (propertyWidget != null) {
      return propertyWidget;
    }
    final HiddenProperty hiddenProperty = propertyDescriptor.getAnnotation(HiddenProperty.class);
    if (hiddenProperty != null && hiddenProperty.hiddenForLocalAccess()) {
      return null;
    }
    if (propertyDescriptor.getAnnotation(Deprecated.class) != null) {
      return null;
    }

    if (getComponentBuilder() instanceof AnalyzerComponentBuilder) {
      AnalyzerComponentBuilder<?> analyzer = (AnalyzerComponentBuilder<?>) getComponentBuilder();
      if (analyzer.isMultipleJobsSupported()) {
        if (analyzer.isMultipleJobsDeterminedBy(propertyDescriptor)) {
          final MultipleInputColumnsPropertyWidget result =
              new MultipleInputColumnsPropertyWidget(analyzer, propertyDescriptor);
          return result;
        }
      }
    }

    // check for fitting property widgets by type
    final Class<?> type = propertyDescriptor.getBaseType();

    final Class<? extends PropertyWidget<?>> widgetClass;
    if (propertyDescriptor.isArray()) {
      if (propertyDescriptor.isInputColumn()) {
        widgetClass = MultipleInputColumnsPropertyWidget.class;
      } else if (ReflectionUtils.isString(type)) {
        widgetClass = MultipleStringPropertyWidget.class;
      } else if (type == Dictionary.class) {
        widgetClass = MultipleDictionariesPropertyWidget.class;
      } else if (type == SynonymCatalog.class) {
        widgetClass = MultipleSynonymCatalogsPropertyWidget.class;
      } else if (type == StringPattern.class) {
        widgetClass = MultipleStringPatternPropertyWidget.class;
      } else if (type == EnumerationValue.class
          && propertyDescriptor instanceof EnumerationProvider) {
        widgetClass = MultipleRemoteEnumPropertyWidget.class;
      } else if (type.isEnum()) {
        widgetClass = MultipleEnumPropertyWidget.class;
      } else if (type == Class.class) {
        widgetClass = MultipleClassesPropertyWidget.class;
      } else if (type == char.class) {
        widgetClass = MultipleCharPropertyWidget.class;
      } else if (ReflectionUtils.isNumber(type)) {
        widgetClass = MultipleNumberPropertyWidget.class;
      } else {
        // not yet implemented
        widgetClass = DummyPropertyWidget.class;
      }
    } else {

      if (propertyDescriptor.isInputColumn()) {
        if (_componentBuilder
                .getDescriptor()
                .getConfiguredPropertiesByType(InputColumn.class, true)
                .size()
            == 1) {
          // if there is only a single input column property, it
          // will
          // be displayed using radiobuttons.
          widgetClass = SingleInputColumnRadioButtonPropertyWidget.class;
        } else {
          // if there are multiple input column properties, they
          // will
          // be displayed using combo boxes.
          widgetClass = SingleInputColumnComboBoxPropertyWidget.class;
        }
      } else if (ReflectionUtils.isCharacter(type)) {
        widgetClass = SingleCharacterPropertyWidget.class;
      } else if (ReflectionUtils.isString(type)) {
        widgetClass = SingleStringPropertyWidget.class;
      } else if (ReflectionUtils.isBoolean(type)) {
        widgetClass = SingleBooleanPropertyWidget.class;
      } else if (ReflectionUtils.isNumber(type)) {
        widgetClass = SingleNumberPropertyWidget.class;
      } else if (ReflectionUtils.isDate(type)) {
        widgetClass = SingleDatePropertyWidget.class;
      } else if (type == Dictionary.class) {
        widgetClass = SingleDictionaryPropertyWidget.class;
      } else if (type == SynonymCatalog.class) {
        widgetClass = SingleSynonymCatalogPropertyWidget.class;
      } else if (type == StringPattern.class) {
        widgetClass = SingleStringPatternPropertyWidget.class;
      } else if (type == EnumerationValue.class
          && propertyDescriptor instanceof EnumerationProvider) {
        widgetClass = SingleRemoteEnumPropertyWidget.class;
      } else if (type.isEnum()) {
        widgetClass = SingleEnumPropertyWidget.class;
      } else if (ReflectionUtils.is(type, Resource.class)) {
        widgetClass = SingleResourcePropertyWidget.class;
      } else if (type == File.class) {
        widgetClass = SingleFilePropertyWidget.class;
      } else if (type == Pattern.class) {
        widgetClass = SinglePatternPropertyWidget.class;
      } else if (ReflectionUtils.is(type, Datastore.class)) {
        widgetClass = SingleDatastorePropertyWidget.class;
      } else if (type == Class.class) {
        widgetClass = SingleClassPropertyWidget.class;
      } else if (type == Map.class) {
        final Class<?> genericType1 = propertyDescriptor.getTypeArgument(0);
        final Class<?> genericType2 = propertyDescriptor.getTypeArgument(1);
        if (genericType1 == String.class && genericType2 == String.class) {
          widgetClass = MapStringToStringPropertyWidget.class;
        } else {
          // not yet implemented
          widgetClass = DummyPropertyWidget.class;
        }
      } else {
        // not yet implemented
        widgetClass = DummyPropertyWidget.class;
      }
    }

    final Injector injector = getInjectorForPropertyWidgets(propertyDescriptor);
    final PropertyWidget<?> result = injector.getInstance(widgetClass);
    return result;
  }