private static T CreateTypedObject <T>(DataRow row, CultureInfo culture, IEnumerable <ValueConverterDefinition> converterDefinitions)
        {
            var obj = Activator.CreateInstance <T>();

            var objType         = obj.GetType();
            var dataMemberProps = objType.GetProperties()
                                  .Where(p => Attribute.IsDefined(p, typeof(DataMemberAttribute)))
                                  .ToList();

            var dataFieldsProps = objType.GetProperties()
                                  .Where(p => Attribute.IsDefined(p, typeof(DataFieldAttribute)))
                                  .ToList();

            foreach (DataColumn column in row.Table.Columns)
            {
                bool isRequired = false;

                // get the property
                var property = objType.GetProperty(column.ColumnName.Trim(), BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

                if (property == null && dataFieldsProps.Any())
                {
                    // look for [DataField] attribute
                    property = dataFieldsProps.FirstOrDefault(p => ((DataFieldAttribute)Attribute.GetCustomAttribute(p, typeof(DataFieldAttribute))).Name == column.ColumnName);
                    if (property != null)
                    {
                        isRequired = ((DataFieldAttribute)Attribute.GetCustomAttribute(property, typeof(DataFieldAttribute))).IsRequired;
                    }
                }

                if (property == null && dataMemberProps.Any())
                {
                    // otherwise look for [DataMember] attribute
                    property = dataMemberProps.FirstOrDefault(p => ((DataMemberAttribute)Attribute.GetCustomAttribute(p, typeof(DataMemberAttribute))).Name == column.ColumnName);
                    if (property != null)
                    {
                        isRequired = ((DataMemberAttribute)Attribute.GetCustomAttribute(property, typeof(DataMemberAttribute))).IsRequired;
                    }
                }

                if (property != null)
                {
                    object value = row[column.ColumnName];

                    if (value == null && isRequired)
                    {
                        // When required but null, throw
                        throw new NoNullAllowedException(column.ColumnName);
                    }
                    else
                    {
                        // when converters exits convert the value
                        if (converterDefinitions != null)
                        {
                            foreach (var converterDef in converterDefinitions.Where(x => x.FieldName == column.ColumnName))
                            {
                                value = converterDef.Converter.Convert(value, property.PropertyType, converterDef.ConverterParameter, culture);
                            }
                        }

                        object tgtValue = ConvertExtensions.ChangeTypeExtended(value, property.PropertyType, culture);

                        property.SetValue(obj, tgtValue, null);
                    }
                }
            }
            return(obj);
        }