/** <inheritdoc/> */
        override public IGridClientFuture <IList <IGridClientNode> > Topology(bool includeAttrs, bool includeMetrics, Guid destNodeId)
        {
            GridClientTopologyRequest msg = new GridClientTopologyRequest(destNodeId);

            msg.IncludeAttributes = includeAttrs;
            msg.IncludeMetrics    = includeMetrics;

            GridClientTcpRequestFuture <IList <IGridClientNode> > fut = new GridClientTcpRequestFuture <IList <IGridClientNode> >(msg);

            fut.DoneConverter = o => {
                var it = o as IEnumerable;

                if (it == null)
                {
                    return(null);
                }

                IList <IGridClientNode> nodes = new List <IGridClientNode>();

                foreach (Object bean in it)
                {
                    nodes.Add(nodeBeanToNode((GridClientNodeBean)bean));
                }

                Top.UpdateTopology(nodes);

                return(nodes);
            };

            makeRequest(fut);

            return(fut);
        }
        /** <inheritdoc/> */
        override public IGridClientFuture <IGridClientNode> Node(String ipAddr, bool includeAttrs, bool includeMetrics, Guid destNodeId)
        {
            GridClientTopologyRequest msg = new GridClientTopologyRequest(destNodeId);

            msg.NodeIP            = ipAddr;
            msg.IncludeAttributes = includeAttrs;
            msg.IncludeMetrics    = includeMetrics;

            GridClientTcpRequestFuture <IGridClientNode> fut = new GridClientTcpRequestFuture <IGridClientNode>(msg);

            fut.DoneConverter = this.futureNodeConverter;

            makeRequest(fut);

            return(fut);
        }
        /**
         * <summary>
         * Wraps topology request into a protocol message.</summary>
         *
         * <param name="req">Topology request that need to be wrapped.</param>
         * <returns>Wrapped message.</returns>
         */
        private static ProtoRequest WrapTopologyRequest(GridClientTopologyRequest req)
        {
            ProtoTopologyRequest.Builder builder = ProtoTopologyRequest.CreateBuilder()
                                                   .SetIncludeAttributes(req.IncludeAttributes)
                                                   .SetIncludeMetrics(req.IncludeMetrics);

            if (req.NodeId != null && !req.NodeId.Equals(ZERO_GUID))
            {
                builder.SetNodeId(req.NodeId.ToString());
            }

            if (req.NodeIP != null)
            {
                builder.SetNodeIp(req.NodeIP);
            }

            return(WrapRequest(req, builder.Build()));
        }
        /** <inheritdoc/> */
        override public IGridClientFuture <IGridClientNode> Node(Guid id, bool includeAttrs, bool includeMetrics, Guid destNodeId)
        {
            Dbg.Assert(id != null);

            GridClientTcpRequestFuture <IGridClientNode> fut;

            // Return request that is in progress.
            if (refreshNodeReqs.TryGetValue(id, out fut))
            {
                return(fut);
            }

            GridClientTopologyRequest msg = new GridClientTopologyRequest(destNodeId);

            msg.NodeId            = id;
            msg.IncludeAttributes = includeAttrs;
            msg.IncludeMetrics    = includeMetrics;

            fut = new GridClientTcpRequestFuture <IGridClientNode>(msg);

            fut.DoneCallback = () => {
                GridClientTcpRequestFuture <IGridClientNode> removed;

                //Clean up the node id requests map.
                Dbg.Assert(refreshNodeReqs.TryRemove(id, out removed));

                Dbg.Assert(fut.Equals(removed));
            };

            fut.DoneConverter = this.futureNodeConverter;

            GridClientTcpRequestFuture <IGridClientNode> actual = refreshNodeReqs.GetOrAdd(id, fut);

            // If another thread put actual request into cache.
            if (!actual.Equals(fut))
            {
                // Ignore created future, use one from cache.
                return(actual);
            }

            makeRequest <IGridClientNode>(fut);

            return(fut);
        }
        /**
         * <summary>
         * Wraps topology request into a protocol message.</summary>
         *
         * <param name="req">Topology request that need to be wrapped.</param>
         * <returns>Wrapped message.</returns>
         */
        private static GridClientTopologyRequest WrapTopologyRequest(ProtoRequest req)
        {
            ProtoTopologyRequest data = ProtoTopologyRequest.ParseFrom(req.Body);

            GridClientTopologyRequest bean = new GridClientTopologyRequest(Guid.Empty);

            bean.IncludeAttributes = data.IncludeAttributes;
            bean.IncludeMetrics    = data.IncludeMetrics;

            if (data.HasNodeId)
            {
                bean.NodeId = Guid.Parse(data.NodeId);
            }

            if (data.HasNodeIp)
            {
                bean.NodeIP = data.NodeIp;
            }

            return(WrapRequest(bean, req));
        }