/// <summary>
        /// Takes a source and destination file and processes the person based tree data in the source
        /// so that addresses are geocoded and dates are formatted into ranges.
        /// If the destination already exists it is read to see which records do not need
        /// parameter
        /// Checks storage and geocodes every tree that has people that need geocoding.
        /// </summary>
        public async Task ProcessTreeDataAsync()
        {
            List <WhoWhatWhereWhen> trees;

            if (await treeWriter.TargetExistsAsync())
            {
                // If the destination already exists, load it from there to complete any records not processed before.
                trees = await treeWriter.ReadAllAsync();
            }
            else
            {
                var people = await treeReader.ReadAllAsync();

                trees = treeParser.ParseListIntoTrees(people);
            }

            // TODO: Test for null logger injected and all output below is logged to a test logger.
            logger?.LogInformation((int)LogEventIds.GeocodingLocations, "Geocoding locations.");

            foreach (var tree in trees)
            {
                //logger?.LogInformation((int)LogEventIds.CheckingTree, "Checking tree {treeId} with match '{matchName}'.", tree.TreeId, tree.MatchName);
                //foreach (var treeEvent in tree)
                tree.Where.Location = await GeocodeLocationAsync(tree.Where.Location);
            }

            await treeWriter.WriteAllAsync(trees);
        }