/** <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);
        }
        /**
         * <summary>
         * Wraps cache request into a protocol message.</summary>
         *
         * <param name="req">Cache request that need to be wrapped.</param>
         * <returns>Wrapped message.</returns>
         */
        private static GridClientCacheRequest WrapCacheRequest(ProtoRequest req)
        {
            ProtoCacheRequest data = ProtoCacheRequest.ParseFrom(req.Body);

            GridClientCacheRequest bean = new GridClientCacheRequest((GridClientCacheRequestOperation)data.Operation, Guid.Empty);

            if (data.HasCacheName)
            {
                bean.CacheName = data.CacheName;
            }

            if (data.HasKey)
            {
                bean.Key = WrapObject(data.Key);
            }

            if (data.HasValue)
            {
                bean.Value = WrapObject(data.Value);
            }

            if (data.HasValue2)
            {
                bean.Value2 = WrapObject(data.Value2);
            }

            if (data.HasValues)
            {
                bean.Values = WrapMap(data.Values);
            }

            return(WrapRequest(bean, req));
        }
        /** <inheritdoc/> */
        override public IGridClientFuture <Boolean> CacheRemove <K>(String cacheName, ISet <GridClientCacheFlag> cacheFlags, K key, Guid destNodeId)
        {
            GridClientCacheRequest req = new GridClientCacheRequest(CacheOp.Rmv, destNodeId);

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

            return(makeRequest <Boolean>(req));
        }
        /** <inheritdoc/> */
        override public IGridClientFuture <Boolean> CacheRemoveAll <K>(String cacheName, ISet <GridClientCacheFlag> cacheFlags, IEnumerable <K> keys, Guid destNodeId)
        {
            Dbg.Assert(keys != null);

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

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

            return(makeRequest <Boolean>(req));
        }
        /** <inheritdoc/> */
        override public IGridClientFuture <Boolean> CachePutAll <K, V>(String cacheName, ISet <GridClientCacheFlag> cacheFlags, IDictionary <K, V> entries, Guid destNodeId)
        {
            Dbg.Assert(entries != null);

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

            req.CacheName  = cacheName;
            req.CacheFlags = encodeCacheFlags(cacheFlags);
            req.Values     = entries.ToMap();

            return(makeRequest <Boolean>(req));
        }
        /** <inheritdoc /> */
        override public IGridClientFuture <Boolean> CacheCompareAndSet <K, V>(String cacheName, ISet <GridClientCacheFlag> cacheFlags, K key, V val1, V val2, Guid destNodeId)
        {
            Dbg.Assert(key != null);

            GridClientCacheRequest msg = new GridClientCacheRequest(CacheOp.Cas, destNodeId);

            msg.CacheName  = cacheName;
            msg.CacheFlags = encodeCacheFlags(cacheFlags);
            msg.Key        = key;
            msg.Value      = val1;
            msg.Value2     = val2;

            return(makeRequest <Boolean>(msg));
        }
        /** <inheritdoc/> */
        override public IGridClientFuture <Boolean> CachePrepend <K, V>(String cacheName, ISet <GridClientCacheFlag> cacheFlags, K key, V val, Guid destNodeId)
        {
            Dbg.Assert(key != null);
            Dbg.Assert(val != null);

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

            req.CacheName  = cacheName;
            req.CacheFlags = encodeCacheFlags(cacheFlags);
            req.Key        = key;
            req.Value      = val;

            return(makeRequest <Boolean>(req));
        }
        /**
         * <summary>
         * Wraps cache request into a protocol message.</summary>
         *
         * <param name="req">Cache request that need to be wrapped.</param>
         * <returns>Wrapped message.</returns>
         */
        private static ProtoRequest WrapCacheRequest(GridClientCacheRequest req)
        {
            ProtoCacheRequest.Builder builder = ProtoCacheRequest.CreateBuilder()
                                                .SetOperation((ProtoCacheRequest.Types.GridCacheOperation)req.Operation);

            if (req.CacheName != null)
            {
                builder.SetCacheName(req.CacheName);
            }

            if (req.CacheFlags != 0)
            {
                builder.SetCacheFlagsOn(req.CacheFlags);
            }

            if (req.Key != null)
            {
                builder.SetKey(WrapObject(req.Key));
            }

            if (req.Value != null)
            {
                builder.SetValue(WrapObject(req.Value));
            }

            if (req.Value2 != null)
            {
                builder.SetValue2(WrapObject(req.Value2));
            }

            if (req.Values != null)
            {
                builder.SetValues(WrapMap(req.Values));
            }

            return(WrapRequest(req, builder.Build()));
        }
        /** <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);
        }