/// <summary>
        /// Recursively searches for all workflow runs.
        /// </summary>
        /// <param name="jenkinsObject"></param>
        /// <returns></returns>
        public async Task <List <WorkflowRun> > FetchAllWorkflowRuns(JenkinsObject jenkinsObject)
        {
            List <WorkflowRun> runs = new List <WorkflowRun>();
            List <Task <List <WorkflowRun> > > tasks = new List <Task <List <WorkflowRun> > >();

            switch (jenkinsObject)
            {
            case Hudson h:
                tasks.AddRange(h.Jobs.Select(j => FetchAllWorkflowRuns(j)));
                break;

            case Folder f:
                tasks.AddRange(f.Jobs.Select(j => FetchAllWorkflowRuns(j)));
                break;

            case WorkflowJob wj:
                tasks.AddRange(wj.builds.Take(1).Select(j => FetchAllWorkflowRuns(j)));
                break;

            case WorkflowRun wr:
                runs.Add(wr);
                break;

            default:
                logger.LogWarning($"Unknown Jenkins object type: {jenkinsObject.GetType().FullName}:\n{JsonConvert.SerializeObject(jenkinsObject, Formatting.Indented)}");
                break;
            }

            await Task.WhenAll(tasks);

            runs.AddRange(tasks.SelectMany(t => t.Result));

            return(runs);
        }
        public JenkinsObject Deserialise(string json)
        {
            JObject o = JObject.Parse(json);

            string className = (string)o.SelectToken("_class");

            Type jenkinsObjectType;

            if (!fetchTypeMap().TryGetValue(className, out jenkinsObjectType))
            {
                Console.WriteLine($"Unknown type '{className}'.");
                jenkinsObjectType = typeof(UnknownJenkinsObject);
            }

            JenkinsObject jenkinsObject = (JenkinsObject)JsonConvert.DeserializeObject(json, jenkinsObjectType);

            return(jenkinsObject);
        }