/** <inheritdoc/> */
        override public IGridClientFuture <IDictionary <K, V> > CacheGetAll <K, V>(String cacheName, ISet <GridClientCacheFlag> cacheFlags, IEnumerable <K> keys, Guid destNodeId)
        {
            Dbg.Assert(keys != null);

            GridClientCacheRequest req = new GridClientCacheRequest(CacheOp.GetAll, destNodeId);

            req.CacheName  = cacheName;
            req.CacheFlags = encodeCacheFlags(cacheFlags);
            req.Keys       = new HashSet <K>(keys);

            GridClientTcpRequestFuture <IDictionary <K, V> > fut = new GridClientTcpRequestFuture <IDictionary <K, V> >(req);

            fut.DoneConverter = o => {
                if (o == null)
                {
                    return(null);
                }

                var map = o as IDictionary;

                if (map == null)
                {
                    throw new ArgumentException("Expects dictionary, but received: " + o);
                }

                return(map.ToMap <K, V>());
            };

            makeRequest <IDictionary <K, V> >(fut);

            return(fut);
        }
        /** <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);
        }
        /**
         * <summary>
         * Makes request to server via tcp protocol and returns a future that will be completed when
         * response is received.</summary>
         *
         * <param name="msg">Message to request,</param>
         * <returns>Response object.</returns>
         * <exception cref="GridClientConnectionResetException">If request failed.</exception>
         * <exception cref="GridClientClosedException">If client was closed.</exception>
         */
        private IGridClientFuture <T> makeRequest <T>(GridClientRequest msg)
        {
            Dbg.Assert(msg != null);

            GridClientTcpRequestFuture <T> res = new GridClientTcpRequestFuture <T>(msg);

            makeRequest(res);

            return(res);
        }
        /** <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);
        }
        /** <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>
         * Makes request to server via tcp protocol and returns a future
         * that will be completed when response is received.</summary>
         *
         * <param name="fut">Future that will handle response.</param>
         * <returns>Response object.</returns>
         * <exception cref="GridClientConnectionResetException">If request failed.</exception>
         * <exception cref="GridClientClosedException">If client was closed.</exception>
         */
        private void makeRequest <T>(GridClientTcpRequestFuture <T> fut)
        {
            long reqId;

            // Validate this connection is alive.
            closeLock.AcquireReaderLock(Timeout.Infinite);

            try {
                if (closed)
                {
                    if (closedIdle)
                    {
                        throw new GridClientConnectionIdleClosedException("Connection was closed by idle thread (will " +
                                                                          "reconnect): " + ServerAddress);
                    }

                    throw new GridClientConnectionResetException("Failed to perform request (connection was closed before " +
                                                                 "message is sent): " + ServerAddress);
                }

                // Update request properties.
                reqId = Interlocked.Increment(ref reqIdCntr);

                fut.Message.RequestId    = reqId;
                fut.Message.ClientId     = ClientId;
                fut.Message.SessionToken = sesTok;

                // Add request to pending queue.
                lock (pendingReqs) {
                    pendingReqs.Add(reqId, fut);
                }
            }
            finally {
                closeLock.ReleaseReaderLock();
            }

            sendPacket(fut.Message);
        }
        /** <inheritdoc/> */
        override public IGridClientFuture <IList <String> > Log(String path, int fromLine, int toLine, Guid destNodeId)
        {
            GridClientLogRequest msg = new GridClientLogRequest(destNodeId);

            msg.From = fromLine;
            msg.To   = toLine;
            msg.Path = path;

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

            fut.DoneConverter = o => {
                if (o == null)
                {
                    return(null);
                }

                var list = o as IList;

                if (list == null)
                {
                    throw new ArgumentException("Expects string's collection, but received: " + o);
                }

                var result = new List <String>();

                foreach (var i in list)
                {
                    result.Add(i as String);
                }

                return(result);
            };

            makeRequest <IList <String> >(fut);

            return(fut);
        }
        /** <inheritdoc/> */
        override public IGridClientFuture <IGridClientDataMetrics> CacheMetrics(String cacheName, ISet <GridClientCacheFlag> cacheFlags, Guid destNodeId)
        {
            GridClientCacheRequest req = new GridClientCacheRequest(CacheOp.Metrics, destNodeId);

            req.CacheName  = cacheName;
            req.CacheFlags = encodeCacheFlags(cacheFlags);

            GridClientTcpRequestFuture <IGridClientDataMetrics> fut = new GridClientTcpRequestFuture <IGridClientDataMetrics>(req);

            fut.DoneConverter = o => {
                if (o == null)
                {
                    return(null);
                }

                var map = o as IDictionary;

                if (map == null)
                {
                    throw new ArgumentException("Expects dictionary, but received: " + o);
                }

                var m = new Dictionary <String, Object>();

                foreach (DictionaryEntry entry in map)
                {
                    m[(String)entry.Key] = entry.Value;
                }

                return(parseCacheMetrics(m));
            };

            makeRequest <IGridClientDataMetrics>(fut);

            return(fut);
        }