class ItemStateConverterImpl implements ItemStateConverter {

    @Override
    public State convertToAcceptedState(@Nullable State state, @Nullable Item item) {
        if (state == null) {
            logger.error("A conversion of null was requested:",
                    new IllegalArgumentException("State must not be null."));
            return UnDefType.NULL;
        }

        if (item != null && !isAccepted(item, state)) {
            for (Class<? extends State> acceptedType : item.getAcceptedDataTypes()) {
                State convertedState = state.as(acceptedType);
                if (convertedState != null) {
                    logger.debug("Converting {} '{}' to {} '{}' for item '{}'", state.getClass().getSimpleName(), state,
                            convertedState.getClass().getSimpleName(), convertedState, item.getName());
                    return convertedState;
                }
            }
        }

        if (item instanceof NumberItem && state instanceof QuantityType) {
            NumberItem numberItem = (NumberItem) item;
            if (numberItem.getDimension() != null) {
                QuantityType<?> quantityState = (QuantityType<?>) state;

                // in case the item does define a unit it takes precedence over all other conversions:
                Unit<?> itemUnit = parseItemUnit(numberItem);
                if (itemUnit != null) {
                    if (!itemUnit.equals(quantityState.getUnit())) {
                        return convertOrUndef(quantityState, itemUnit);
                    }

                    return quantityState;
                }

                Class<? extends Quantity<?>> dimension = numberItem.getDimension();
                @SuppressWarnings({ "unchecked", "rawtypes" })
                // explicit cast to Class<? extends Quantity> as JDK compiler complains
                Unit<? extends Quantity<?>> conversionUnit = unitProvider
                        .getUnit((Class<? extends Quantity>) dimension);
                if (conversionUnit != null
                        && UnitUtils.isDifferentMeasurementSystem(conversionUnit, quantityState.getUnit())) {
                    return convertOrUndef(quantityState, conversionUnit);
                }

                return state;
            } else {
                State convertedState = state.as(DecimalType.class);
                if (convertedState != null) {
                    // convertedState is always returned because the state is an instance
                    // of QuantityType which never returns null for as(DecimalType.class)
                    return convertedState;
                }
            }
        }

        return state;
    }

    @Activate public  ItemStateConverterImpl(final @Reference UnitProvider unitProvider);

}