internal override void InternalExecute()
        {
            Stopwatch stopwatch = Stopwatch.StartNew();
            //////////////////////////////////////////////////
            WorkItemStoreContext targetStore = new WorkItemStoreContext(me.Target, WorkItemStoreFlags.BypassRules);

            TfsQueryContext tfsqc = new TfsQueryContext(targetStore);

            TfsTeamService            teamService = me.Target.Collection.GetService <TfsTeamService>();
            QueryHierarchy            qh          = targetStore.Store.Projects[me.Target.Config.Project].QueryHierarchy;
            List <TeamFoundationTeam> teamList    = teamService.QueryTeams(me.Target.Config.Project).ToList();

            Trace.WriteLine(string.Format("Found {0} teams?", teamList.Count));
            //////////////////////////////////////////////////
            int  current   = teamList.Count;
            int  count     = 0;
            long elapsedms = 0;

            foreach (TeamFoundationTeam team in teamList)
            {
                Stopwatch witstopwatch = Stopwatch.StartNew();

                Trace.Write(string.Format("Processing team {0}", team.Name));
                Regex  r = new Regex(@"^Project - ([a-zA-Z ]*)");
                string path;
                if (r.IsMatch(team.Name))
                {
                    Trace.Write(string.Format(" is a Project"));
                    path = string.Format(@"Projects\{0}", r.Match(team.Name).Groups[1].Value.Replace(" ", "-"));
                }
                else
                {
                    Trace.Write(string.Format(" is a Team"));
                    path = string.Format(@"Teams\{0}", team.Name.Replace(" ", "-"));
                }
                Trace.Write(string.Format(" and new path is {0}", path));
                //me.AddFieldMap("*", new RegexFieldMap("KM.Simulation.Team", "System.AreaPath", @"^Project - ([a-zA-Z ]*)", @"Nemo\Projects\$1"));

                string[] bits = path.Split(char.Parse(@"\"));

                CreateFolderHyerarchy(bits, qh["Shared Queries"]);

                //_me.ApplyFieldMappings(workitem);
                qh.Save();


                witstopwatch.Stop();
                elapsedms = elapsedms + witstopwatch.ElapsedMilliseconds;
                current--;
                count++;
                TimeSpan average   = new TimeSpan(0, 0, 0, 0, (int)(elapsedms / count));
                TimeSpan remaining = new TimeSpan(0, 0, 0, 0, (int)(average.TotalMilliseconds * current));
                Trace.WriteLine("");
                //Trace.WriteLine(string.Format("Average time of {0} per work item and {1} estimated to completion", string.Format(@"{0:s\:fff} seconds", average), string.Format(@"{0:%h} hours {0:%m} minutes {0:s\:fff} seconds", remaining)));
            }
            //////////////////////////////////////////////////
            stopwatch.Stop();
            Console.WriteLine(@"DONE in {0:%h} hours {0:%m} minutes {0:s\:fff} seconds", stopwatch.Elapsed);
        }
        protected override void InternalExecute()
        {
            Stopwatch stopwatch = Stopwatch.StartNew();
            //////////////////////////////////////////////////
            TfsTeamService            teamService = Engine.Target.GetService <TfsTeamService>();
            QueryHierarchy            qh          = ((TfsWorkItemMigrationClient)Engine.Target.WorkItems).Store.Projects[Engine.Target.Config.AsTeamProjectConfig().Project].QueryHierarchy;
            List <TeamFoundationTeam> teamList    = teamService.QueryTeams(Engine.Target.Config.AsTeamProjectConfig().Project).ToList();

            Log.LogInformation("Found {0} teams?", teamList.Count);
            //////////////////////////////////////////////////
            int  current   = teamList.Count;
            int  count     = 0;
            long elapsedms = 0;

            foreach (TeamFoundationTeam team in teamList)
            {
                Stopwatch witstopwatch = Stopwatch.StartNew();

                Log.LogTrace("Processing team {0}", team.Name);
                Regex  r = new Regex(@"^Project - ([a-zA-Z ]*)");
                string path;
                if (r.IsMatch(team.Name))
                {
                    Log.LogInformation("{0} is a Project", team.Name);
                    path = string.Format(@"Projects\{0}", r.Match(team.Name).Groups[1].Value.Replace(" ", "-"));
                }
                else
                {
                    Log.LogInformation("{0} is a Team", team.Name);
                    path = string.Format(@"Teams\{0}", team.Name.Replace(" ", "-"));
                }
                Log.LogInformation(" and new path is {0}", path);
                //me.AddFieldMap("*", new RegexFieldMap("KM.Simulation.Team", "System.AreaPath", @"^Project - ([a-zA-Z ]*)", @"Nemo\Projects\$1"));

                string[] bits = path.Split(char.Parse(@"\"));

                CreateFolderHyerarchy(bits, qh["Shared Queries"]);

                //_me.ApplyFieldMappings(workitem);
                qh.Save();

                witstopwatch.Stop();
                elapsedms = elapsedms + witstopwatch.ElapsedMilliseconds;
                current--;
                count++;
                TimeSpan average   = new TimeSpan(0, 0, 0, 0, (int)(elapsedms / count));
                TimeSpan remaining = new TimeSpan(0, 0, 0, 0, (int)(average.TotalMilliseconds * current));
                Log.LogInformation("Average time of {average} per work item and {remaining} estimated to completion", average.ToString("c"), remaining.ToString("c"));
            }
            //////////////////////////////////////////////////
            stopwatch.Stop();
            Log.LogInformation("DONE in {Elapsed} ", stopwatch.Elapsed.ToString("c"));
        }
        /// <summary>
        /// Add Query Definition under a specific Query Folder.
        /// </summary>
        /// <param name="targetHierarchy">The object that represents the whole of the target query tree</param>
        /// <param name="query">Query Definition - Contains the Query Details</param>
        /// <param name="QueryFolder">Parent Folder</param>
        void MigrateQuery(QueryHierarchy targetHierarchy, QueryDefinition query, QueryFolder parentFolder)
        {
            if (parentFolder.FirstOrDefault(q => q.Name == query.Name) != null)
            {
                this.totalQueriesSkipped++;
                Trace.WriteLine($"Skipping query '{query.Name}' as already exists");
            }
            else
            {
                // Sort out any path issues in the quertText
                var fixedQueryText = query.QueryText.Replace($"'{Engine.Source.Config.Project}", $"'{Engine.Target.Config.Project}"); // the ' should only items at the start of areapath etc.

                if (config.PrefixProjectToNodes)
                {
                    // we need to inject the team name as a folder in the structure too
                    fixedQueryText = fixedQueryText.Replace($"{Engine.Target.Config.Project}\\", $"{Engine.Target.Config.Project}\\{Engine.Source.Config.Project}\\");
                }

                if (config.SourceToTargetFieldMappings != null)
                {
                    foreach (var sourceField in config.SourceToTargetFieldMappings.Keys)
                    {
                        fixedQueryText = query.QueryText.Replace($"{sourceField}", $"'{config.SourceToTargetFieldMappings[sourceField]}");
                    }
                }

                // you cannot just add an item from one store to another, we need to create a new object
                var queryCopy = new QueryDefinition(query.Name, fixedQueryText);
                this.totalQueriesAttempted++;
                Trace.WriteLine($"Migrating query '{query.Name}'");
                parentFolder.Add(queryCopy);
                try
                {
                    targetHierarchy.Save(); // moved the save here for better error message
                    this.totalQueriesMigrated++;
                }
                catch (Exception ex)
                {
                    this.totalQueryFailed++;
                    Trace.WriteLine($"Error saving query '{query.Name}', probably due to invalid area or iteration paths");
                    Trace.WriteLine($"Source Query: '{query}'");
                    Trace.WriteLine($"Target Query: '{fixedQueryText}'");
                    Trace.WriteLine(ex.Message);
                    targetHierarchy.Refresh(); // get the tree without the last edit
                }
            }
        }
        /// <summary>
        /// Define Query Folders under the current parent
        /// </summary>
        /// <param name="targetHierarchy">The object that represents the whole of the target query tree</param>
        /// <param name="sourceFolder">The source folder in tree on source instance</param>
        /// <param name="parentFolder">The target folder in tree on target instance</param>
        private void MigrateFolder(QueryHierarchy targetHierarchy, QueryFolder sourceFolder, QueryFolder parentFolder)
        {
            // We only migrate non-private folders and their contents
            if (sourceFolder.IsPersonal)
            {
                Log.LogInformation("Found a personal folder {sourceFolderName}. Migration only available for shared Team Query folders", sourceFolder.Name);
            }
            else
            {
                this.totalFoldersAttempted++;

                // we need to replace the team project name in folder names as it included in query paths
                var requiredPath = sourceFolder.Path.Replace($"{Source.Project}/", $"{Target.Project}/");

                // Is the project name to be used in the migration as an extra folder level?
                if (_Options.PrefixProjectToNodes == true)
                {
                    // we need to inject the team name as a folder in the structure
                    requiredPath = requiredPath.Replace(_Options.SharedFolderName, $"{_Options.SharedFolderName}/{Source.Project}");

                    // If on the root level we need to check that the extra folder has already been added
                    if (sourceFolder.Path.Count(f => f == '/') == 1)
                    {
                        var         targetSharedFolderRoot = (QueryFolder)parentFolder[_Options.SharedFolderName];
                        QueryFolder extraFolder            = (QueryFolder)targetSharedFolderRoot.FirstOrDefault(q => q.Path == requiredPath);
                        if (extraFolder == null)
                        {
                            // we are at the root level on the first pass and need to create the extra folder for the team name
                            Log.LogInformation("Adding a folder '{Project}'", Source.Project);
                            extraFolder = new QueryFolder(Source.Project);
                            targetSharedFolderRoot.Add(extraFolder);
                            targetHierarchy.Save(); // moved the save here a more immediate and relavent error message
                        }

                        // adjust the working folder to the newly added one
                        parentFolder = targetSharedFolderRoot;
                    }
                }

                // check if there is a folder of the required name, using the path to make sure it is unique
                QueryFolder targetFolder = (QueryFolder)parentFolder.FirstOrDefault(q => q.Path == requiredPath);
                if (targetFolder != null)
                {
                    Log.LogInformation("Skipping folder '{sourceFolderName}' as already exists", sourceFolder.Name);
                }
                else
                {
                    Log.LogInformation("Migrating a folder '{sourceFolderName}'", sourceFolder.Name);
                    targetFolder = new QueryFolder(sourceFolder.Name);
                    parentFolder.Add(targetFolder);
                    targetHierarchy.Save(); // moved the save here a more immediate and relavent error message
                }

                // Process child items
                foreach (QueryItem sub_query in sourceFolder)
                {
                    if (sub_query.GetType() == typeof(QueryFolder))
                    {
                        MigrateFolder(targetHierarchy, (QueryFolder)sub_query, (QueryFolder)targetFolder);
                    }
                    else
                    {
                        MigrateQuery(targetHierarchy, (QueryDefinition)sub_query, (QueryFolder)targetFolder);
                    }
                }
            }
        }