/// <summary>
        /// Uses <see cref="EPARTools"/> to ascertain which <see cref="ExpiredProduct"/>s in a <see cref="VMDPID"/> are
        /// EMA-authorised, search for an SPC document on the EMA website (as no direct links to documents
        /// are provided in the PID) and then uses <see cref="SPCParser"/> to extract a dictionary of
        /// products and target species. The product in question is matched to this dictionary by name.
        /// </summary>
        /// <param name="inpid"></param>
        /// <returns>The provided <see cref="VMDPID"/> with EMA-authorised expired products' target species populated</returns>
        private static async Task <VMDPID> PopulateExpiredProductTargetSpeciesFromEma(VMDPID inpid)
        {
            var expiredProducts =
                new ConcurrentBag <ExpiredProduct>(inpid.ExpiredProducts.Where(
                                                       ep => EPARTools.IsEPAR(ep.SPC_Link)));

            var tasks = expiredProducts.Select(async ep => await PopulateTargetSpeciesFromEma(ep));
            await Task.WhenAll(tasks);

            inpid.ExpiredProducts = inpid.ExpiredProducts.Where(ep => !EPARTools.IsEPAR(ep.SPC_Link))
                                    .Union(expiredProducts).ToList();

            return(inpid);
        }
        /// <summary>
        /// Helper method designed for testing to download SPC document
        /// </summary>
        /// <param name="p"><see cref="ReferenceProduct"/> to get SPC link for</param>
        /// <returns>Path to downloaded file in temp folder</returns>
        public static async Task <string> GetSpc(Product p)
        {
            var uri = ((ExpiredProduct)p).SPC_Link;

            if (EPARTools.IsEPAR(uri))
            {
                uri = (await EPARTools.GetSearchResults(p.Name))[0];
            }

            var tf = Path.GetTempPath() +
                     Path.DirectorySeparatorChar +
                     uri.Split('/')[uri.Split('/').Length - 1];

            if (!File.Exists(tf))
            {
                using (var fs = File.OpenWrite(tf))
                {
                    (await GetHttpStream(uri)).CopyTo(fs);
                }
            }

            return(tf);
        }
        private static async Task PopulateTargetSpeciesFromEma(ReferenceProduct expiredProduct)
        {
            var possibleTargetSpecies = new Dictionary <string, string[]>();
            var searchResults         = await EPARTools.GetSearchResults(expiredProduct.Name);

            foreach (var result in searchResults)
            {
                var tf = Path.GetTempFileName();
                using (var tfs = File.OpenWrite(tf))
                {
                    (await GetHttpStream(result)).CopyTo(tfs);
                }

                var targetSpecies = SPCParser.GetTargetSpeciesFromMultiProductPdf(tf);
                foreach (var ts in targetSpecies)
                {
                    possibleTargetSpecies[ts.Key.ToLowerInvariant()] = ts.Value;
                }
                File.Delete(tf);
            }

            var productKey = expiredProduct.Name.ToLowerInvariant();

            //exact name match
            if (possibleTargetSpecies.ContainsKey(productKey))
            {
                expiredProduct.TargetSpecies = possibleTargetSpecies[productKey];
            }

            //todo:smarter nonexact matching

            //name starts with
            else if (possibleTargetSpecies.Keys.Any(k => k.StartsWith(productKey)))
            {
                productKey = possibleTargetSpecies.Keys.Single(k => k.StartsWith(productKey));
                expiredProduct.TargetSpecies = possibleTargetSpecies[productKey];
            }

            //resolve inconsistent spacing in name between VMD and EMA
            else if (possibleTargetSpecies.Keys.Any(k => k.Replace(" ", "").Equals(productKey.Replace(" ", ""))))
            {
                productKey =
                    possibleTargetSpecies.Keys.Single(k => k.Replace(" ", "").Equals(productKey.Replace(" ", "")));
                expiredProduct.TargetSpecies = possibleTargetSpecies[productKey];
            }

            //get the bit after "for" in the name. Risky - e.g. "solution for injection"
            //could maybe do with species lookup for validation
            else if (productKey.Contains(" for "))
            {
                var forSplit = productKey.Split(new[] { "for" }, StringSplitOptions.None);
                var postFor  = forSplit[forSplit.Length - 1].Replace("and", ",").Split(',')
                               .Select(t => t.Trim().ToLowerInvariant())
                               .Where(t => !string.IsNullOrWhiteSpace(t));

                expiredProduct.TargetSpecies = postFor.ToArray();
            }
            else
            {
                Debug.WriteLine($"{expiredProduct.Name} ReferenceProduct not found");
            }
            PopulateStaticTypedTargetSpecies(expiredProduct);
        }