You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by vo...@apache.org on 2015/09/21 16:27:46 UTC

[50/52] [partial] ignite git commit: IGNITE-1513: Moved .Net.

http://git-wip-us.apache.org/repos/asf/ignite/blob/f2eb16cd/modules/platform/dotnet/Apache.Ignite.Core/Cache/Event/ICacheEntryEventFilter.cs
----------------------------------------------------------------------
diff --git a/modules/platform/dotnet/Apache.Ignite.Core/Cache/Event/ICacheEntryEventFilter.cs b/modules/platform/dotnet/Apache.Ignite.Core/Cache/Event/ICacheEntryEventFilter.cs
new file mode 100644
index 0000000..98f5c5a
--- /dev/null
+++ b/modules/platform/dotnet/Apache.Ignite.Core/Cache/Event/ICacheEntryEventFilter.cs
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.Ignite.Core.Cache.Event
+{
+    /// <summary>
+    /// Cache entry event filter.
+    /// </summary>
+    public interface ICacheEntryEventFilter<TK, TV>
+    {
+        /// <summary>
+        /// Evaluates cache entry event.
+        /// </summary>
+        /// <param name="evt">Event.</param>
+        bool Evaluate(ICacheEntryEvent<TK, TV> evt);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/f2eb16cd/modules/platform/dotnet/Apache.Ignite.Core/Cache/Event/ICacheEntryEventListener.cs
----------------------------------------------------------------------
diff --git a/modules/platform/dotnet/Apache.Ignite.Core/Cache/Event/ICacheEntryEventListener.cs b/modules/platform/dotnet/Apache.Ignite.Core/Cache/Event/ICacheEntryEventListener.cs
new file mode 100644
index 0000000..76ae04c
--- /dev/null
+++ b/modules/platform/dotnet/Apache.Ignite.Core/Cache/Event/ICacheEntryEventListener.cs
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.Ignite.Core.Cache.Event
+{
+    using System.Collections.Generic;
+
+    /// <summary>
+    /// Cache entry event listener.
+    /// </summary>
+    public interface ICacheEntryEventListener<TK, TV>
+    {
+        /// <summary>
+        /// Event callback.
+        /// </summary>
+        /// <param name="evts">Events.</param>
+        void OnEvent(IEnumerable<ICacheEntryEvent<TK, TV>> evts);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/f2eb16cd/modules/platform/dotnet/Apache.Ignite.Core/Cache/Expiry/ExpiryPolicy.cs
----------------------------------------------------------------------
diff --git a/modules/platform/dotnet/Apache.Ignite.Core/Cache/Expiry/ExpiryPolicy.cs b/modules/platform/dotnet/Apache.Ignite.Core/Cache/Expiry/ExpiryPolicy.cs
new file mode 100644
index 0000000..1feccbd
--- /dev/null
+++ b/modules/platform/dotnet/Apache.Ignite.Core/Cache/Expiry/ExpiryPolicy.cs
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.Ignite.Core.Cache.Expiry
+{
+    using System;
+
+    /// <summary>
+    /// Default expiry policy implementation with all durations deinfed explicitly.
+    /// </summary>
+    public class ExpiryPolicy : IExpiryPolicy
+    {
+        /** Expiry for create. */
+        private readonly TimeSpan? _create;
+
+        /** Expiry for update. */
+        private readonly TimeSpan? _update;
+
+        /** Expiry for access. */
+        private readonly TimeSpan? _access;
+
+        /// <summary>
+        /// Constructor.
+        /// </summary>
+        /// <param name="create">Expiry for create.</param>
+        /// <param name="update">Expiry for udpate.</param>
+        /// <param name="access">Expiry for access.</param>
+        public ExpiryPolicy(TimeSpan? create, TimeSpan? update, TimeSpan? access)
+        {
+            _create = create;
+            _update = update;
+            _access = access;
+        }
+
+        /// <summary>
+        /// Gets expiry for create operation.
+        /// <para />
+        /// If <c>TimeSpan.ZERO</c> is returned, cache entry is considered immediately expired
+        /// and will not be added to cache. 
+        /// <para />
+        /// If <c>null</c> is returned, no change to previously understood expiry is performed.
+        /// </summary>
+        /// <returns>Expiry for create opeartion.</returns>
+        public TimeSpan? GetExpiryForCreate()
+        {
+            return _create;
+        }
+
+        /// <summary>
+        /// Gets expiry for update operation.
+        /// <para />
+        /// If <c>TimeSpan.ZERO</c> is returned, cache entry is considered immediately expired.
+        /// <para />
+        /// If <c>null</c> is returned, no change to previously understood expiry is performed.
+        /// </summary>
+        /// <returns>Expiry for update operation.</returns>
+        public TimeSpan? GetExpiryForUpdate()
+        {
+            return _update;
+        }
+
+        /// <summary>
+        /// Gets expiry for access operation.
+        /// <para />
+        /// If <c>TimeSpan.ZERO</c> is returned, cache entry is considered immediately expired.
+        /// <para />
+        /// If <c>null</c> is returned, no change to previously understood expiry is performed.
+        /// </summary>
+        /// <returns>Expiry for access operation.</returns>
+        public TimeSpan? GetExpiryForAccess()
+        {
+            return _access;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/f2eb16cd/modules/platform/dotnet/Apache.Ignite.Core/Cache/Expiry/IExpiryPolicy.cs
----------------------------------------------------------------------
diff --git a/modules/platform/dotnet/Apache.Ignite.Core/Cache/Expiry/IExpiryPolicy.cs b/modules/platform/dotnet/Apache.Ignite.Core/Cache/Expiry/IExpiryPolicy.cs
new file mode 100644
index 0000000..ff627ae
--- /dev/null
+++ b/modules/platform/dotnet/Apache.Ignite.Core/Cache/Expiry/IExpiryPolicy.cs
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.Ignite.Core.Cache.Expiry
+{
+    using System;
+
+    /// <summary>
+    /// Defines functions to determine when cache entries will expire based on
+    /// creation, access and modification operations.
+    /// </summary>
+    public interface IExpiryPolicy
+    {
+        /// <summary>
+        /// Gets expiry for create operation.
+        /// <para />
+        /// If <c>TimeSpan.ZERO</c> is returned, cache entry is considered immediately expired
+        /// and will not be added to cache. 
+        /// <para />
+        /// If <c>null</c> is returned, no change to previously understood expiry is performed.
+        /// </summary>
+        /// <returns>Expiry for create opeartion.</returns>
+        TimeSpan? GetExpiryForCreate();
+
+        /// <summary>
+        /// Gets expiry for update operation.
+        /// <para />
+        /// If <c>TimeSpan.ZERO</c> is returned, cache entry is considered immediately expired.
+        /// <para />
+        /// If <c>null</c> is returned, no change to previously understood expiry is performed.
+        /// </summary>
+        /// <returns>Expiry for update operation.</returns>
+        TimeSpan? GetExpiryForUpdate();
+
+        /// <summary>
+        /// Gets expiry for access operation.
+        /// <para />
+        /// If <c>TimeSpan.ZERO</c> is returned, cache entry is considered immediately expired.
+        /// <para />
+        /// If <c>null</c> is returned, no change to previously understood expiry is performed.
+        /// </summary>
+        /// <returns>Expiry for access operation.</returns>
+        TimeSpan? GetExpiryForAccess();
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/f2eb16cd/modules/platform/dotnet/Apache.Ignite.Core/Cache/ICache.cs
----------------------------------------------------------------------
diff --git a/modules/platform/dotnet/Apache.Ignite.Core/Cache/ICache.cs b/modules/platform/dotnet/Apache.Ignite.Core/Cache/ICache.cs
new file mode 100644
index 0000000..5116839
--- /dev/null
+++ b/modules/platform/dotnet/Apache.Ignite.Core/Cache/ICache.cs
@@ -0,0 +1,542 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.Ignite.Core.Cache
+{
+    using System;
+    using System.Collections;
+    using System.Collections.Generic;
+    using Apache.Ignite.Core.Cache.Expiry;
+    using Apache.Ignite.Core.Cache.Query;
+    using Apache.Ignite.Core.Cache.Query.Continuous;
+    using Apache.Ignite.Core.Cache.Store;
+    using Apache.Ignite.Core.Common;
+    using Apache.Ignite.Core.Transactions;
+
+    /// <summary>
+    /// Main entry point for Ignite cache APIs. You can get a named cache by calling
+    /// <see cref="IIgnite.GetCache{TK,TV}"/> method.
+    /// <para />
+    /// Cache API supports distributed transactions. All <c>Get(...)</c>, <c>Put(...)</c>, <c>Replace(...)</c>,
+    /// and <c>Remove(...)</c> operations are transactional and will participate in an ongoing transaction,
+    /// if any. Other methods like <c>Peek(...)</c> or various <c>Contains(...)</c> methods may
+    /// be transaction-aware, i.e. check in-transaction entries first, but will not affect the current
+    /// state of transaction. See <see cref="ITransaction"/> documentation for more information
+    /// about transactions.
+    /// <para />
+    /// Neither <c>null</c> keys or values are allowed to be stored in cache. If a <c>null</c> value
+    /// happens to be in cache (e.g. after invalidation or remove), then cache will treat this case
+    /// as there is no value at all.
+    /// <para />
+    /// Note that cache is generic and you can only work with provided key and value types. If cache also
+    /// contains keys or values of other types, any attempt to retrieve them will result in
+    /// <see cref="InvalidCastException"/>. Use <see cref="ICache{Object, Object}"/> in order to work with entries
+    /// of arbitrary types.
+    /// <para/>
+    /// All members are thread-safe and may be used concurrently from multiple threads.
+    /// </summary>
+    /// <typeparam name="TK">Key type.</typeparam>
+    /// <typeparam name="TV">Value type.</typeparam>
+    public interface ICache<TK, TV> : IAsyncSupport<ICache<TK, TV>>, IEnumerable<ICacheEntry<TK, TV>>
+    {
+        /// <summary>
+        /// Name of this cache (<c>null</c> for default cache).
+        /// </summary>
+        string Name { get; }
+
+        /// <summary>
+        /// Ignite hosting this cache.
+        /// </summary>
+        IIgnite Ignite { get; }
+
+        /// <summary>
+        /// Checks whether this cache contains no key-value mappings.
+        /// <para />
+        /// Semantically equals to <c>ICache.Size(CachePeekMode.PRIMARY) == 0</c>.
+        /// </summary>
+        bool IsEmpty();
+
+        /// <summary>
+        /// Gets a value indicating whether to keep values in portable form.
+        /// </summary>
+        bool IsKeepPortable { get; }
+
+        /// <summary>
+        /// Get another cache instance with read-through and write-through behavior disabled.
+        /// </summary>
+        /// <returns>Cache with read-through and write-through behavior disabled.</returns>
+        ICache<TK, TV> WithSkipStore();
+
+        /// <summary>
+        /// Returns cache with the specified expired policy set. This policy will be used for each operation
+        /// invoked on the returned cache.
+        /// <para />
+        /// Expiry durations for each operation are calculated only once and then used as constants. Please
+        /// consider this when implementing customg expiry policy implementations.
+        /// </summary>
+        /// <param name="plc">Expiry policy to use.</param>
+        /// <returns>Cache instance with the specified expiry policy set.</returns>
+        ICache<TK, TV> WithExpiryPolicy(IExpiryPolicy plc);
+
+        /// <summary>
+        /// Gets cache with KeepPortable mode enabled, changing key and/or value types if necessary.
+        /// You can only change key/value types when transitioning from non-portable to portable cache;
+        /// Changing type of portable cache is not allowed and will throw an <see cref="InvalidOperationException"/>
+        /// </summary>
+        /// <typeparam name="TK1">Key type in portable mode.</typeparam>
+        /// <typeparam name="TV1">Value type in protable mode.</typeparam>
+        /// <returns>Cache instance with portable mode enabled.</returns>
+        ICache<TK1, TV1> WithKeepPortable<TK1, TV1>();
+
+        /// <summary>
+        /// Executes <see cref="LocalLoadCache"/> on all cache nodes.
+        /// </summary>
+        /// <param name="p">
+        /// Optional predicate. If provided, will be used to filter values to be put into cache.
+        /// </param>
+        /// <param name="args">
+        /// Optional user arguments to be passed into <see cref="ICacheStore.LoadCache" />.
+        /// </param>
+        [AsyncSupported]
+        void LoadCache(ICacheEntryFilter<TK, TV> p, params object[] args);
+
+        /// <summary>
+        /// Delegates to <see cref="ICacheStore.LoadCache" /> method to load state 
+        /// from the underlying persistent storage. The loaded values will then be given 
+        /// to the optionally passed in predicate, and, if the predicate returns true, 
+        /// will be stored in cache. If predicate is null, then all loaded values will be stored in cache.
+        /// </summary>
+        /// <param name="p">
+        /// Optional predicate. If provided, will be used to filter values to be put into cache.
+        /// </param>
+        /// <param name="args">
+        /// Optional user arguments to be passed into <see cref="ICacheStore.LoadCache" />.
+        /// </param>
+        [AsyncSupported]
+        void LocalLoadCache(ICacheEntryFilter<TK, TV> p, params object[] args);
+
+        /// <summary>
+        /// Check if cache contains mapping for this key.
+        /// </summary>
+        /// <param name="key">Key.</param>
+        /// <returns>True if cache contains mapping for this key.</returns>
+        [AsyncSupported]
+        bool ContainsKey(TK key);
+
+        /// <summary>
+        /// Check if cache contains mapping for these keys.
+        /// </summary>
+        /// <param name="keys">Keys.</param>
+        /// <returns>True if cache contains mapping for all these keys.</returns>
+        [AsyncSupported]
+        bool ContainsKeys(IEnumerable<TK> keys);
+
+        /// <summary>
+        /// Peeks at cached value using optional set of peek modes. This method will sequentially
+        /// iterate over given peek modes, and try to peek at value using each peek mode. Once a
+        /// non-null value is found, it will be immediately returned.
+        /// This method does not participate in any transactions, however, it may peek at transactional
+        /// value depending on the peek modes used.
+        /// </summary>
+        /// <param name="key">Key.</param>
+        /// <param name="modes">Peek modes.</param>
+        /// <returns>Peeked value.</returns>
+        TV LocalPeek(TK key, params CachePeekMode[] modes);
+
+        /// <summary>
+        /// Retrieves value mapped to the specified key from cache.
+        /// If the value is not present in cache, then it will be looked up from swap storage. If
+        /// it's not present in swap, or if swap is disable, and if read-through is allowed, value
+        /// will be loaded from persistent store.
+        /// This method is transactional and will enlist the entry into ongoing transaction if there is one.
+        /// </summary>
+        /// <param name="key">Key.</param>
+        /// <returns>Value.</returns>
+        [AsyncSupported]
+        TV Get(TK key);
+
+        /// <summary>
+        /// Retrieves values mapped to the specified keys from cache.
+        /// If some value is not present in cache, then it will be looked up from swap storage. If
+        /// it's not present in swap, or if swap is disabled, and if read-through is allowed, value
+        /// will be loaded from persistent store.
+        /// This method is transactional and will enlist the entry into ongoing transaction if there is one.
+        /// </summary>
+        /// <param name="keys">Keys.</param>
+        /// <returns>Map of key-value pairs.</returns>
+        [AsyncSupported]
+        IDictionary<TK, TV> GetAll(IEnumerable<TK> keys);
+
+        /// <summary>
+        /// Associates the specified value with the specified key in the cache.
+        /// <para />
+        /// If the cache previously contained a mapping for the key, 
+        /// the old value is replaced by the specified value.
+        /// </summary>
+        /// <param name="key">Key with which the specified value is to be associated.</param>
+        /// <param name="val">Value to be associated with the specified key.</param>
+        [AsyncSupported]
+        void Put(TK key, TV val);
+
+        /// <summary>
+        /// Associates the specified value with the specified key in this cache,
+        /// returning an existing value if one existed.
+        /// </summary>
+        /// <param name="key">Key with which the specified value is to be associated.</param>
+        /// <param name="val">Value to be associated with the specified key.</param>
+        /// <returns>
+        /// The value associated with the key at the start of the operation or null if none was associated.
+        /// </returns>
+        [AsyncSupported]
+        TV GetAndPut(TK key, TV val);
+        
+        /// <summary>
+        /// Atomically replaces the value for a given key if and only if there is a value currently mapped by the key.
+        /// </summary>
+        /// <param name="key">Key with which the specified value is to be associated.</param>
+        /// <param name="val">Value to be associated with the specified key.</param>
+        /// <returns>
+        /// The previous value associated with the specified key, or null if there was no mapping for the key.
+        /// </returns>
+        [AsyncSupported]
+        TV GetAndReplace(TK key, TV val);
+
+        /// <summary>
+        /// Atomically removes the entry for a key only if currently mapped to some value.
+        /// </summary>
+        /// <param name="key">Key with which the specified value is associated.</param>
+        /// <returns>The value if one existed or null if no mapping existed for this key.</returns>
+        [AsyncSupported]
+        TV GetAndRemove(TK key);
+
+        /// <summary>
+        /// Atomically associates the specified key with the given value if it is not already associated with a value.
+        /// </summary>
+        /// <param name="key">Key with which the specified value is to be associated.</param>
+        /// <param name="val">Value to be associated with the specified key.</param>
+        /// <returns>True if a value was set.</returns>
+        [AsyncSupported]
+        bool PutIfAbsent(TK key, TV val);
+
+        /// <summary>
+        /// Stores given key-value pair in cache only if cache had no previous mapping for it.
+        /// If cache previously contained value for the given key, then this value is returned.
+        /// In case of PARTITIONED or REPLICATED caches, the value will be loaded from the primary node,
+        /// which in its turn may load the value from the swap storage, and consecutively, if it's not
+        /// in swap, from the underlying persistent storage.
+        /// If the returned value is not needed, method putxIfAbsent() should be used instead of this one to
+        /// avoid the overhead associated with returning of the previous value.
+        /// If write-through is enabled, the stored value will be persisted to store.
+        /// This method is transactional and will enlist the entry into ongoing transaction if there is one.
+        /// </summary>
+        /// <param name="key">Key to store in cache.</param>
+        /// <param name="val">Value to be associated with the given key.</param>
+        /// <returns>
+        /// Previously contained value regardless of whether put happened or not (null if there was no previous value).
+        /// </returns>
+        [AsyncSupported]
+        TV GetAndPutIfAbsent(TK key, TV val);
+
+        /// <summary>
+        /// Stores given key-value pair in cache only if there is a previous mapping for it.
+        /// If cache previously contained value for the given key, then this value is returned.
+        /// In case of PARTITIONED or REPLICATED caches, the value will be loaded from the primary node,
+        /// which in its turn may load the value from the swap storage, and consecutively, if it's not
+        /// in swap, rom the underlying persistent storage.
+        /// If write-through is enabled, the stored value will be persisted to store.
+        /// This method is transactional and will enlist the entry into ongoing transaction if there is one.
+        /// </summary>
+        /// <param name="key">Key to store in cache.</param>
+        /// <param name="val">Value to be associated with the given key.</param>
+        /// <returns>True if the value was replaced.</returns>
+        [AsyncSupported]
+        bool Replace(TK key, TV val);
+
+        /// <summary>
+        /// Stores given key-value pair in cache only if only if the previous value is equal to the
+        /// old value passed as argument.
+        /// This method is transactional and will enlist the entry into ongoing transaction if there is one.
+        /// </summary>
+        /// <param name="key">Key to store in cache.</param>
+        /// <param name="oldVal">Old value to match.</param>
+        /// <param name="newVal">Value to be associated with the given key.</param>
+        /// <returns>True if replace happened, false otherwise.</returns>
+        [AsyncSupported]
+        bool Replace(TK key, TV oldVal, TV newVal);
+
+        /// <summary>
+        /// Stores given key-value pairs in cache.
+        /// If write-through is enabled, the stored values will be persisted to store.
+        /// This method is transactional and will enlist the entry into ongoing transaction if there is one.
+        /// </summary>
+        /// <param name="vals">Key-value pairs to store in cache.</param>
+        [AsyncSupported]
+        void PutAll(IDictionary<TK, TV> vals);
+
+        /// <summary>
+        /// Attempts to evict all entries associated with keys. Note, that entry will be evicted only 
+        /// if it's not used (not participating in any locks or transactions).
+        /// </summary>
+        /// <param name="keys">Keys to evict from cache.</param>
+        void LocalEvict(IEnumerable<TK> keys);
+
+        /// <summary>
+        /// Clears the contents of the cache, without notifying listeners or CacheWriters.
+        /// </summary>
+        [AsyncSupported]
+        void Clear();
+
+        /// <summary>
+        /// Clear entry from the cache and swap storage, without notifying listeners or CacheWriters.
+        /// Entry is cleared only if it is not currently locked, and is not participating in a transaction.
+        /// </summary>
+        /// <param name="key">Key to clear.</param>
+        [AsyncSupported]
+        void Clear(TK key);
+
+        /// <summary>
+        /// Clear entries from the cache and swap storage, without notifying listeners or CacheWriters.
+        /// Entry is cleared only if it is not currently locked, and is not participating in a transaction.
+        /// </summary>
+        /// <param name="keys">Keys to clear.</param>
+        [AsyncSupported]
+        void ClearAll(IEnumerable<TK> keys);
+
+        /// <summary>
+        /// Clear entry from the cache and swap storage, without notifying listeners or CacheWriters.
+        /// Entry is cleared only if it is not currently locked, and is not participating in a transaction.
+        /// <para />
+        /// Note that this operation is local as it merely clears
+        /// an entry from local cache, it does not remove entries from remote caches.
+        /// </summary>
+        /// <param name="key">Key to clear.</param>
+        void LocalClear(TK key);
+
+        /// <summary>
+        /// Clear entries from the cache and swap storage, without notifying listeners or CacheWriters.
+        /// Entry is cleared only if it is not currently locked, and is not participating in a transaction.
+        /// <para />
+        /// Note that this operation is local as it merely clears
+        /// entries from local cache, it does not remove entries from remote caches.
+        /// </summary>
+        /// <param name="keys">Keys to clear.</param>
+        void LocalClearAll(IEnumerable<TK> keys);
+
+        /// <summary>
+        /// Removes given key mapping from cache. If cache previously contained value for the given key,
+        /// then this value is returned. In case of PARTITIONED or REPLICATED caches, the value will be
+        /// loaded from the primary node, which in its turn may load the value from the disk-based swap
+        /// storage, and consecutively, if it's not in swap, from the underlying persistent storage.
+        /// If the returned value is not needed, method removex() should always be used instead of this
+        /// one to avoid the overhead associated with returning of the previous value.
+        /// If write-through is enabled, the value will be removed from store.
+        /// This method is transactional and will enlist the entry into ongoing transaction if there is one.
+        /// </summary>
+        /// <param name="key">Key whose mapping is to be removed from cache.</param>
+        /// <returns>False if there was no matching key.</returns>
+        [AsyncSupported]
+        bool Remove(TK key);
+
+        /// <summary>
+        /// Removes given key mapping from cache if one exists and value is equal to the passed in value.
+        /// If write-through is enabled, the value will be removed from store.
+        /// This method is transactional and will enlist the entry into ongoing transaction if there is one.
+        /// </summary>
+        /// <param name="key">Key whose mapping is to be removed from cache.</param>
+        /// <param name="val">Value to match against currently cached value.</param>
+        /// <returns>True if entry was removed, false otherwise.</returns>
+        [AsyncSupported]
+        bool Remove(TK key, TV val);
+
+        /// <summary>
+        /// Removes given key mappings from cache.
+        /// If write-through is enabled, the value will be removed from store.
+        /// This method is transactional and will enlist the entry into ongoing transaction if there is one.
+        /// </summary>
+        /// <param name="keys">Keys whose mappings are to be removed from cache.</param>
+        [AsyncSupported]
+        void RemoveAll(IEnumerable<TK> keys);
+
+        /// <summary>
+        /// Removes all mappings from cache.
+        /// If write-through is enabled, the value will be removed from store.
+        /// This method is transactional and will enlist the entry into ongoing transaction if there is one.
+        /// </summary>
+        [AsyncSupported]
+        void RemoveAll();
+
+        /// <summary>
+        /// Gets the number of all entries cached on this node.
+        /// </summary>
+        /// <param name="modes">Optional peek modes. If not provided, then total cache size is returned.</param>
+        /// <returns>Cache size on this node.</returns>
+        int GetLocalSize(params CachePeekMode[] modes);
+
+        /// <summary>
+        /// Gets the number of all entries cached across all nodes.
+        /// <para />
+        /// NOTE: this operation is distributed and will query all participating nodes for their cache sizes.
+        /// </summary>
+        /// <param name="modes">Optional peek modes. If not provided, then total cache size is returned.</param>
+        /// <returns>Cache size across all nodes.</returns>
+        [AsyncSupported]
+        int GetSize(params CachePeekMode[] modes);
+
+        /// <summary>
+        /// This method unswaps cache entries by given keys, if any, from swap storage into memory.
+        /// </summary>
+        /// <param name="keys">Keys to promote entries for.</param>
+        void LocalPromote(IEnumerable<TK> keys);
+        
+        /// <summary>
+        /// Queries cache.
+        /// </summary>
+        /// <param name="qry">Query.</param>
+        /// <returns>Cursor.</returns>
+        IQueryCursor<ICacheEntry<TK, TV>> Query(QueryBase qry);
+
+        /// <summary>
+        /// Queries separate entry fields.
+        /// </summary>
+        /// <param name="qry">SQL fields query.</param>
+        /// <returns>Cursor.</returns>
+        IQueryCursor<IList> QueryFields(SqlFieldsQuery qry);
+
+        /// <summary>
+        /// Start continuous query execution.
+        /// </summary>
+        /// <param name="qry">Continuous query.</param>
+        /// <returns>Handle to stop query execution.</returns>
+        IContinuousQueryHandle QueryContinuous(ContinuousQuery<TK, TV> qry);
+
+        /// <summary>
+        /// Start continuous query execution.
+        /// </summary>
+        /// <param name="qry">Continuous query.</param>
+        /// <param name="initialQry">
+        /// The initial query. This query will be executed before continuous listener is registered which allows 
+        /// to iterate through entries which have already existed at the time continuous query is executed.
+        /// </param>
+        /// <returns>
+        /// Handle to get initial query cursor or stop query execution.
+        /// </returns>
+        IContinuousQueryHandle<ICacheEntry<TK, TV>> QueryContinuous(ContinuousQuery<TK, TV> qry, QueryBase initialQry);
+        
+        /// <summary>
+        /// Get local cache entries.
+        /// </summary>
+        /// <param name="peekModes">Peek modes.</param>
+        /// <returns>Enumerable instance.</returns>
+        IEnumerable<ICacheEntry<TK, TV>> GetLocalEntries(params CachePeekMode[] peekModes);
+
+        /// <summary>
+        /// Invokes an <see cref="ICacheEntryProcessor{K, V, A, R}"/> against the 
+        /// <see cref="IMutableCacheEntry{K, V}"/> specified by the provided key. 
+        /// If an entry does not exist for the specified key, an attempt is made to load it (if a loader is configured) 
+        /// or a surrogate entry, consisting of the key with a null value is used instead.
+        /// </summary>
+        /// <typeparam name="TR">The type of the result.</typeparam>
+        /// <typeparam name="TA">The type of the argument.</typeparam>
+        /// <param name="key">The key.</param>
+        /// <param name="processor">The processor.</param>
+        /// <param name="arg">The argument.</param>
+        /// <returns>Result of the processing.</returns>
+        /// <exception cref="CacheEntryProcessorException">If an exception has occured during processing.</exception>
+        [AsyncSupported]
+        TR Invoke<TR, TA>(TK key, ICacheEntryProcessor<TK, TV, TA, TR> processor, TA arg);
+
+        /// <summary>
+        /// Invokes an <see cref="ICacheEntryProcessor{K, V, A, R}"/> against a set of keys.
+        /// If an entry does not exist for the specified key, an attempt is made to load it (if a loader is configured) 
+        /// or a surrogate entry, consisting of the key with a null value is used instead.
+        /// 
+        /// The order that the entries for the keys are processed is undefined. 
+        /// Implementations may choose to process the entries in any order, including concurrently.
+        /// Furthermore there is no guarantee implementations will use the same processor instance 
+        /// to process each entry, as the case may be in a non-local cache topology.
+        /// </summary>
+        /// <typeparam name="TR">The type of the result.</typeparam>
+        /// <typeparam name="TA">The type of the argument.</typeparam>
+        /// <param name="keys">The keys.</param>
+        /// <param name="processor">The processor.</param>
+        /// <param name="arg">The argument.</param>
+        /// <returns>
+        /// Map of <see cref="ICacheEntryProcessorResult{R}" /> of the processing per key, if any, 
+        /// defined by the <see cref="ICacheEntryProcessor{K,V,A,R}"/> implementation.  
+        /// No mappings will be returned for processors that return a null value for a key.
+        /// </returns>
+        /// <exception cref="CacheEntryProcessorException">If an exception has occured during processing.</exception>
+        [AsyncSupported]
+        IDictionary<TK, ICacheEntryProcessorResult<TR>> InvokeAll<TR, TA>(IEnumerable<TK> keys,
+            ICacheEntryProcessor<TK, TV, TA, TR> processor, TA arg);
+
+        /// <summary>
+        /// Creates an <see cref="ICacheLock"/> instance associated with passed key.
+        /// This method does not acquire lock immediately, you have to call appropriate method on returned instance.
+        /// </summary>
+        /// <param name="key">Key for lock.</param>
+        /// <returns>New <see cref="ICacheLock"/> instance associated with passed key.</returns>
+        ICacheLock Lock(TK key);
+
+        /// <summary>
+        /// Creates an <see cref="ICacheLock"/> instance associated with passed keys.
+        /// This method does not acquire lock immediately, you have to call appropriate method on returned instance.
+        /// </summary>
+        /// <param name="keys">Keys for lock.</param>
+        /// <returns>New <see cref="ICacheLock"/> instance associated with passed keys.</returns>
+        ICacheLock LockAll(IEnumerable<TK> keys);
+
+        /// <summary>
+        /// Checks if specified key is locked.
+        /// <para />
+        /// This is a local operation and does not involve any network trips
+        /// or access to persistent storage in any way.
+        /// </summary>
+        /// <param name="key">Key to check.</param>
+        /// <param name="byCurrentThread">
+        /// If true, checks that current thread owns a lock on this key; 
+        /// otherwise, checks that any thread on any node owns a lock on this key.
+        /// </param>
+        /// <returns>True if specified key is locked; otherwise, false.</returns>
+        bool IsLocalLocked(TK key, bool byCurrentThread);
+
+        /// <summary>
+        /// Gets snapshot metrics (statistics) for this cache.
+        /// </summary>
+        /// <returns>Cache metrics.</returns>
+        ICacheMetrics GetMetrics();
+
+        /// <summary>
+        /// Rebalances cache partitions. This method is usually used when rebalanceDelay configuration parameter 
+        /// has non-zero value. When many nodes are started or stopped almost concurrently, 
+        /// it is more efficient to delay rebalancing until the node topology is stable to make sure that no redundant 
+        /// re-partitioning happens.
+        /// <para />
+        /// In case of partitioned caches, for better efficiency user should usually make sure that new nodes get 
+        /// placed on the same place of consistent hash ring as the left nodes, and that nodes are restarted before
+        /// rebalanceDelay expires.
+        /// </summary>
+        /// <returns>Future that will be completed when rebalancing is finished.</returns>
+        IFuture Rebalance();
+
+        /// <summary>
+        /// Get another cache instance with no-retries behavior enabled.
+        /// </summary>
+        /// <returns>Cache with no-retries behavior enabled.</returns>
+        ICache<TK, TV> WithNoRetries();
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/f2eb16cd/modules/platform/dotnet/Apache.Ignite.Core/Cache/ICacheAffinity.cs
----------------------------------------------------------------------
diff --git a/modules/platform/dotnet/Apache.Ignite.Core/Cache/ICacheAffinity.cs b/modules/platform/dotnet/Apache.Ignite.Core/Cache/ICacheAffinity.cs
new file mode 100644
index 0000000..64f34d7
--- /dev/null
+++ b/modules/platform/dotnet/Apache.Ignite.Core/Cache/ICacheAffinity.cs
@@ -0,0 +1,158 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.Ignite.Core.Cache
+{
+    using System.Collections.Generic;
+    using Apache.Ignite.Core.Cluster;
+
+    /// <summary>
+    /// Provides affinity information to detect which node is primary and which nodes are
+    /// backups for a partitioned cache. You can get an instance of this interface by calling
+    /// <see cref="IIgnite.GetAffinity"/> method.
+    /// <para />
+    /// Mapping of a key to a node is a three-step operation. First step will get an affinity key for 
+    /// given key using <c>CacheAffinityKeyMapper</c>. If mapper is not specified, the original key 
+    /// will be used. Second step will map affinity key to partition using 
+    /// <c>CacheAffinityFunction.partition(Object)</c> method. Third step will map obtained partition 
+    /// to nodes for current grid topology version.
+    /// <para />
+    /// Interface provides various <c>mapKeysToNodes(...)</c> methods which provide node affinity mapping 
+    /// for given keys. All <c>mapKeysToNodes(...)</c> methods are not transactional and will not enlist
+    /// keys into ongoing transaction.
+    /// <para/>
+    /// All members are thread-safe and may be used concurrently from multiple threads.
+    /// </summary>
+    public interface ICacheAffinity
+    {
+        /// <summary>
+        /// Gets number of partitions in cache according to configured affinity function.
+        /// </summary>
+        /// <returns>Number of cache partitions.</returns>
+        int Partitions { get; }
+
+        /// <summary>
+        /// Gets partition id for the given key.
+        /// </summary>
+        /// <param name="key">Key to get partition id for.</param>
+        /// <returns>Partition id.</returns>
+        int GetPartition<TK>(TK key);
+
+        /// <summary>
+        /// Returns 'true' if given node is the primary node for given key.
+        /// </summary>
+        /// <param name="n">Node.</param>
+        /// <param name="key">Key.</param>
+        /// <returns>'True' if given node is the primary node for given key.</returns>
+        bool IsPrimary<TK>(IClusterNode n, TK key);
+
+        /// <summary>
+        /// Returns 'true' if given node is the backup node for given key.
+        /// </summary>
+        /// <param name="n">Node.</param>
+        /// <param name="key">Key.</param>
+        /// <returns>'True' if given node is the backup node for given key.</returns>
+        bool IsBackup<TK>(IClusterNode n, TK key);
+
+        /// <summary>
+        /// Returns 'true' if given node is either primary or backup node for given key.
+        /// </summary>
+        /// <param name="n">Node.</param>
+        /// <param name="key">Key.</param>
+        /// <returns>'True' if given node is either primary or backup node for given key.</returns>
+        bool IsPrimaryOrBackup<TK>(IClusterNode n, TK key);
+
+        /// <summary>
+        /// Gets partition ids for which nodes of the given projection has primary
+        /// ownership.
+        /// </summary>
+        /// <param name="n">Node.</param>
+        /// <returns>Partition ids for which given projection has primary ownership.</returns>
+        int[] GetPrimaryPartitions(IClusterNode n);
+
+        /// <summary>
+        /// Gets partition ids for which nodes of the given projection has backup
+        /// ownership.
+        /// </summary>
+        /// <param name="n">Node.</param>
+        /// <returns>Partition ids for which given projection has backup ownership.</returns>
+        int[] GetBackupPartitions(IClusterNode n);
+
+        /// <summary>
+        /// Gets partition ids for which nodes of the given projection has ownership
+        /// (either primary or backup).
+        /// </summary>
+        /// <param name="n">Node.</param>
+        /// <returns>Partition ids for which given projection has ownership.</returns>
+        int[] GetAllPartitions(IClusterNode n);
+
+        /// <summary>
+        /// Maps passed in key to a key which will be used for node affinity.
+        /// </summary>
+        /// <param name="key">Key to map.</param>
+        /// <returns>Key to be used for node-to-affinity mapping (may be the same key as passed in).</returns>
+        TR GetAffinityKey<TK, TR>(TK key);
+
+        /// <summary>
+        /// This method provides ability to detect which keys are mapped to which nodes.
+        /// Use it to determine which nodes are storing which keys prior to sending
+        /// jobs that access these keys.
+        /// </summary>
+        /// <param name="keys">Keys to map to nodes.</param>
+        /// <returns>Map of nodes to keys or empty map if there are no alive nodes for this cache.</returns>
+        IDictionary<IClusterNode, IList<TK>> MapKeysToNodes<TK>(IList<TK> keys);
+
+        /// <summary>
+        /// This method provides ability to detect to which primary node the given key
+        /// is mapped. Use it to determine which nodes are storing which keys prior to sending
+        /// jobs that access these keys.
+        /// </summary>
+        /// <param name="key">Keys to map to a node.</param>
+        /// <returns>Primary node for the key or null if there are no alive nodes for this cache.</returns>
+        IClusterNode MapKeyToNode<TK>(TK key);
+
+        /// <summary>
+        /// Gets primary and backup nodes for the key. Note that primary node is always
+        /// first in the returned collection.
+        /// </summary>
+        /// <param name="key"></param>
+        /// <returns></returns>
+        IList<IClusterNode> MapKeyToPrimaryAndBackups<TK>(TK key);
+
+        /// <summary>
+        /// Gets primary node for the given partition.
+        /// </summary>
+        /// <param name="part">Partition id.</param>
+        /// <returns>Primary node for the given partition.</returns>
+        IClusterNode MapPartitionToNode(int part);
+
+        /// <summary>
+        /// Gets primary nodes for the given partitions.
+        /// </summary>
+        /// <param name="parts">Partition ids.</param>
+        /// <returns>Mapping of given partitions to their primary nodes.</returns>
+        IDictionary<int, IClusterNode> MapPartitionsToNodes(IList<int> parts);
+
+        /// <summary>
+        /// Gets primary and backup nodes for partition. Note that primary node is always
+        /// first in the returned collection.
+        /// </summary>
+        /// <param name="part">Partition to get affinity nodes for.</param>
+        /// <returns>Collection of primary and backup nodes for partition with primary node always first</returns>
+        IList<IClusterNode> MapPartitionToPrimaryAndBackups(int part);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/f2eb16cd/modules/platform/dotnet/Apache.Ignite.Core/Cache/ICacheEntry.cs
----------------------------------------------------------------------
diff --git a/modules/platform/dotnet/Apache.Ignite.Core/Cache/ICacheEntry.cs b/modules/platform/dotnet/Apache.Ignite.Core/Cache/ICacheEntry.cs
new file mode 100644
index 0000000..49ebfec
--- /dev/null
+++ b/modules/platform/dotnet/Apache.Ignite.Core/Cache/ICacheEntry.cs
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.Ignite.Core.Cache
+{
+    /// <summary>
+    /// Cache entry interface.
+    /// </summary>
+    /// <typeparam name="TK">Key type.</typeparam>
+    /// <typeparam name="TV">Value type.</typeparam>
+    public interface ICacheEntry<out TK, out TV>
+    {
+        /// <summary>
+        /// Gets the key.
+        /// </summary>
+        TK Key { get; }
+
+        /// <summary>
+        /// Gets the value.
+        /// </summary>
+        TV Value { get; }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/f2eb16cd/modules/platform/dotnet/Apache.Ignite.Core/Cache/ICacheEntryFilter.cs
----------------------------------------------------------------------
diff --git a/modules/platform/dotnet/Apache.Ignite.Core/Cache/ICacheEntryFilter.cs b/modules/platform/dotnet/Apache.Ignite.Core/Cache/ICacheEntryFilter.cs
new file mode 100644
index 0000000..9c7ee88
--- /dev/null
+++ b/modules/platform/dotnet/Apache.Ignite.Core/Cache/ICacheEntryFilter.cs
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.Ignite.Core.Cache
+{
+    /// <summary>
+    /// Cache entry predicate.
+    /// </summary>
+    /// <typeparam name="TK">Key type.</typeparam>
+    /// <typeparam name="TV">Value type.</typeparam>
+    public interface ICacheEntryFilter<in TK, in TV>
+    {
+        /// <summary>
+        /// Returns a value indicating whether provided cache entry satisfies this predicate.
+        /// </summary>
+        /// <param name="entry">Cache entry.</param>
+        /// <returns>Value indicating whether provided cache entry satisfies this predicate.</returns>
+        bool Invoke(ICacheEntry<TK, TV> entry);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/f2eb16cd/modules/platform/dotnet/Apache.Ignite.Core/Cache/ICacheEntryProcessor.cs
----------------------------------------------------------------------
diff --git a/modules/platform/dotnet/Apache.Ignite.Core/Cache/ICacheEntryProcessor.cs b/modules/platform/dotnet/Apache.Ignite.Core/Cache/ICacheEntryProcessor.cs
new file mode 100644
index 0000000..c8614c0
--- /dev/null
+++ b/modules/platform/dotnet/Apache.Ignite.Core/Cache/ICacheEntryProcessor.cs
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.Ignite.Core.Cache
+{
+    /// <summary>
+    /// An invocable function that allows applications to perform compound operations
+    /// on a cache entry atomically, according the defined consistency of a cache.
+    /// <para />
+    /// Any cache entry mutations will not take effect until after
+    /// the <see cref="Process" /> method has completedS execution.
+    /// <para />
+    /// If an exception is thrown by an entry processor, a Caching Implementation
+    /// must wrap any exception thrown wrapped in an <see cref="CacheEntryProcessorException" />
+    /// If this occurs no mutations will be made to the cache entry.
+    /// </summary>
+    /// <typeparam name="TK">Key type.</typeparam>
+    /// <typeparam name="TV">Value type.</typeparam>
+    /// <typeparam name="TA">The type of the processor argument.</typeparam>
+    /// <typeparam name="TR">The type of the processor result.</typeparam>
+    public interface ICacheEntryProcessor<in TK, TV, in TA, out TR>
+    {
+        /// <summary>
+        /// Process an entry.
+        /// </summary>
+        /// <param name="entry">The entry to process.</param>
+        /// <param name="arg">The argument.</param>
+        /// <returns>Processing result.</returns>
+        TR Process(IMutableCacheEntry<TK, TV> entry, TA arg);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/f2eb16cd/modules/platform/dotnet/Apache.Ignite.Core/Cache/ICacheEntryProcessorResult.cs
----------------------------------------------------------------------
diff --git a/modules/platform/dotnet/Apache.Ignite.Core/Cache/ICacheEntryProcessorResult.cs b/modules/platform/dotnet/Apache.Ignite.Core/Cache/ICacheEntryProcessorResult.cs
new file mode 100644
index 0000000..2d0f709
--- /dev/null
+++ b/modules/platform/dotnet/Apache.Ignite.Core/Cache/ICacheEntryProcessorResult.cs
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.Ignite.Core.Cache
+{
+    /// <summary>
+    /// Represents a result of processing <see cref="ICacheEntry{K, V}"/> 
+    /// by <see cref="ICacheEntryProcessor{K, V, A, R}"/>.
+    /// </summary>
+    /// <typeparam name="T">Processor result type.</typeparam>
+    public interface ICacheEntryProcessorResult<out T>
+    {
+        /// <summary>
+        /// Gets the result of processing an entry.
+        /// <para />
+        /// If an exception was thrown during the processing of an entry, 
+        /// either by the <see cref="ICacheEntryProcessor{K, V, A, R}"/> itself 
+        /// or by the Caching implementation, the exceptions will be wrapped and re-thrown as a 
+        /// <see cref="CacheEntryProcessorException"/> when calling this property.
+        /// </summary>
+        /// <value>
+        /// The result.
+        /// </value>
+        T Result { get; }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/f2eb16cd/modules/platform/dotnet/Apache.Ignite.Core/Cache/ICacheLock.cs
----------------------------------------------------------------------
diff --git a/modules/platform/dotnet/Apache.Ignite.Core/Cache/ICacheLock.cs b/modules/platform/dotnet/Apache.Ignite.Core/Cache/ICacheLock.cs
new file mode 100644
index 0000000..a930961
--- /dev/null
+++ b/modules/platform/dotnet/Apache.Ignite.Core/Cache/ICacheLock.cs
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.Ignite.Core.Cache
+{
+    using System;
+    using System.Threading;
+
+    /// <summary>
+    /// Cache locking interface.
+    /// <para/>
+    /// All members are thread-safe and may be used concurrently from multiple threads.
+    /// </summary>
+    public interface ICacheLock : IDisposable
+    {
+        /// <summary>
+        /// Acquires an exclusive lock.
+        /// </summary>
+        void Enter();
+
+        /// <summary>
+        /// Acquires an exclusive lock only if it is free at the time of invocation.
+        /// </summary>
+        /// <returns>True if the current thread acquires the lock; otherwise, false.</returns>
+        bool TryEnter();
+
+        /// <summary>
+        /// Attempts, for the specified amount of time, to acquire an exclusive lock.
+        /// </summary>
+        /// <param name="timeout">
+        /// A <see cref="TimeSpan" /> representing the amount of time to wait for the lock. 
+        /// A value of –1 millisecond specifies an infinite wait.
+        /// </param>
+        /// <returns>True if the current thread acquires the lock; otherwise, false.</returns>
+        bool TryEnter(TimeSpan timeout);
+
+        /// <summary>
+        /// Releases an exclusive lock on the specified object.
+        /// <see cref="IDisposable.Dispose"/> does not call this method and will throw 
+        /// <see cref="SynchronizationLockException"/> if this lock is acquired.
+        /// </summary>
+        void Exit();
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/f2eb16cd/modules/platform/dotnet/Apache.Ignite.Core/Cache/ICacheMetrics.cs
----------------------------------------------------------------------
diff --git a/modules/platform/dotnet/Apache.Ignite.Core/Cache/ICacheMetrics.cs b/modules/platform/dotnet/Apache.Ignite.Core/Cache/ICacheMetrics.cs
new file mode 100644
index 0000000..3405625
--- /dev/null
+++ b/modules/platform/dotnet/Apache.Ignite.Core/Cache/ICacheMetrics.cs
@@ -0,0 +1,486 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.Ignite.Core.Cache
+{
+    /// <summary>
+    /// Cache metrics used to obtain statistics on cache itself.
+    /// </summary>
+    public interface ICacheMetrics
+    {
+        /// <summary>
+        /// The number of get requests that were satisfied by the cache.
+        /// </summary>
+        /// <returns>
+        /// The number of hits
+        /// </returns>
+        long CacheHits { get; }
+
+        /// <summary>
+        /// This is a measure of cache efficiency.
+        /// </summary>
+        /// <returns>
+        /// The percentage of successful hits, as a decimal e.g 75.
+        /// </returns>
+        float CacheHitPercentage { get; }
+
+        /// <summary>
+        /// A miss is a get request that is not satisfied.
+        /// </summary>
+        /// <returns>
+        /// The number of misses
+        /// </returns>
+        long CacheMisses { get; }
+
+        /// <summary>
+        /// Returns the percentage of cache accesses that did not find a requested entry in the cache.
+        /// </summary>
+        /// <returns>
+        /// The percentage of accesses that failed to find anything.
+        /// </returns>
+        float CacheMissPercentage { get; }
+
+        /// <summary>
+        /// The total number of requests to the cache. This will be equal to the sum of the hits and misses.
+        /// </summary>
+        /// <returns>
+        /// The number of gets.
+        /// </returns>
+        long CacheGets { get; }
+
+        /// <summary>
+        /// The total number of puts to the cache.
+        /// </summary>
+        /// <returns>
+        /// The number of puts.
+        /// </returns>
+        long CachePuts { get; }
+
+        /// <summary>
+        /// The total number of removals from the cache. This does not include evictions, where the cache itself
+        /// initiates the removal to make space.
+        /// </summary>
+        /// <returns>
+        /// The number of removals.
+        /// </returns>
+        long CacheRemovals { get; }
+
+        /// <summary>
+        /// The total number of evictions from the cache. An eviction is a removal initiated by the cache itself 
+        /// to free up space. An eviction is not treated as a removal and does not appear in the removal counts.
+        /// </summary>
+        /// <returns>
+        /// The number of evictions.
+        /// </returns>
+        long CacheEvictions { get; }
+
+        /// <summary>
+        /// The mean time to execute gets.
+        /// </summary>
+        /// <returns>
+        /// The time in �s.
+        /// </returns>
+        float AverageGetTime { get; }
+
+        /// <summary>
+        /// The mean time to execute puts.
+        /// </summary>
+        /// <returns>
+        /// The time in �s.
+        /// </returns>
+        float AveragePutTime { get; }
+
+        /// <summary>
+        /// The mean time to execute removes.
+        /// </summary>
+        /// <returns>
+        /// The time in �s.
+        /// </returns>
+        float AverageRemoveTime { get; }
+
+        /// <summary>
+        /// The mean time to execute tx commit.
+        /// </summary>
+        /// <returns>
+        /// The time in �s.
+        /// </returns>
+        float AverageTxCommitTime { get; }
+
+        /// <summary>
+        /// The mean time to execute tx rollbacks.
+        /// </summary>
+        /// <returns>
+        /// Number of transaction rollbacks.
+        /// </returns>
+        float AverageTxRollbackTime { get; }
+
+        /// <summary>
+        /// Gets total number of transaction commits.
+        /// </summary>
+        /// <returns>
+        /// Number of transaction commits.
+        /// </returns>
+        long CacheTxCommits { get; }
+
+        /// <summary>
+        /// Gets total number of transaction rollbacks.
+        /// </summary>
+        /// <returns>
+        /// Number of transaction rollbacks.
+        /// </returns>
+        long CacheTxRollbacks { get; }
+
+        /// <summary>
+        /// Gets cache name.
+        /// </summary>
+        /// <returns>
+        /// Cache name.
+        /// </returns>
+        string CacheName { get; }
+
+        /// <summary>
+        /// Gets number of entries that was swapped to disk.
+        /// </summary>
+        /// <returns>
+        /// Number of entries that was swapped to disk.
+        /// </returns>
+        long OverflowSize { get; }
+
+        /// <summary>
+        /// Gets number of entries stored in off-heap memory.
+        /// </summary>
+        /// <returns>
+        /// Number of entries stored in off-heap memory.
+        /// </returns>
+        long OffHeapEntriesCount { get; }
+
+        /// <summary>
+        /// Gets memory size allocated in off-heap.
+        /// </summary>
+        /// <returns>
+        /// Memory size allocated in off-heap.
+        /// </returns>
+        long OffHeapAllocatedSize { get; }
+
+        /// <summary>
+        /// Gets number of non-null values in the cache.
+        /// </summary>
+        /// <returns>
+        /// Number of non-null values in the cache.
+        /// </returns>
+        int Size { get; }
+
+        /// <summary>
+        /// Gets number of keys in the cache, possibly with null values.
+        /// </summary>
+        /// <returns>
+        /// Number of keys in the cache.
+        /// </returns>
+        int KeySize { get; }
+
+        /// <summary>
+        /// Returns true if this cache is empty.
+        /// </summary>
+        /// <returns>
+        /// True if this cache is empty.
+        /// </returns>
+        bool IsEmpty { get; }
+
+        /// <summary>
+        /// Gets current size of evict queue used to batch up evictions.
+        /// </summary>
+        /// <returns>
+        /// Current size of evict queue.
+        /// </returns>
+        int DhtEvictQueueCurrentSize { get; }
+
+        /// <summary>
+        /// Gets transaction per-thread map size.
+        /// </summary>
+        /// <returns>
+        /// Thread map size.
+        /// </returns>
+        int TxThreadMapSize { get; }
+
+        /// <summary>
+        /// Gets transaction per-Xid map size.
+        /// </summary>
+        /// <returns>
+        /// Transaction per-Xid map size.
+        /// </returns>
+        int TxXidMapSize { get; }
+
+        /// <summary>
+        /// Gets committed transaction queue size.
+        /// </summary>
+        /// <returns>
+        /// Committed transaction queue size.
+        /// </returns>
+        int TxCommitQueueSize { get; }
+
+        /// <summary>
+        /// Gets prepared transaction queue size.
+        /// </summary>
+        /// <returns>
+        /// Prepared transaction queue size.
+        /// </returns>
+        int TxPrepareQueueSize { get; }
+
+        /// <summary>
+        /// Gets start version counts map size.
+        /// </summary>
+        /// <returns>
+        /// Start version counts map size.
+        /// </returns>
+        int TxStartVersionCountsSize { get; }
+
+        /// <summary>
+        /// Gets number of cached committed transaction IDs.
+        /// </summary>
+        /// <returns>
+        /// Number of cached committed transaction IDs.
+        /// </returns>
+        int TxCommittedVersionsSize { get; }
+
+        /// <summary>
+        /// Gets number of cached rolled back transaction IDs.
+        /// </summary>
+        /// <returns>
+        /// Number of cached rolled back transaction IDs.
+        /// </returns>
+        int TxRolledbackVersionsSize { get; }
+
+        /// <summary>
+        /// Gets transaction DHT per-thread map size.
+        /// </summary>
+        /// <returns>
+        /// DHT thread map size.
+        /// </returns>
+        int TxDhtThreadMapSize { get; }
+
+        /// <summary>
+        /// Gets transaction DHT per-Xid map size.
+        /// </summary>
+        /// <returns>
+        /// Transaction DHT per-Xid map size.
+        /// </returns>
+        int TxDhtXidMapSize { get; }
+
+        /// <summary>
+        /// Gets committed DHT transaction queue size.
+        /// </summary>
+        /// <returns>
+        /// Committed DHT transaction queue size.
+        /// </returns>
+        int TxDhtCommitQueueSize { get; }
+
+        /// <summary>
+        /// Gets prepared DHT transaction queue size.
+        /// </summary>
+        /// <returns>
+        /// Prepared DHT transaction queue size.
+        /// </returns>
+        int TxDhtPrepareQueueSize { get; }
+
+        /// <summary>
+        /// Gets DHT start version counts map size.
+        /// </summary>
+        /// <returns>
+        /// DHT start version counts map size.
+        /// </returns>
+        int TxDhtStartVersionCountsSize { get; }
+
+        /// <summary>
+        /// Gets number of cached committed DHT transaction IDs.
+        /// </summary>
+        /// <returns>
+        /// Number of cached committed DHT transaction IDs.
+        /// </returns>
+        int TxDhtCommittedVersionsSize { get; }
+
+        /// <summary>
+        /// Gets number of cached rolled back DHT transaction IDs.
+        /// </summary>
+        /// <returns>
+        /// Number of cached rolled back DHT transaction IDs.
+        /// </returns>
+        int TxDhtRolledbackVersionsSize { get; }
+
+        /// <summary>
+        /// Returns true if write-behind is enabled.
+        /// </summary>
+        /// <returns>
+        /// True if write-behind is enabled.
+        /// </returns>
+        bool IsWriteBehindEnabled { get; }
+
+        /// <summary>
+        /// Gets the maximum size of the write-behind buffer. When the count of unique keys in write buffer exceeds 
+        /// this value, the buffer is scheduled for write to the underlying store. 
+        /// <para /> 
+        /// If this value is 0, then flush is performed only on time-elapsing basis. 
+        /// </summary>
+        /// <returns>
+        /// Buffer size that triggers flush procedure.
+        /// </returns>
+        int WriteBehindFlushSize { get; }
+
+        /// <summary>
+        /// Gets the number of flush threads that will perform store update operations.
+        /// </summary>
+        /// <returns>
+        /// Count of worker threads.
+        /// </returns>
+        int WriteBehindFlushThreadCount { get; }
+
+        /// <summary>
+        /// Gets the cache flush frequency. All pending operations on the underlying store will be performed 
+        /// within time interval not less then this value. 
+        /// <para /> If this value is 0, then flush is performed only when buffer size exceeds flush size.
+        /// </summary>
+        /// <returns>
+        /// Flush frequency in milliseconds.
+        /// </returns>
+        long WriteBehindFlushFrequency { get; }
+
+        /// <summary>
+        /// Gets the maximum count of similar (put or remove) operations that can be grouped to a single batch.
+        /// </summary>
+        /// <returns>
+        /// Maximum size of batch.
+        /// </returns>
+        int WriteBehindStoreBatchSize { get; }
+
+        /// <summary>
+        /// Gets count of write buffer overflow events since initialization. 
+        /// Each overflow event causes the ongoing flush operation to be performed synchronously.
+        /// </summary>
+        /// <returns>
+        /// Count of cache overflow events since start.
+        /// </returns>
+        int WriteBehindTotalCriticalOverflowCount { get; }
+
+        /// <summary>
+        /// Gets count of write buffer overflow events in progress at the moment. 
+        /// Each overflow event causes the ongoing flush operation to be performed synchronously.
+        /// </summary>
+        /// <returns>
+        /// Count of cache overflow events since start.
+        /// </returns>
+        int WriteBehindCriticalOverflowCount { get; }
+
+        /// <summary>
+        /// Gets count of cache entries that are in a store-retry state. 
+        /// An entry is assigned a store-retry state when underlying store failed due some reason 
+        /// and cache has enough space to retain this entry till the next try.
+        /// </summary>
+        /// <returns>
+        /// Count of entries in store-retry state.
+        /// </returns>
+        int WriteBehindErrorRetryCount { get; }
+
+        /// <summary>
+        /// Gets count of entries that were processed by the write-behind store 
+        /// and have not been flushed to the underlying store yet.
+        /// </summary>
+        /// <returns>
+        /// Total count of entries in cache store internal buffer.
+        /// </returns>
+        int WriteBehindBufferSize { get; }
+
+        /// <summary>
+        /// Determines the required type of keys for this cache, if any.
+        /// </summary>
+        /// <returns>
+        /// The fully qualified class name of the key type, or "java.lang.Object" if the type is undefined.
+        /// </returns>
+        string KeyType { get; }
+
+        /// <summary>
+        /// Determines the required type of values for this cache, if any.
+        /// </summary>
+        /// <returns>
+        /// The fully qualified class name of the value type, or "java.lang.Object" if the type is undefined.
+        /// </returns>
+        string ValueType { get; }
+
+        /// <summary>
+        /// Whether storeByValue true or storeByReference false. When true, both keys and values are stored by value. 
+        /// <para /> 
+        /// When false, both keys and values are stored by reference. Caches stored by reference are capable of 
+        /// mutation by any threads holding the reference. 
+        /// The effects are: 
+        /// - if the key is mutated, then the key may not be retrievable or removable
+        /// - if the value is mutated, then all threads in the JVM can potentially observe those mutations, subject
+        /// to the normal Java Memory Model rules.
+        /// Storage by reference only applies to the local heap. 
+        /// If an entry is moved off heap it will need to be transformed into a representation. 
+        /// Any mutations that occur after transformation may not be reflected in the cache. 
+        /// <para /> 
+        /// When a cache is storeByValue, any mutation to the key or value does not affect the key of value 
+        /// stored in the cache. 
+        /// <para /> 
+        /// The default value is true.
+        /// </summary>
+        /// <returns>
+        /// True if the cache is store by value
+        /// </returns>
+        bool IsStoreByValue { get; }
+
+        /// <summary>
+        /// Checks whether statistics collection is enabled in this cache. 
+        /// <para /> 
+        /// The default value is false.
+        /// </summary>
+        /// <returns>
+        /// True if statistics collection is enabled
+        /// </returns>
+        bool IsStatisticsEnabled { get; }
+
+        /// <summary>
+        /// Checks whether management is enabled on this cache. 
+        /// <para /> 
+        /// The default value is false.
+        /// </summary>
+        /// <returns>
+        /// True if management is enabled
+        /// </returns>
+        bool IsManagementEnabled { get; }
+
+        /// <summary>
+        /// Determines if a cache should operate in read-through mode. 
+        /// <para /> 
+        /// The default value is false
+        /// </summary>
+        /// <returns>
+        /// True when a cache is in "read-through" mode.
+        /// </returns>
+        bool IsReadThrough { get; }
+
+        /// <summary>
+        /// Determines if a cache should operate in "write-through" mode. 
+        /// <para /> 
+        /// Will appropriately cause the configured CacheWriter to be invoked. 
+        /// <para /> 
+        /// The default value is false
+        /// </summary>
+        /// <returns>
+        /// True when a cache is in "write-through" mode.
+        /// </returns>
+        bool IsWriteThrough { get; }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/f2eb16cd/modules/platform/dotnet/Apache.Ignite.Core/Cache/IMutableCacheEntry.cs
----------------------------------------------------------------------
diff --git a/modules/platform/dotnet/Apache.Ignite.Core/Cache/IMutableCacheEntry.cs b/modules/platform/dotnet/Apache.Ignite.Core/Cache/IMutableCacheEntry.cs
new file mode 100644
index 0000000..ae71be6
--- /dev/null
+++ b/modules/platform/dotnet/Apache.Ignite.Core/Cache/IMutableCacheEntry.cs
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.Ignite.Core.Cache
+{
+    /// <summary>
+    /// Mutable representation of <see cref="ICacheEntry{K, V}"/>
+    /// </summary>
+    /// <typeparam name="TK">Key type.</typeparam>
+    /// <typeparam name="TV">Value type.</typeparam>
+    public interface IMutableCacheEntry<out TK, TV> : ICacheEntry<TK, TV>
+    {
+        /// <summary>
+        /// Gets a value indicating whether cache entry exists in cache.
+        /// </summary>
+        bool Exists { get; }
+
+        /// <summary>
+        /// Removes the entry from the Cache.
+        /// </summary>
+        void Remove();
+
+        /// <summary>
+        /// Gets, sets or replaces the value associated with the key.
+        /// <para />
+        /// If <see cref="Exists"/> is false and setter is called then a mapping is added to the cache 
+        /// visible once the EntryProcessor completes.
+        /// <para />
+        /// After setter invocation <see cref="Exists"/> will return true.
+        /// </summary>
+        new TV Value { get; set; }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ignite/blob/f2eb16cd/modules/platform/dotnet/Apache.Ignite.Core/Cache/Query/Continuous/ContinuousQuery.cs
----------------------------------------------------------------------
diff --git a/modules/platform/dotnet/Apache.Ignite.Core/Cache/Query/Continuous/ContinuousQuery.cs b/modules/platform/dotnet/Apache.Ignite.Core/Cache/Query/Continuous/ContinuousQuery.cs
new file mode 100644
index 0000000..8f297a2
--- /dev/null
+++ b/modules/platform/dotnet/Apache.Ignite.Core/Cache/Query/Continuous/ContinuousQuery.cs
@@ -0,0 +1,170 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.Ignite.Core.Cache.Query.Continuous
+{
+    using System;
+    using System.Diagnostics.CodeAnalysis;
+    using Apache.Ignite.Core.Cache.Event;
+
+    /// <summary>
+    /// API for configuring continuous cache queries.
+    /// <para />
+    /// Continuous queries allow to register a remote and a listener for cache update events. 
+    /// If an update event passes the filter, it will be sent to the node that executed the 
+    /// query and listener will be notified on that node.
+    /// <para />
+    /// Continuous query can either be executed on the whole topology or only on local node.
+    /// <para />
+    /// In case query is distributed and a new node joins, it will get the filter for the query 
+    /// during discovery process before it actually joins topology, so no updates will be missed.
+    /// <para />
+    /// To execute the query use method 
+    /// <see cref="ICache{K,V}.QueryContinuous(ContinuousQuery{K,V})"/>.
+    /// </summary>
+    public class ContinuousQuery<TK, TV>
+    {
+        /// <summary>
+        /// Default buffer size.
+        /// </summary>
+        [SuppressMessage("Microsoft.Design", "CA1000:DoNotDeclareStaticMembersOnGenericTypes")]
+        public const int DfltBufSize = 1;
+
+        /// <summary>
+        /// Default time interval.
+        /// </summary>
+        [SuppressMessage("ReSharper", "StaticMemberInGenericType")]
+        [SuppressMessage("Microsoft.Design", "CA1000:DoNotDeclareStaticMembersOnGenericTypes")]
+        public static readonly TimeSpan DfltTimeInterval = new TimeSpan(0);
+
+        /// <summary>
+        /// Default auto-unsubscribe flag value.
+        /// </summary>
+        [SuppressMessage("Microsoft.Design", "CA1000:DoNotDeclareStaticMembersOnGenericTypes")]
+        public const bool DfltAutoUnsubscribe = true;
+
+        /// <summary>
+        /// Constructor.
+        /// </summary>
+        /// <param name="lsnr">Listener.</param>
+        public ContinuousQuery(ICacheEntryEventListener<TK, TV> lsnr) : this(lsnr, false)
+        {
+            // No-op.
+        }
+
+        /// <summary>
+        /// Constructor.
+        /// </summary>
+        /// <param name="lsnr">Listener.</param>
+        /// <param name="loc">Whether query should be executed locally.</param>
+        public ContinuousQuery(ICacheEntryEventListener<TK, TV> lsnr, bool loc) : this(lsnr, null, loc)
+        {
+            // No-op.
+        }
+
+        /// <summary>
+        /// Constructor.
+        /// </summary>
+        /// <param name="lsnr">Listener.</param>
+        /// <param name="filter">Filter.</param>
+        public ContinuousQuery(ICacheEntryEventListener<TK, TV> lsnr, ICacheEntryEventFilter<TK, TV> filter)
+            : this(lsnr, filter, false)
+        {
+            // No-op.
+        }
+
+        /// <summary>
+        /// Constructor.
+        /// </summary>
+        /// <param name="lsnr">Listener.</param>
+        /// <param name="filter">Filter.</param>
+        /// <param name="loc">Whether query should be executed locally.</param>
+        public ContinuousQuery(ICacheEntryEventListener<TK, TV> lsnr, ICacheEntryEventFilter<TK, TV> filter, bool loc)
+        {
+            Listener = lsnr;
+            Filter = filter;
+            Local = loc;
+
+            BufferSize = DfltBufSize;
+            TimeInterval = DfltTimeInterval;
+            AutoUnsubscribe = DfltAutoUnsubscribe;
+        }
+
+        /// <summary>
+        /// Cache entry event listener. Invoked on the node where continuous query execution 
+        /// has been started.
+        /// </summary>
+        public ICacheEntryEventListener<TK, TV> Listener { get; set; }
+
+        /// <summary>
+        /// Optional cache entry filter. Invoked on a node where cache event occurred. If filter
+        /// returns <c>false</c>, then cache entry event will not be sent to a node where
+        /// continuous query has been started.
+        /// <para />
+        /// Must be either portable or serializable in case query is not local.
+        /// </summary>
+        public ICacheEntryEventFilter<TK, TV> Filter { get; set; }
+
+        /// <summary>
+        /// Buffer size. When a cache update happens, entry is first put into a buffer. 
+        /// Entries from buffer will be sent to the master node only if the buffer is 
+        /// full or time provided via <see cref="TimeInterval"/> is exceeded.
+        /// <para />
+        /// Defaults to <see cref="DfltBufSize"/>
+        /// </summary>
+        public int BufferSize { get; set; }
+
+        /// <summary>
+        /// Time interval. When a cache update happens, entry is first put into a buffer. 
+        /// Entries from buffer will be sent to the master node only if the buffer is full 
+        /// (its size can be provided via <see cref="BufferSize"/> property) or time provided 
+        /// via this method is exceeded.
+        /// <para />
+        /// Defaults to <c>0</c> which means that time check is disabled and entries will be 
+        /// sent only when buffer is full.
+        /// </summary>
+        public TimeSpan TimeInterval { get; set; }
+
+        /// <summary>
+        /// Automatic unsubscribe flag. This flag indicates that query filters on remote nodes 
+        /// should be automatically unregistered if master node (node that initiated the query) 
+        /// leaves topology. If this flag is <c>false</c>, filters will be unregistered only 
+        /// when the query is cancelled from master node, and won't ever be unregistered if 
+        /// master node leaves grid.
+        /// <para />
+        /// Defaults to <c>true</c>.
+        /// </summary>
+        public bool AutoUnsubscribe { get; set; }
+
+        /// <summary>
+        /// Local flag. When set query will be executed only on local node, so only local 
+        /// entries will be returned as query result.
+        /// <para />
+        /// Defaults to <c>false</c>.
+        /// </summary>
+        public bool Local { get; set; }
+
+        /// <summary>
+        /// Validate continuous query state.
+        /// </summary>
+        internal void Validate()
+        {
+            if (Listener == null)
+                throw new ArgumentException("Listener cannot be null.");
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ignite/blob/f2eb16cd/modules/platform/dotnet/Apache.Ignite.Core/Cache/Query/Continuous/IContinuousQueryHandle.cs
----------------------------------------------------------------------
diff --git a/modules/platform/dotnet/Apache.Ignite.Core/Cache/Query/Continuous/IContinuousQueryHandle.cs b/modules/platform/dotnet/Apache.Ignite.Core/Cache/Query/Continuous/IContinuousQueryHandle.cs
new file mode 100644
index 0000000..03f8e05
--- /dev/null
+++ b/modules/platform/dotnet/Apache.Ignite.Core/Cache/Query/Continuous/IContinuousQueryHandle.cs
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Apache.Ignite.Core.Cache.Query.Continuous
+{
+    using System;
+    using System.Diagnostics.CodeAnalysis;
+
+    /// <summary>
+    /// Represents a continuous query handle.
+    /// </summary>
+    [SuppressMessage("Microsoft.Design", "CA1040:AvoidEmptyInterfaces")]
+    public interface IContinuousQueryHandle : IDisposable
+    {
+        // No-op.
+    }
+
+    /// <summary>
+    /// Represents a continuous query handle.
+    /// </summary>
+    /// <typeparam name="T">Type of the initial query cursor.</typeparam>
+    public interface IContinuousQueryHandle<T> : IContinuousQueryHandle
+    {
+        /// <summary>
+        /// Gets the cursor for initial query.
+        /// Can be called only once, throws exception on consequent calls.
+        /// </summary>
+        /// <returns>Initial query cursor.</returns>
+        IQueryCursor<T> GetInitialQueryCursor();
+    }
+}
\ No newline at end of file