/// <summary>
        /// Find all output formats that matches the given <paramref name="rawAddress"/> in a given assembly.
        /// </summary>
        /// <param name="rawAddress">Input to be checked.</param>
        /// <param name="assembly">
        /// Assembly that will be searched for output formats.
        /// <para>Defaults to the Address Separation Library assembly, meaning only pre-defined output formats showing up.</para>
        /// </param>
        /// <returns>IEnumerable with all <c>matching</c> output formats found. Empty if none found.</returns>
        public static IEnumerable <DescriptionMapper> GetCompatibleOutputFormats(string rawAddress, Assembly assembly = null)
        {
            var matchingOutputFormats = new List <DescriptionMapper>();

            // get all output formats based on assembly
            var allOutputFormatClasses = OutputFormatHelper
                                         .GetMappings(assembly)
                                         .RemoveNullRegexes();

            // process each found output format class with the given rawAddress
            foreach (var outputFormat in allOutputFormatClasses)
            {
                // get and create processor instance
                var processorInstance = AddressSeparationProcessorFactory.CreateInstance(outputFormat.Type, new DontThrowProcessingOptions(), null);

                // get and invoke method
                var processMethod = processorInstance.GetType()
                                    .GetMethod("Process", new[] { typeof(string) });
                var methodResultInstance = processMethod
                                           .Invoke(processorInstance, new object[] { rawAddress });

                // fetch and assert result
                bool isAddressResolved = (bool)methodResultInstance.GetType()
                                         .GetProperty("AddressHasBeenResolved")?
                                         .GetValue(methodResultInstance);

                if (isAddressResolved)
                {
                    matchingOutputFormats.Add(outputFormat);
                }
            }

            return(matchingOutputFormats);
        }
        public void Factory_CreateInstance_ReturnsInstanceOfCorrectType()
        {
            // arrange
            var outputFormatType = typeof(InputSameAsOutputOutputFormat);

            // act
            var instance = AddressSeparationProcessorFactory.CreateInstance(outputFormatType)
                           as AddressSeparationProcessor <InputSameAsOutputOutputFormat>;

            // assert
            Assert.IsNotNull(instance);
            Assert.IsInstanceOf(typeof(AddressSeparationProcessor <InputSameAsOutputOutputFormat>), instance);
        }
        public void Factory_CreateInstance_HasInputManipulationQueue()
        {
            // arrange
            var outputFormatType = typeof(InputSameAsOutputOutputFormat);
            var queue            = new Queue <IInputManipulation>();

            // act
            var instance = AddressSeparationProcessorFactory.CreateInstance(outputFormatType, queue)
                           as AddressSeparationProcessor <InputSameAsOutputOutputFormat>;

            // assert
            Assert.IsNotNull(instance);
            Assert.IsNotNull(instance.InputManipulationQueue);
        }
        public void Factory_CreateInstance_HasOptions()
        {
            // arrange
            var outputFormatType = typeof(InputSameAsOutputOutputFormat);
            var options          = new DontThrowProcessingOptions();

            // act
            var instance = AddressSeparationProcessorFactory.CreateInstance(outputFormatType, options)
                           as AddressSeparationProcessor <InputSameAsOutputOutputFormat>;

            // assert
            Assert.IsNotNull(instance);
            Assert.IsNotNull(instance.Options);
        }
        /// <summary>
        /// Processes the selected cells
        /// </summary>
        private void btnProcess_Click(object sender, RibbonControlEventArgs e)
        {
            // sanity check
            var selection = Globals.ThisAddIn.Application.Selection as Range;

            if (selection == null)
            {
                MessageBox.Show(Resources.Messages.PlaceCursorOntoAddress, Resources.Messages.ProcessTitle,
                                MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }

            // get selected output format type
            string selectedOutputFormatText = cbOutputFormat.Text;
            Type   selectedOutputFormatType = _outputFormatsDictionary[selectedOutputFormatText]?.Type;

            if (selectedOutputFormatType == null)
            {
                MessageBox.Show(Resources.Messages.SelectOutputFormat, Resources.Messages.ProcessTitle,
                                MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }

            // create processor
            var     queue             = GetInputManipulationQueue();
            dynamic processor         = AddressSeparationProcessorFactory.CreateInstance(selectedOutputFormatType, null, queue);
            var     matchedProperties = OutputFormatHelper.GetPropertyRegexGroups(selectedOutputFormatType).ToList();

            // try resolving every address
            foreach (Range cell in selection.Cells)
            {
                // skip empty cells
                if (cell.Value == null)
                {
                    continue;
                }

                // process address
                object address = processor.Process(cell.Value).ResolvedAddress;

                // place properties next to active cell
                for (int i = 0; i < matchedProperties.Count(); i++)
                {
                    string propertyName = matchedProperties[i].Property.Name;
                    cell.Offset[0, i + 1].Value = address.GetType()
                                                  .GetProperty(propertyName)
                                                  .GetValue(address);
                }
            }
        }