/// <summary>
        /// Modifies the target data before passing it to the source object.  This method is called only in <see cref="F:System.Windows.Data.BindingMode.TwoWay" /> bindings.
        /// </summary>
        /// <param name="value">The target data being passed to the source.</param>
        /// <param name="targetType">The <see cref="T:System.Type" /> of data expected by the source object.</param>
        /// <param name="parameter">An optional parameter to be used in the converter logic.</param>
        /// <param name="culture">The culture of the conversion.</param>
        /// <returns>The value to be passed to the source object.</returns>
        object IValueConverter.ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            var converter = Converter;

            if (converter == null) return value;

            var converterParameter = ConverterParameter;
            SourceValuesErrors = null;
            try
            {
                var multiValueConverter = converter as IMultiValueConverter;
                if (multiValueConverter != null)
                {
                    // Guess target types based on current source values
                    var targetTypes = new Type[m_sourceCount];
                    for (var i = 0; i < targetTypes.Length; i++)
                    {
                        var currentValue = Target.GetValue(dataProperties[m_sourceStartIndex + i]);
                        targetTypes[i] = currentValue != null ? currentValue.GetType() : typeof(Object);
                    }

                    var convertedValues = multiValueConverter.ConvertBack(value, targetTypes, converterParameter, culture);

                    return convertedValues;
                }


                var valueConverter = converter as IValueConverter;
                if (valueConverter != null)
                {
                    var convertedValue = valueConverter.ConvertBack(value, targetType, converterParameter, culture);
                    return convertedValue != DependencyProperty.UnsetValue ? new object[] { convertedValue } : convertedValue;
                }
            }
            catch (Exception ex)
            {

                SourceValuesErrors = new MultiBindingValidationError[] { new MultiBindingValidationError(ex) };
                if (MultiBinding.ValidatesOnExceptions)
                {
                    return DependencyProperty.UnsetValue;
                }
                throw;
            }

            return value;
        }
        /// <summary>
        /// Modifies the source data before passing it to the target for display in the UI.
        /// </summary>
        /// <param name="value">The source data being passed to the target.</param>
        /// <param name="targetType">The <see cref="T:System.Type" /> of data expected by the target dependency property.</param>
        /// <param name="parameter">An optional parameter to be used in the converter logic.</param>
        /// <param name="culture">The culture of the conversion.</param>
        /// <returns>The value to be passed to the target dependency property.</returns>
        object IValueConverter.Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value == null) return DependencyProperty.UnsetValue;
            var unconvertedValues = (object[])value;
            var converter = Converter;

            object result = unconvertedValues;
            if (converter != null)
            {
                var converterParameter = ConverterParameter;
                SourceValuesErrors = null;
                try
                {
                    var multiConverter = converter as IMultiValueConverter;
                    if (multiConverter != null)
                    {
                        result = multiConverter.Convert(unconvertedValues, targetType, converterParameter, culture);
                    }
                    else
                    {
                        var singleConverter = converter as IValueConverter;
                        if (singleConverter != null)
                        {
                            result = singleConverter.Convert(unconvertedValues[0], targetType, converterParameter, culture);
                        }
                    }
                }
                catch (Exception ex)
                {

                    SourceValuesErrors = new MultiBindingValidationError[] { new MultiBindingValidationError(ex) };
                    if (MultiBinding.ValidatesOnExceptions)
                    {
                        return DependencyProperty.UnsetValue;
                    }
                    throw;
                }

            }


            if (result != DependencyProperty.UnsetValue)
            {

                var format = StringFormat;
                if (format != null)
                {
                    format = Regex.Replace(format, @"%(\d+)", "{$1}");
                    if (result is Object[])
                    {
                        result = String.Format(culture, format, result);
                    }
                    else
                    {
                        result = String.Format(culture, format, result);
                    }
                }
            }
            return result;
        }