/// <summary>
        /// Tries to map values from the row to the object using reflection.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="rowObj">The new object.</param>
        /// <param name="row">The row.</param>
        /// <param name="validator">The validator.</param>
        /// <param name="errors">The errors.</param>
        /// <exception cref="System.ArgumentNullException">
        /// rowObj
        /// or
        /// row
        /// or
        /// validator
        /// or
        /// errors
        /// </exception>
        public static void TryMapValues <T>(T rowObj, dynamic row, IObjectValidator validator, ref List <string> errors)
        {
            if (rowObj == null)
            {
                throw new ArgumentNullException("rowObj");
            }
            if (row == null)
            {
                throw new ArgumentNullException("row");
            }
            if (validator == null)
            {
                throw new ArgumentNullException("validator");
            }
            if (errors == null)
            {
                throw new ArgumentNullException("errors");
            }

            CustomExpandoObject expando = row as CustomExpandoObject;

            if (expando == null)
            {
                expando = new CustomExpandoObject(row, true);
            }

            var getRowValueMethod = validator.GetType().GetMethods().First(x => x.Name == "GetRowValue" && x.GetParameters().Count() >= 5 && x.GetParameters().First().ParameterType == typeof(string));

            PropertyInfo[] properties = typeof(T).GetProperties();

            foreach (var prop in properties)
            {
                if (expando.ContainsKey(prop.Name)) //there may be properties that were not imported
                {
                    string val = Convert.ToString(expando[prop.Name]);

                    Type nonNullableType = FileIOHelpers.GetNonNullableType(prop.PropertyType);
                    if (nonNullableType.IsValueType)
                    {
                        bool isNullable = Nullable.GetUnderlyingType(prop.PropertyType) != null;
                        //convert the Helpers.GetValue method into a generic method of the same type as the property
                        var genericGetvalueMethod = getRowValueMethod.MakeGenericMethod(new Type[] { nonNullableType });
                        var value = genericGetvalueMethod.Invoke(validator, new object[] { val, errors, null, isNullable, prop.Name });
                        prop.SetValue(rowObj, value, null); //this should use the setrowvalue that outputs conversion errors
                    }
                    else
                    {
                        prop.SetValue(rowObj, Convert.ChangeType(val, prop.PropertyType), null);
                    }
                }
            }
        }
        /// <summary>
        /// Converts the headers and values into a dynamic object.
        /// </summary>
        /// <param name="headers">The headers.</param>
        /// <param name="values">The values.</param>
        /// <returns>dynamic.</returns>
        /// <exception cref="System.ArgumentNullException">
        /// headers
        /// or
        /// values
        /// </exception>
        public static dynamic RowToExpando(string[] headers, string[] values)
        {
            if (headers == null)
            {
                throw new ArgumentNullException("headers");
            }
            if (values == null)
            {
                throw new ArgumentNullException("values");
            }
            CustomExpandoObject expandoObject = new CustomExpandoObject(true);

            for (var i = 0; i < headers.Length; i++)
            {
                expandoObject.Add(headers[i], values[i]);
            }
            return(expandoObject);
        }
        /// <summary>
        /// Converts the headers and values into a dynamic object.
        /// </summary>
        /// <param name="headers">The headers.</param>
        /// <param name="values">The values.</param>
        /// <param name="rowIndex">The rowIndex.</param>
        /// <returns>dynamic.</returns>
        /// <exception cref="System.ArgumentNullException">
        /// headers
        /// or
        /// values
        /// </exception>
        public static dynamic RowToExpando(IDictionary <string, string> headers, IDictionary <string, string> values, int rowIndex = -1)
        {
            if (headers == null)
            {
                throw new ArgumentNullException("headers");
            }
            if (values == null)
            {
                throw new ArgumentNullException("values");
            }
            //As not every excel cell may have a value, we have to emit only those cells whose key match up to the headers
            CustomExpandoObject expandoObject = new CustomExpandoObject(true);

            foreach (string key in headers.Keys)
            {
                if (values.ContainsKey(key))
                {
                    if (!expandoObject.ContainsKey(headers[key]))
                    {
                        expandoObject.Add(headers[key], values[key]);
                    }
                    else
                    {
                        expandoObject.Add(key + "_" + headers[key], values[key]);
                    }
                }
                else
                {
                    if (expandoObject.ContainsKey(headers[key]))
                    {
                        throw new DuplicateColumnNameException(string.Format("Column '{0}' found multiple times in the excel file.", headers[key]));
                    }
                    expandoObject.Add(headers[key], String.Empty);
                }
            }

            if (rowIndex >= 0)
            {
                expandoObject.Add("__RowIndex", rowIndex);
            }

            return(expandoObject);
        }