/// <summary>
        /// Because the nodes.hot_threads endpoint returns plain text instead of JSON, we have to
        /// manually parse the response text into a typed response object.
        /// </summary>
        private NodesHotThreadsResponse DeserializeNodesHotThreadResponse(IApiCallDetails response, Stream stream)
        {
            using (stream)
                using (var sr = new StreamReader(stream, Encoding.UTF8))
                {
                    var typedResponse     = new NodesHotThreadsResponse();
                    var plainTextResponse = sr.ReadToEnd();

                    // If the response doesn't start with :::, which is the pattern that delimits
                    // each node section in the response, then the response format isn't recognized.
                    // Just return an empty response object. This is especially useful when unit
                    // testing against an in-memory connection where you won't get a real response.
                    if (!plainTextResponse.StartsWith(":::", StringComparison.Ordinal))
                    {
                        return(typedResponse);
                    }

                    var sections = plainTextResponse.Split(new string[] { ":::" }, StringSplitOptions.RemoveEmptyEntries);
                    var info     =
                        from section in sections
                        select section.Split(new string[] { "\n   \n" }, StringSplitOptions.None)
                        into sectionLines
                            where sectionLines.Length > 0
                        let nodeLine = sectionLines.FirstOrDefault()
                                           where nodeLine != null
                                       let matches = NodeRegex.Match(nodeLine)
                                                         where matches.Success
                                                     let node = matches.Groups["name"].Value
                                                                let nodeId                         = matches.Groups["id"].Value
                                                                                         let hosts = matches.Groups["hosts"].Value.Split(new[] { '{', '}' }, StringSplitOptions.RemoveEmptyEntries)
                                                                                                     let threads = sectionLines.Skip(1).Take(sectionLines.Length - 1).ToList()
                                                                                                                   select new HotThreadInformation
                    {
                        NodeName = node,
                        NodeId   = nodeId,
                        Threads  = threads,
                        Hosts    = hosts
                    };
                    return(new NodesHotThreadsResponse(info.ToList()));
                }
        }
		/// <summary>
		/// Because the nodes.hot_threads endpoint returns plain text instead of JSON, we have to
		/// manually parse the response text into a typed response object.
		/// </summary>
		private NodesHotThreadsResponse DeserializeNodesHotThreadResponse(IApiCallDetails response, Stream stream)
		{
			using (stream)
			using (var sr = new StreamReader(stream, Encoding.UTF8))
			{
				var typedResponse = new NodesHotThreadsResponse();
				var plainTextResponse = sr.ReadToEnd();

				// If the response doesn't start with :::, which is the pattern that delimits
				// each node section in the response, then the response format isn't recognized.
				// Just return an empty response object. This is especially useful when unit
				// testing against an in-memory connection where you won't get a real response.
				if (!plainTextResponse.StartsWith(":::", StringComparison.Ordinal))
					return typedResponse;

				var sections = plainTextResponse.Split(new string[] { ":::" }, StringSplitOptions.RemoveEmptyEntries);
				var info =
					from section in sections
					select section.Split(new string[] {"\n   \n"}, StringSplitOptions.None)
					into sectionLines
					where sectionLines.Length > 0
					let nodeLine = sectionLines.FirstOrDefault()
					where nodeLine != null
					let matches = NodeRegex.Match(nodeLine)
					where matches.Success
					let node = matches.Groups["name"].Value
					let nodeId = matches.Groups["id"].Value
					let hosts = matches.Groups["hosts"].Value.Split(new[] {'{', '}'}, StringSplitOptions.RemoveEmptyEntries)
					let threads = sectionLines.Skip(1).Take(sectionLines.Length - 1).ToList()
					select new HotThreadInformation
					{
						NodeName = node,
						NodeId = nodeId,
						Threads = threads,
						Hosts = hosts
					};
				return new NodesHotThreadsResponse(info.ToList());
			}

		}
        /// <summary>
        /// Because the nodes.hot_threads endpoint returns plain text instead of JSON, we have to
        /// manually parse the response text into a typed response object.
        /// </summary>
        private NodesHotThreadsResponse DeserializeNodesHotThreadResponse(IElasticsearchResponse response, Stream stream)
        {
            var typedResponse     = new NodesHotThreadsResponse();
            var plainTextResponse = Encoding.UTF8.GetString(response.ResponseRaw);

            // If the response doesn't start with :::, which is the pattern that delimits
            // each node section in the response, then the response format isn't recognized.
            // Just return an empty response object. This is especially useful when unit
            // testing against an in-memory connection where you won't get a real response.
            if (!plainTextResponse.StartsWith(":::"))
            {
                return(typedResponse);
            }

            var sections = plainTextResponse.Split(new string[] { ":::" }, StringSplitOptions.RemoveEmptyEntries);

            foreach (var section in sections)
            {
                var sectionLines = section.Split(new string[] { "\n   \n" }, StringSplitOptions.None);

                if (sectionLines.Length > 0)
                {
                    var hotThreadInfo = new HotThreadInformation
                    {
                        // First line contains the node name between [ ]
                        Node = sectionLines.First().Split('[')[1].TrimEnd(']'),
                        // The rest of the lines are hot threads
                        Threads = sectionLines.Skip(1).Take(sectionLines.Length - 1).ToList()
                    };

                    typedResponse.HotThreads.Add(hotThreadInfo);
                }
            }

            return(typedResponse);
        }
		/// <summary>
		/// Because the nodes.hot_threads endpoint returns plain text instead of JSON, we have to
		/// manually parse the response text into a typed response object.
		/// </summary>
		private NodesHotThreadsResponse DeserializeNodesHotThreadResponse(IElasticsearchResponse response, Stream stream)
		{
			var typedResponse = new NodesHotThreadsResponse();
			var plainTextResponse = Encoding.UTF8.GetString(response.ResponseRaw);

			// If the response doesn't start with :::, which is the pattern that delimits
			// each node section in the response, then the response format isn't recognized.
			// Just return an empty response object. This is especially useful when unit
			// testing against an in-memory connection where you won't get a real response.
			if (!plainTextResponse.StartsWith(":::"))
				return typedResponse;

			var sections = plainTextResponse.Split(new string[] { ":::" }, StringSplitOptions.RemoveEmptyEntries);

			foreach(var section in sections)
			{
				var sectionLines = section.Split(new string[] { "\n   \n" }, StringSplitOptions.None);

				if (sectionLines.Length > 0)
				{
					var hotThreadInfo = new HotThreadInformation
					{
						// First line contains the node name between [ ]
						Node = sectionLines.First().Split('[')[1].TrimEnd(']'),
						// The rest of the lines are hot threads
						Threads = sectionLines.Skip(1).Take(sectionLines.Length - 1).ToList()
					};

					typedResponse.HotThreads.Add(hotThreadInfo);
				}
			}

			return typedResponse;
		}