/// <summary>
        /// Initializes a new instance of the <see cref="ConfigurationItem"/> class.
        /// </summary>
        /// <param name="configuration">Configuration, use to get access the the absolute path.</param>
        /// <param name="mapping">Mapping used to retrieve values.</param>
        /// <param name="templateSubFolder">Folder in which to search for referenced files like work item templates and icons</param>
        public ConfigurationItem(IConfiguration configuration, MappingElement mapping, string templateSubFolder)
        {
            SyncServiceTrace.I(Properties.Resources.LogService_LoadWorkItem, mapping.WorkItemType);

            // Set the simple properties
            WorkItemType                 = mapping.WorkItemType;
            WorkItemSubtypeField         = mapping.WorkItemSubtypeField;
            WorkItemSubtypeValue         = mapping.WorkItemSubtypeValue;
            WorkItemTypeMapping          = mapping.MappingWorkItemType;
            ReqTableIdentifierExpression = mapping.AssignRegularExpression;
            ReqTableCellRow              = mapping.AssignCellRow;
            ReqTableCellCol              = mapping.AssignCellCol;
            RelatedTemplate              = mapping.RelatedTemplate;
            _configuration               = configuration;
            RelatedTemplateFile          = Path.Combine(templateSubFolder, RelatedTemplate);
            HideElementInWord            = mapping.HideElementInWord;
            PreOperations                = null;
            PostOperations               = null;

            _imageFilename = Path.Combine(templateSubFolder, mapping.ImageFile);

            FieldConfigurations = new List <IConfigurationFieldItem>();

            if (mapping.PreOperations != null && mapping.PreOperations.Count > 0)
            {
                PreOperations = new List <IConfigurationTestOperation>();
                foreach (var operation in mapping.PreOperations)
                {
                    PreOperations.Add(new ConfigurationTestOperation(operation));
                }
            }
            if (mapping.PostOperations != null && mapping.PostOperations.Count > 0)
            {
                PostOperations = new List <IConfigurationTestOperation>();
                foreach (var operation in mapping.PostOperations)
                {
                    PostOperations.Add(new ConfigurationTestOperation(operation));
                }
            }

            // Insert a field for the invisible stack rank
            if (_configuration.UseStackRank)
            {
                var stackRankConfig = FieldConfigurations.FirstOrDefault(x => x.ReferenceFieldName.Equals("Microsoft.VSTS.Common.StackRank", StringComparison.OrdinalIgnoreCase));
                if (stackRankConfig != null)
                {
                    SyncServiceTrace.W("Mapping the stack rank field is not supported in combination with UseStackRank=true");
                    FieldConfigurations.Remove(stackRankConfig);
                }
                FieldConfigurations.Add(
                    new ConfigurationFieldItem("Microsoft.VSTS.Common.StackRank", null, FieldValueType.PlainText,
                                               Direction.OtherToTfs, 0, 0, null, false, HandleAsDocumentType.All, null, string.Empty, null, ShapeOnlyWorkaroundMode.AddSpace, false, null, null, String.Empty));
            }

            // Read the configured state transitions if some are defined
            if (mapping.StateTransitions != null)
            {
                _stateTransitionField = mapping.StateTransitions.FieldName;
                _stateTransitions     = new Dictionary <string, string>();

                foreach (var transition in mapping.StateTransitions.Items)
                {
                    _stateTransitions.Add(transition.From, transition.To);
                }
            }

            foreach (MappingField field in mapping.Fields)
            {
                // This fixes some items having their ids configured as html.
                if (field.Name.Equals(FieldReferenceNames.SystemId))
                {
                    field.FieldValueType = FieldValueType.PlainText;
                }

                ConfigurationFieldItemDefaultValue cfidv = null;
                if (field.DefaultValue != null)
                {
                    cfidv = new ConfigurationFieldItemDefaultValue(field.DefaultValue.ShowName,
                                                                   field.DefaultValue.DefaultValue);
                }
                FieldConfigurations.Add(new ConfigurationFieldItem(field.Name, field.MappingName, field.FieldValueType,
                                                                   field.Direction, field.TableRow, field.TableCol,
                                                                   field.TestCaseStepDelimiter, field.HandleAsDocument,
                                                                   field.HandleAsDocumentMode, field.OLEMarkerField,
                                                                   field.OLEMarkerValue, cfidv,
                                                                   field.ShapeOnlyWorkaroundMode,
                                                                   field.TableCol != 0 && field.TableRow != 0,
                                                                   field.WordBookmark,
                                                                   field.VariableName,
                                                                   field.DateTimeFormat
                                                                   ));
            }

            // If the state transition field is not mapped, add it as unmapped field (so it gets queried anyways)
            var stateTransition = FieldConfigurations.FirstOrDefault(x => x.ReferenceFieldName.Equals(_stateTransitionField));

            if (stateTransition == null && _stateTransitionField != null)
            {
                FieldConfigurations.Add(new ConfigurationFieldItem(_stateTransitionField, string.Empty, FieldValueType.PlainText, Direction.OtherToTfs, 0, 0, string.Empty, false, HandleAsDocumentType.OleOnDemand, null, string.Empty, null, ShapeOnlyWorkaroundMode.AddSpace, false, null, null, null));
            }

            // Set the converters
            _converters = new Dictionary <string, IConverter>();

            SyncServiceTrace.I(Properties.Resources.LogService_LoadWorkItem_Converters, mapping.Converters.Length, mapping.WorkItemType);

            foreach (MappingConverter converter in mapping.Converters)
            {
                var valueMapper = new SimpleValueMapper(converter.FieldName);
                foreach (MappingConverterValue value in converter.Values)
                {
                    valueMapper.AddMapping(value.Text, value.MappingText);
                }
                _converters.Add(valueMapper.FieldName.ToUpperInvariant(), valueMapper);
            }

            Links = new List <IConfigurationLinkItem>();
            if (mapping.Links != null)
            {
                foreach (MappingLink link in mapping.Links)
                {
                    var cli = new ConfigurationLinkItem(link.LinkValueType, link.LinkedWorkItemTypes, link.Direction, link.TableRow, link.TableCol, link.Overwrite, link.LinkSeparator, link.LinkFormat, link.AutomaticLinkWorkItemType, link.AutomaticLinkWorkItemSubtypeField, link.AutomaticLinkWorkItemSubtypeValue, link.AutomaticLinkSuppressWarnings);
                    Links.Add(cli);
                }
            }

            // Read the 'field to linked work item' configuration.
            FieldToLinkedItemConfiguration = new List <IConfigurationFieldToLinkedItem>();
            if (mapping.FieldsToLinkedItems != null)
            {
                foreach (var fieldToLinkedItem in mapping.FieldsToLinkedItems)
                {
                    FieldToLinkedItemConfiguration.Add(new ConfigurationFieldToLinkedItem(fieldToLinkedItem));
                }
            }
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="ConfigurationItem"/> class.
        /// </summary>
        /// <param name="configuration">Configuration, used to get the absolute path.</param>
        /// <param name="header">Mapping used to retrieve values.</param>
        /// <param name="templateSubFolder">Folder in which to search for referenced files like work item templates and icons</param>
        public ConfigurationItem(IConfiguration configuration, MappingHeader header, string templateSubFolder)
        {
            SyncServiceTrace.I("Loading header {0}", header.Identifier);

            // Set the simple properties
            WorkItemType                 = header.Identifier;
            WorkItemSubtypeField         = null;
            WorkItemSubtypeValue         = null;
            WorkItemTypeMapping          = header.Identifier;
            ReqTableIdentifierExpression = header.Identifier + " ";
            ReqTableCellRow              = header.Row;
            ReqTableCellCol              = header.Column;
            RelatedTemplate              = header.RelatedTemplate;

            _configuration      = configuration;
            _imageFilename      = Path.Combine(templateSubFolder, header.ImageFile);
            RelatedTemplateFile = Path.Combine(templateSubFolder, RelatedTemplate);
            Level = header.Level;

            // Set the mapping fields
            FieldConfigurations = new List <IConfigurationFieldItem>();

            // Read the configured state transitions if some are defined

            /*
             * if (header.StateTransitions != null)
             * {
             *  _stateTransitionField = header.StateTransitions.FieldName;
             *  _stateTransitions = new Dictionary<string, string>();
             *
             *  foreach (var transition in header.StateTransitions.Items)
             *  {
             *      _stateTransitions.Add(transition.From, transition.To);
             *  }
             * }
             */

            foreach (var field in header.Fields)
            {
                ConfigurationFieldItemDefaultValue cfidv = null;
                if (field.DefaultValue != null)
                {
                    cfidv = new ConfigurationFieldItemDefaultValue(field.DefaultValue.ShowName,
                                                                   field.DefaultValue.DefaultValue);
                }
                FieldConfigurations.Add(new ConfigurationFieldItem(field.Name, field.MappingName, field.FieldValueType,
                                                                   field.Direction, field.TableRow, field.TableCol,
                                                                   field.TestCaseStepDelimiter, field.HandleAsDocument,
                                                                   field.HandleAsDocumentMode, field.OLEMarkerField,
                                                                   field.OLEMarkerValue, cfidv,
                                                                   field.ShapeOnlyWorkaroundMode,
                                                                   field.TableCol != 0 && field.TableRow != 0,
                                                                   field.WordBookmark,
                                                                   field.VariableName,
                                                                   field.DateTimeFormat
                                                                   ));
            }

            // If the state transition field is not mapped, add it as unmapped field ( so it gets queried anyways)

            /*
             * var stateTransition = _fieldConfiguration.FirstOrDefault(x => x.ReferenceFieldName.Equals(_stateTransitionField));
             * if (stateTransition == null && _stateTransitionField != null)
             * {
             *  _fieldConfiguration.Add(new ConfigurationFieldItem(_stateTransitionField, string.Empty, FieldValueType.PlainText, Direction.OtherToTfs, 0, 0, string.Empty, false, HandleAsDocumentType.OleOnDemand, null, false));
             * }
             * */

            // Set the converters
            _converters = new Dictionary <string, IConverter>();

            if (header.Converters != null)
            {
                foreach (MappingConverter converter in header.Converters)
                {
                    var valueMapper = new SimpleValueMapper(converter.FieldName);
                    foreach (MappingConverterValue value in converter.Values)
                    {
                        valueMapper.AddMapping(value.Text, value.MappingText);
                    }
                    _converters.Add(valueMapper.FieldName.ToUpperInvariant(), valueMapper);
                }
            }

            Links = new List <IConfigurationLinkItem>();
            FieldToLinkedItemConfiguration = new List <IConfigurationFieldToLinkedItem>();

            /*
             * if (header.Links != null)
             * {
             *  foreach (MappingLink link in header.Links)
             *  {
             *      var cli = new ConfigurationLinkItem(link.LinkValueType, link.Direction, link.TableRow, link.TableCol, link.Overwrite, link.LinkSeparator, link.LinkFormat);
             *      _links.Add(cli);
             *  }
             * }
             *
             * // Read the 'field to linked work item' configuration.
             * if (header.FieldsToLinkedItems != null)
             * {
             *  foreach (var fieldToLinkedItem in header.FieldsToLinkedItems)
             *  {
             *      _fieldToLinkedItemConfiguration.Add(new ConfigurationFieldToLinkedItem(fieldToLinkedItem));
             *  }
             * }
             */
        }