public T Convert<T> (string stringValue, int supportedTypeIndex)
 {
     T value = default (T);
     ConversionRule conversionRule = null;
     lock (_mapSyncRoot)
     {
         if ((supportedTypeIndex > 0) && 
             (supportedTypeIndex < _map.Count))
         {
             if (_map[supportedTypeIndex].SupportedType == typeof (T))
             {
                 conversionRule = _map[supportedTypeIndex];
             }
             else 
             {
                 // oh nos! someone supplied a bad index! or type!
             }
         }
         else 
         {
             // arg, definitely a bad index
         }
     }
     object untypedValue = null;
     try
     {
         untypedValue = conversionRule.Conversion (stringValue);
     }
     // alright, catching all exceptions is bad, but how do you constrain
     // or set reasonable expectations on a user-submitted lambda expression?
     catch (Exception exception)
     {
         throw new ArgumentException (
             string.Format (
             "Cannot convert type [{0}] with value [{1}] to type [{2}]." + 
             " Converter threw exception.",
             stringValue.GetType (),
             stringValue,
             typeof (T)),
             exception);
     }
     // NOTE: proper use of `is` operator
     if (untypedValue is T)
     {
         value = (T)(untypedValue);
     }
     else
     {
         // i think you know what to do ;)
     }
     return value;
 }