/// <summary>
        /// Visits the specified <see cref="FieldMapping" />.
        /// </summary>
        /// <param name="fieldMapping">The <see cref="FieldMapping" /> to visit.</param>
        /// <exception cref="System.ComponentModel.DataAnnotations.ValidationException">Missing source column mapping.  Please select a source column.</exception>
        public override void VisitFieldMapping(FieldMapping fieldMapping)
        {
            var c = fieldMapping;

            if (c.IsIncluded && (c.Index == null || c.Index == -1))
                throw new ValidationException("Missing source column mapping.  Please select a source column for '" + c.DisplayName + "'.");

            base.VisitFieldMapping(fieldMapping);
        }
        /// <summary>
        /// Visits the specified <see cref="FieldMapping" />.
        /// </summary>
        /// <param name="fieldMapping">The <see cref="FieldMapping" /> to visit.</param>
        /// <exception cref="System.ComponentModel.DataAnnotations.ValidationException">Missing source column mapping.  Please select a source column.</exception>
        public override void VisitFieldMapping(FieldMapping fieldMapping)
        {
            var c = fieldMapping;

            if (c.IsIncluded && (c.Index == null || c.Index == -1))
            {
                throw new ValidationException("Missing source column mapping.  Please select a source column for '" + c.DisplayName + "'.");
            }

            base.VisitFieldMapping(fieldMapping);
        }
        private static FieldIndex FindField(BatchJob batchJob, FieldMapping fieldMapping)
        {
            FieldIndex match;

            //first try match definitions 
            foreach (var matchDefinition in fieldMapping.MatchDefinitions)
            {
                if (matchDefinition.Text.IsNullOrEmpty())
                    continue;

                string text = matchDefinition.Text;

                match = matchDefinition.UseRegex
                    ? batchJob.SourceFields.FirstOrDefault(f => Regex.IsMatch(f.Name, text, RegexOptions.IgnoreCase))
                    : batchJob.SourceFields.FirstOrDefault(f => string.Equals(f.Name, text, StringComparison.OrdinalIgnoreCase));

                if (match == null)
                    continue;

                fieldMapping.TranslatorSource = matchDefinition.TranslatorSource;
                return match;
            }

            // next try name match
            var name = fieldMapping.Name;
            match = batchJob.SourceFields.FirstOrDefault(f => string.Equals(f.Name, name, StringComparison.OrdinalIgnoreCase));

            return match;
        }
        private object GetDefault(BatchJob batchJob, FieldMapping fieldMapping)
        {
            var fieldDefault = fieldMapping.Default;
            if (!fieldDefault.HasValue)
                return null;

            if (fieldDefault.Value == FieldDefault.CurrentDate)
                return DateTime.Now;

            if (fieldDefault.Value == FieldDefault.UserName)
                return batchJob.UserName;

            if (fieldDefault.Value == FieldDefault.Static)
                return fieldMapping.DefaultValue;

            return null;
        }
        /// <summary>
        /// Visits the specified <see cref="FieldMapping"/>.
        /// </summary>
        /// <param name="fieldMapping">The <see cref="FieldMapping"/> to visit.</param>
        public virtual void VisitFieldMapping(FieldMapping fieldMapping)
        {
            foreach (var item in fieldMapping.MatchDefinitions)
                VisitFieldMatch(item);

        }