private int FindDirs(Dictionary <string, string> opts, Dictionary <string, string> pars, ref List <string> resultFinalList)
        {
            // example:  find git repos  (.git, or hooks not preceeded by .git)  consutil1 -v=1 oper=findd src=k:\_git\ pat=hooks,.git patex=.git
            List <string> srcDirsList = new List <string>();
            var           rVal        = TraverseAndCollect(opts, pars, srcDirsList, WalkDirectoryTree);

            if (rVal != 0)
            {
                string msg = SimpleUtils.ErrorMsg("aborting copy on error", rVal, "oper.copy walk");
                Console.WriteLine(msg);
                myLog(msg);
            }
            else
            {
                List <string> desDirsList = new List <string>();
                rVal = DedupList(opts, pars, srcDirsList, desDirsList); // dedupped dirs list
                Console.WriteLine("Directory List length:" + desDirsList.Count);
                if (pars.ContainsKey("pat"))
                {
                    string   pattern = pars["pat"];
                    string[] pats    = pattern.Split(',');
                    foreach (string pat in pats)
                    {
                        if (pat.Length > 0)
                        {
                            foreach (string dir in desDirsList)
                            {
                                if (dir.EndsWith(pat))
                                {
                                    if (pars.ContainsKey("patex"))    // todo: this should be pipelined not hardcoded
                                    {
                                        string patternExclude = pars["patex"];
                                        if (dir.IndexOf("\\") > 1)
                                        {
                                            if (dir.Substring(0, dir.LastIndexOf("\\")).IndexOf(patternExclude) > 0)
                                            {
                                                continue; // has a parent dir component that excludes this match
                                            }
                                        }
                                    }
                                    resultFinalList.Add(dir);
                                }
                            }
                        }
                    }
                    Console.WriteLine("Filtered List length:" + resultFinalList.Count);
                }
                else
                {
                    resultFinalList = desDirsList;
                }
            }
            return(rVal);
        }
        public List <string> FilterFSInfo(string[] args, Dictionary <string, string> opts, Dictionary <string, string> pars)
        {
            if ((opts == null) || (pars == null))
            {
                int argsErr = SimpleUtils.ExtractArguements(args, out opts, out pars, myLog);
                Console.WriteLine("FileSystemOps.FilterFSInfo.opts returns: {0:X}({0})", argsErr);
            }

            foreach (string nam in opts.Keys)
            {
                try {
                    switch (nam)
                    {
                    case "help":
                        Console.WriteLine("no help here");
                        break;
                    }
                }
                catch (Exception exc) {
                    string msg = SimpleUtils.ExceptionMsg(exc, "FileSystemOps.FilterFSInfo.opts");
                    Console.WriteLine(msg);
                    myLog(msg);
                }
            }

            List <string> resultFinalList = new List <string>();

            DateTime dtStt = DateTime.Now;

            if (pars.ContainsKey("oper"))
            {
                //string nam = pars["oper"];
                int rVal;
                try {
                    switch (pars["oper"])
                    {
                    case "verbs":
                        if (pars.ContainsKey("cmd"))
                        {
                            ProcessStartInfo startInfo = new ProcessStartInfo(pars["cmd"]);

                            for (int i = 0; i < startInfo.Verbs.Length; i++)
                            {
                                // Display the possible verbs.
                                Console.WriteLine("  {0}. {1}", i, startInfo.Verbs[i]);
                            }
                        }

                        break;

                    case "findf": {     // find files.  if destination than use it
                                        //consutil1 -v oper=findf src=c:\source  des=d:\destination
                        rVal = TraverseAndCollect(opts, pars, resultFinalList, WalkDirectoryFileTree);
                        if (pars.ContainsKey("des"))
                        {
                            if (rVal != 0)
                            {
                                string msg = SimpleUtils.ErrorMsg("aborting copy on error", rVal, "oper.copy walk");
                                Console.WriteLine(msg);
                                myLog(msg);
                            }
                            else
                            {
                                CopyFiles(opts, pars, resultFinalList);
                            }
                        }
                    }
                    break;

                    case "findd": {     // find directories. sample to find directories with git repos, bare or not, in prep for duping directories or pulling for git updates.
                                        //consutil1 -v oper=invoked pat=hooks,.git patex=.git src=E:\_GIT_K_working_clones\  ttail=\ resultsf=\junk\K_Result.txt  destf=\junk\K_gitSrcDirs_pull.txt
                                        //consutil1 -v oper=findd pat=hooks,.git patex=.git src=E:\_GIT_K_working_clones\  ttail=\ resultsf=\junk\invoked_test_Result.txt cmd="C:\Program Files\Git\bin\git.exe" opts=pull  destf=\junk\test_gitSrcDirs_pull.txt workDir=@takesrc
                        rVal = FindDirs(opts, pars, ref resultFinalList);
                        if (pars.ContainsKey("ttail"))
                        {
                            List <string> templ = new List <string>();
                            foreach (string dir in resultFinalList)
                            {
                                try {
                                    templ.Add(dir.Substring(0, dir.LastIndexOf(pars["ttail"])));
                                }
                                catch (Exception exc) {
                                    string lmsg = SimpleUtils.ExceptionMsg(exc, " truncating dir for copy :" + dir);
                                    Console.WriteLine(lmsg);
                                    myLog(lmsg);
                                }
                            }
                            resultFinalList = templ;
                        }

                        if (pars.ContainsKey("des"))
                        {
                            if (rVal != 0)
                            {
                                string msg = SimpleUtils.ErrorMsg("aborting copy on error", rVal, "oper.findd walk");
                                Console.WriteLine(msg);
                                myLog(msg);
                            }
                            else
                            {
                                CopyDirectories(args, opts, pars, resultFinalList);
                            }
                        }
                    }
                    break;

                    case "invoked": {
                        // clone repos from a tree
                        // -v oper=invoked pat=hooks,.git patex=.git src=E:\_GIT_K_working_clones\ des=g:\_t ttail=\ resultsf=\junk\K_e_Result.txt cmd="C:\Program Files\Git\bin\git.exe" opts=clone  destf=\junk\K_e_dest.txt workDir=@takesrc -fd=
                        // pull a bunch of repos
                        // consutil1 -v oper=invoked pat=hooks,.git patex=.git src=E:\_GIT_K_working_clones\  ttail=\ resultsf=\junk\invoked_G_Result.txt cmd="C:\Program Files\Git\bin\git.exe" opts=pull  destf=\junk\G_gitSrcDirs_pull.txt workDir=@takesrc
                        rVal = FindDirs(opts, pars, ref resultFinalList);
                        if (pars.ContainsKey("ttail"))
                        {
                            List <string> templ = new List <string>();
                            foreach (string dir in resultFinalList)
                            {
                                try {
                                    templ.Add(dir.Substring(0, dir.LastIndexOf(pars["ttail"])));
                                }
                                catch (Exception exc) {
                                    string lmsg = SimpleUtils.ExceptionMsg(exc, " truncating dir for copy :" + dir);
                                    Console.WriteLine(lmsg);
                                    myLog(lmsg);
                                }
                            }
                            resultFinalList = templ;
                        }

                        if (pars.ContainsKey("cmd"))
                        {
                            if (rVal != 0)
                            {
                                string msg = SimpleUtils.ErrorMsg("aborting copy on error", rVal, "oper.findd walk");
                                Console.WriteLine(msg);
                                myLog(msg);
                            }
                            else
                            {
                                InvokeDirectories(args, opts, pars, resultFinalList);
                            }
                        }
                    }
                    break;
                    }
                }
                catch (Exception exc) {
                    rVal = exc.HResult;
                    string msg = SimpleUtils.ExceptionMsg(exc, "FileSystemOps.FilterFSInfo.pars");
                    Console.WriteLine(msg);
                    myLog(msg);
                }
            }
            DateTime dtStp = DateTime.Now;

            Console.WriteLine("msecs=" + dtStp.Subtract(dtStt).TotalMilliseconds);

            if ((opts.ContainsKey("v")) && (opts["v"].Equals("1")))
            {
                foreach (string stg in resultFinalList)
                {
                    Console.WriteLine(stg);
                }
                Console.WriteLine("List end");
            }
            if (pars.ContainsKey("resultsf"))
            {
                StreamWriter sw = new StreamWriter(pars["resultsf"]);
                foreach (string stg in resultFinalList)
                {
                    sw.WriteLine(stg);
                }
                sw.Close();
            }

            return(resultFinalList);
        }