http://git-wip-us.apache.org/repos/asf/geode-native/blob/6cbd424f/clicache/src/impl/ManagedCacheLoader.hpp
----------------------------------------------------------------------
diff --git a/clicache/src/impl/ManagedCacheLoader.hpp 
b/clicache/src/impl/ManagedCacheLoader.hpp
new file mode 100644
index 0000000..4d09d49
--- /dev/null
+++ b/clicache/src/impl/ManagedCacheLoader.hpp
@@ -0,0 +1,160 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "../geode_defs.hpp"
+#include <vcclr.h>
+#include "begin_native.hpp"
+#include <geode/CacheLoader.hpp>
+#include "end_native.hpp"
+
+
+#include "../ICacheLoader.hpp"
+#include "CacheLoader.hpp"
+
+namespace apache
+{
+  namespace geode
+  {
+    namespace client
+    {
+
+      /// <summary>
+      /// Wraps the managed <see cref="Apache.Geode.Client.ICacheLoader" />
+      /// object and implements the native 
<c>apache::geode::client::CacheLoader</c> interface.
+      /// </summary>
+      class ManagedCacheLoaderGeneric
+        : public apache::geode::client::CacheLoader
+      {
+      public:
+
+        /// <summary>
+        /// Constructor to initialize with the provided managed object.
+        /// </summary>
+        /// <param name="userptr">
+        /// The managed object.
+        /// </param>
+        inline ManagedCacheLoaderGeneric(
+          /*Generic::ICacheLoader<Object^, Object^>^ managedptr,*/ Object^ 
userptr)
+          : /*m_managedptr( managedptr ),*/ m_userptr(userptr) { }
+
+        /// <summary>
+        /// Static function to create a <c>ManagedCacheLoader</c> using given
+        /// managed assembly path and given factory function.
+        /// </summary>
+        /// <param name="assemblyPath">
+        /// The path of the managed assembly that contains the 
<c>ICacheLoader</c>
+        /// factory function.
+        /// </param>
+        /// <param name="factoryFunctionName">
+        /// The name of the factory function of the managed class for creating
+        /// an object that implements <c>ICacheLoader</c>.
+        /// This should be a static function of the format
+        /// {Namespace}.{Class Name}.{Method Name}.
+        /// </param>
+        /// <exception cref="IllegalArgumentException">
+        /// If the managed library cannot be loaded or the factory function 
fails.
+        /// </exception>
+        static apache::geode::client::CacheLoader* create(const char* 
assemblyPath,
+          const char* factoryFunctionName);
+
+        virtual ~ManagedCacheLoaderGeneric() { }
+
+        /// <summary>
+        /// Loads a value. Application writers should implement this
+        /// method to customize the loading of a value.
+        /// </summary>
+        /// <remarks>
+        /// This method is called by the caching service when the requested
+        /// value is not in the cache. Any exception thrown by this method
+        /// is propagated back to and thrown by the invocation of
+        /// <see cref="Apache.Geode.Client.Region.Get" /> that triggered this 
load.
+        /// </remarks>
+        /// <param name="region">a Region Pointer for which this is 
called.</param>
+        /// <param name="key">the key for the cacheable</param>
+        /// <param name="aCallbackArgument">any related user data, or 
null</param>
+        /// <returns>
+        /// the value supplied for this key, or null if no value can be
+        /// supplied. 
+        /// If every available loader returns
+        /// a null value, <see cref="Apache.Geode.Client.Region.Get" />
+        /// will return null.
+        /// </returns>
+        /// <seealso cref="Apache.Geode.Client.Region.Get" />
+        virtual CacheablePtr load(const RegionPtr& region,
+          const CacheableKeyPtr& key, const UserDataPtr& aCallbackArgument);
+
+        /// <summary>
+        /// Called when the region containing this callback is destroyed, when
+        /// the cache is closed.
+        /// </summary>
+        /// <remarks>
+        /// Implementations should clean up any external
+        /// resources, such as database connections. Any runtime exceptions 
this method
+        /// throws will be logged.
+        /// <para>
+        /// It is possible for this method to be called multiple times on a 
single
+        /// callback instance, so implementations must be tolerant of this.
+        /// </para>
+        /// </remarks>
+        /// <param name="region">the region pointer</param>
+        /// <seealso cref="Apache.Geode.Client.Cache.Close" />
+        /// <seealso cref="Apache.Geode.Client.Region.DestroyRegion" />
+        virtual void close(const RegionPtr& region);
+
+        /*
+        /// <summary>
+        /// Returns the wrapped managed object reference.
+        /// </summary>
+        inline Apache::Geode::Client::ICacheLoader^ ptr( ) const
+        {
+        return m_managedptr;
+        }
+        */
+
+        inline void setptr(Apache::Geode::Client::ICacheLoaderProxy^ 
managedptr)
+        {
+          m_managedptr = managedptr;
+        }
+
+        inline Object^ userptr() const
+        {
+          return m_userptr;
+        }
+
+
+      private:
+
+        /// <summary>
+        /// Using gcroot to hold the managed delegate pointer (since it cannot 
be stored directly).
+        /// Note: not using auto_gcroot since it will result in 'Dispose' of 
the ICacheLoader
+        /// to be called which is not what is desired when this object is 
destroyed. Normally this
+        /// managed object may be created by the user and will be handled 
automatically by the GC.
+        /// </summary>
+        gcroot<Apache::Geode::Client::ICacheLoaderProxy^> m_managedptr;
+
+        gcroot<Object^> m_userptr;
+
+        // Disable the copy and assignment constructors
+        ManagedCacheLoaderGeneric(const ManagedCacheLoaderGeneric&);
+        ManagedCacheLoaderGeneric& operator = (const 
ManagedCacheLoaderGeneric&);
+      };
+
+    }  // namespace client
+  }  // namespace geode
+}  // namespace apache

http://git-wip-us.apache.org/repos/asf/geode-native/blob/6cbd424f/clicache/src/impl/ManagedCacheWriter.cpp
----------------------------------------------------------------------
diff --git a/clicache/src/impl/ManagedCacheWriter.cpp 
b/clicache/src/impl/ManagedCacheWriter.cpp
new file mode 100644
index 0000000..646cf7e
--- /dev/null
+++ b/clicache/src/impl/ManagedCacheWriter.cpp
@@ -0,0 +1,316 @@
+/*
+ * 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.
+ */
+
+//#include "../geode_includes.hpp"
+#include "ManagedCacheWriter.hpp"
+#include "../ICacheWriter.hpp"
+#include "../Region.hpp"
+#include "../RegionEvent.hpp"
+#include "../EntryEvent.hpp"
+#include "../Log.hpp"
+#include "ManagedString.hpp"
+#include "../ExceptionTypes.hpp"
+#include "SafeConvert.hpp"
+#include "CacheWriter.hpp"
+
+using namespace System;
+using namespace System::Text;
+using namespace System::Reflection;
+
+namespace apache
+{
+  namespace geode
+  {
+    namespace client
+    {
+
+      CacheWriter* ManagedCacheWriterGeneric::create(const char* assemblyPath,
+                                                     const char* 
factoryFunctionName)
+      {
+        try
+        {
+          String^ mg_assemblyPath =
+            Apache::Geode::Client::ManagedString::Get(assemblyPath);
+          String^ mg_factoryFunctionName =
+            Apache::Geode::Client::ManagedString::Get(factoryFunctionName);
+          String^ mg_typeName = nullptr;
+
+          String^ mg_genericKey = nullptr;
+          String^ mg_genericVal = nullptr;
+
+          System::Int32 dotIndx = -1;
+          System::Int32 genericsOpenIndx = -1;
+          System::Int32 genericsCloseIndx = -1;
+          System::Int32 commaIndx = -1;
+
+          if (mg_factoryFunctionName == nullptr ||
+              (dotIndx = mg_factoryFunctionName->LastIndexOf('.')) < 0)
+          {
+            std::string ex_str = "ManagedCacheWriterGeneric: Factory function 
name '";
+            ex_str += factoryFunctionName;
+            ex_str += "' does not contain type name";
+            throw IllegalArgumentException(ex_str.c_str());
+          }
+
+          if ((genericsCloseIndx = mg_factoryFunctionName->LastIndexOf('>')) < 
0)
+          {
+            std::string ex_str = "ManagedCacheWriterGeneric: Factory function 
name '";
+            ex_str += factoryFunctionName;
+            ex_str += "' does not contain any generic type parameters";
+            throw 
apache::geode::client::IllegalArgumentException(ex_str.c_str());
+          }
+
+          if ((genericsOpenIndx = mg_factoryFunctionName->LastIndexOf('<')) < 
0 ||
+              genericsOpenIndx > genericsCloseIndx)
+          {
+            std::string ex_str = "ManagedCacheWriterGeneric: Factory function 
name '";
+            ex_str += factoryFunctionName;
+            ex_str += "' does not contain expected generic type parameters";
+            throw 
apache::geode::client::IllegalArgumentException(ex_str.c_str());
+          }
+
+          if ((commaIndx = mg_factoryFunctionName->LastIndexOf(',')) < 0 ||
+              (commaIndx < genericsOpenIndx || commaIndx > genericsCloseIndx))
+          {
+            std::string ex_str = "ManagedCacheWriterGeneric: Factory function 
name '";
+            ex_str += factoryFunctionName;
+            ex_str += "' does not contain expected generic type parameter 
comma separator";
+            throw 
apache::geode::client::IllegalArgumentException(ex_str.c_str());
+          }
+
+          StringBuilder^ typeBuilder = gcnew 
StringBuilder(mg_factoryFunctionName->Substring(0, genericsOpenIndx));
+          mg_typeName = typeBuilder->ToString();
+          mg_genericKey = mg_factoryFunctionName->Substring(genericsOpenIndx + 
1, commaIndx - genericsOpenIndx - 1);
+          mg_genericKey = mg_genericKey->Trim();
+          mg_genericVal = mg_factoryFunctionName->Substring(commaIndx + 1, 
genericsCloseIndx - commaIndx - 1);
+          mg_genericVal = mg_genericVal->Trim();
+          mg_factoryFunctionName = mg_factoryFunctionName->Substring(dotIndx + 
1);
+
+          Apache::Geode::Client::Log::Fine(
+            "Attempting to instantiate a [{0}<{1}, {2}>] via the [{3}] factory 
method.",
+            mg_typeName, mg_genericKey, mg_genericVal, mg_factoryFunctionName);
+
+          typeBuilder->Append("`2");
+          mg_typeName = typeBuilder->ToString();
+
+          Assembly^ assmb = nullptr;
+          try
+          {
+            assmb = Assembly::Load(mg_assemblyPath);
+          }
+          catch (System::Exception^)
+          {
+            assmb = nullptr;
+          }
+          if (assmb == nullptr)
+          {
+            std::string ex_str = "ManagedCacheWriterGeneric: Could not load 
assembly: ";
+            ex_str += assemblyPath;
+            throw IllegalArgumentException(ex_str.c_str());
+          }
+
+          Apache::Geode::Client::Log::Debug("Loading type: [{0}]", 
mg_typeName);
+
+          Type^ typeInst = assmb->GetType(mg_typeName, false, true);
+
+          if (typeInst != nullptr)
+          {
+            array<Type^>^ types = gcnew array<Type^>(2);
+            types[0] = Type::GetType(mg_genericKey, false, true);
+            types[1] = Type::GetType(mg_genericVal, false, true);
+
+            if (types[0] == nullptr || types[1] == nullptr)
+            {
+              std::string ex_str = "ManagedCacheWriterGeneric: Could not get 
both generic type argument instances";
+              throw 
apache::geode::client::IllegalArgumentException(ex_str.c_str());
+            }
+
+            typeInst = typeInst->MakeGenericType(types);
+            Apache::Geode::Client::Log::Info("Loading function: [{0}]", 
mg_factoryFunctionName);
+
+            MethodInfo^ mInfo = typeInst->GetMethod(mg_factoryFunctionName,
+                                                    BindingFlags::Public | 
BindingFlags::Static | BindingFlags::IgnoreCase);
+            if (mInfo != nullptr)
+            {
+              Object^ managedptr = nullptr;
+              try
+              {
+                managedptr = mInfo->Invoke(typeInst, nullptr);
+              }
+              catch (System::Exception^ ex)
+              {
+                Apache::Geode::Client::Log::Debug("{0}: {1}", 
ex->GetType()->Name, ex->Message);
+                managedptr = nullptr;
+              }
+              if (managedptr == nullptr)
+              {
+                std::string ex_str = "ManagedCacheWriterGeneric: Could not 
create "
+                  "object on invoking factory function [";
+                ex_str += factoryFunctionName;
+                ex_str += "] in assembly: ";
+                ex_str += assemblyPath;
+                throw IllegalArgumentException(ex_str.c_str());
+              }
+              ManagedCacheWriterGeneric* mgcw = new 
ManagedCacheWriterGeneric(managedptr);
+
+              Type^ cwgType = 
Type::GetType("Apache.Geode.Client.CacheWriterGeneric`2");
+              cwgType = cwgType->MakeGenericType(types);
+              Object^ cwg = Activator::CreateInstance(cwgType);
+
+              mInfo = cwgType->GetMethod("SetCacheWriter");
+              array<Object^>^ params = gcnew array<Object^>(1);
+              params[0] = managedptr;
+              mInfo->Invoke(cwg, params);
+
+              mgcw->setptr((Apache::Geode::Client::ICacheWriter<Object^, 
Object^>^)cwg);
+
+              return mgcw;
+            }
+            else
+            {
+              std::string ex_str = "ManagedCacheWriterGeneric: Could not load "
+                "function with name [";
+              ex_str += factoryFunctionName;
+              ex_str += "] in assembly: ";
+              ex_str += assemblyPath;
+              throw IllegalArgumentException(ex_str.c_str());
+            }
+          }
+          else
+          {
+            Apache::Geode::Client::ManagedString typeName(mg_typeName);
+            std::string ex_str = "ManagedCacheWriterGeneric: Could not load 
type [";
+            ex_str += typeName.CharPtr;
+            ex_str += "] in assembly: ";
+            ex_str += assemblyPath;
+            throw IllegalArgumentException(ex_str.c_str());
+          }
+        }
+        catch (const apache::geode::client::Exception&)
+        {
+          throw;
+        }
+        catch (System::Exception^ ex)
+        {
+          Apache::Geode::Client::ManagedString mg_exStr(ex->ToString());
+          std::string ex_str = "ManagedCacheWriterGeneric: Got an exception 
while "
+            "loading managed library: ";
+          ex_str += mg_exStr.CharPtr;
+          throw IllegalArgumentException(ex_str.c_str());
+        }
+        return NULL;
+      }
+
+      bool ManagedCacheWriterGeneric::beforeUpdate(const EntryEvent& ev)
+      {
+        try {
+          Apache::Geode::Client::EntryEvent<Object^, Object^> mevent(&ev);
+
+          return m_managedptr->BeforeUpdate(%mevent);
+        }
+        catch (Apache::Geode::Client::GeodeException^ ex) {
+          ex->ThrowNative();
+        }
+        catch (System::Exception^ ex) {
+          Apache::Geode::Client::GeodeException::ThrowNative(ex);
+        }
+        return false;
+      }
+
+      bool ManagedCacheWriterGeneric::beforeCreate(const EntryEvent& ev)
+      {
+        try {
+          Apache::Geode::Client::EntryEvent<Object^, Object^> mevent(&ev);
+
+          return m_managedptr->BeforeCreate(%mevent);
+        }
+        catch (Apache::Geode::Client::GeodeException^ ex) {
+          ex->ThrowNative();
+        }
+        catch (System::Exception^ ex) {
+          Apache::Geode::Client::GeodeException::ThrowNative(ex);
+        }
+        return false;
+      }
+
+      bool ManagedCacheWriterGeneric::beforeDestroy(const EntryEvent& ev)
+      {
+        try {
+          Apache::Geode::Client::EntryEvent<Object^, Object^> mevent(&ev);
+
+          return m_managedptr->BeforeDestroy(%mevent);
+        }
+        catch (Apache::Geode::Client::GeodeException^ ex) {
+          ex->ThrowNative();
+        }
+        catch (System::Exception^ ex) {
+          Apache::Geode::Client::GeodeException::ThrowNative(ex);
+        }
+        return false;
+      }
+      bool ManagedCacheWriterGeneric::beforeRegionClear(const RegionEvent& ev)
+      {
+        try {
+          Apache::Geode::Client::RegionEvent<Object^, Object^> mevent(&ev);
+
+          return m_managedptr->BeforeRegionClear(%mevent);
+        }
+        catch (Apache::Geode::Client::GeodeException^ ex) {
+          ex->ThrowNative();
+        }
+        catch (System::Exception^ ex) {
+          Apache::Geode::Client::GeodeException::ThrowNative(ex);
+        }
+        return false;
+      }
+
+      bool ManagedCacheWriterGeneric::beforeRegionDestroy(const RegionEvent& 
ev)
+      {
+        try {
+          Apache::Geode::Client::RegionEvent<Object^, Object^> mevent(&ev);
+
+          return m_managedptr->BeforeRegionDestroy(%mevent);
+        }
+        catch (Apache::Geode::Client::GeodeException^ ex) {
+          ex->ThrowNative();
+        }
+        catch (System::Exception^ ex) {
+          Apache::Geode::Client::GeodeException::ThrowNative(ex);
+        }
+        return false;
+      }
+
+      void ManagedCacheWriterGeneric::close(const RegionPtr& rp)
+      {
+        try {
+          Apache::Geode::Client::IRegion<Object^, Object^>^ mregion =
+            Apache::Geode::Client::Region<Object^, Object^>::Create(rp);
+
+          
m_managedptr->Close(reinterpret_cast<Apache::Geode::Client::Region<Object^, 
Object^>^>(mregion));
+        }
+        catch (Apache::Geode::Client::GeodeException^ ex) {
+          ex->ThrowNative();
+        }
+        catch (System::Exception^ ex) {
+          Apache::Geode::Client::GeodeException::ThrowNative(ex);
+        }
+      }
+
+    }  // namespace client
+  }  // namespace geode
+}  // namespace apache
+

http://git-wip-us.apache.org/repos/asf/geode-native/blob/6cbd424f/clicache/src/impl/ManagedCacheWriter.hpp
----------------------------------------------------------------------
diff --git a/clicache/src/impl/ManagedCacheWriter.hpp 
b/clicache/src/impl/ManagedCacheWriter.hpp
new file mode 100644
index 0000000..0b6eba1
--- /dev/null
+++ b/clicache/src/impl/ManagedCacheWriter.hpp
@@ -0,0 +1,191 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "../geode_defs.hpp"
+#include <vcclr.h>
+#include "begin_native.hpp"
+#include <geode/CacheWriter.hpp>
+#include "end_native.hpp"
+
+#include "../ICacheWriter.hpp"
+
+using namespace System;
+
+namespace apache
+{
+  namespace geode
+  {
+    namespace client
+    {
+
+      /// <summary>
+      /// Wraps the managed <see cref="Apache.Geode.Client.ICacheWriter" />
+      /// object and implements the native 
<c>apache::geode::client::CacheWriter</c> interface.
+      /// </summary>
+      class ManagedCacheWriterGeneric
+        : public CacheWriter
+      {
+      public:
+
+        /// <summary>
+        /// Constructor to initialize with the provided managed object.
+        /// </summary>
+        /// <param name="userptr">
+        /// The managed object.
+        /// </param>
+        inline ManagedCacheWriterGeneric(Object^ userptr) : m_userptr(userptr) 
{ }
+
+        /// <summary>
+        /// Static function to create a <c>ManagedCacheWriter</c> using given
+        /// managed assembly path and given factory function.
+        /// </summary>
+        /// <param name="assemblyPath">
+        /// The path of the managed assembly that contains the 
<c>ICacheWriter</c>
+        /// factory function.
+        /// </param>
+        /// <param name="factoryFunctionName">
+        /// The name of the factory function of the managed class for creating
+        /// an object that implements <c>ICacheWriter</c>.
+        /// This should be a static function of the format
+        /// {Namespace}.{Class Name}.{Method Name}.
+        /// </param>
+        /// <exception cref="IllegalArgumentException">
+        /// If the managed library cannot be loaded or the factory function 
fails.
+        /// </exception>
+        static CacheWriter* create(const char* assemblyPath,
+          const char* factoryFunctionName);
+
+        virtual ~ManagedCacheWriterGeneric() { }
+
+        /// <summary>
+        /// Called before an entry is updated. The entry update is initiated 
by a
+        /// <c>put</c> or a <c>get</c> that causes the loader to update an 
existing entry.
+        /// </summary>
+        /// <remarks>
+        /// The entry previously existed in the cache where the operation was
+        /// initiated, although the old value may have been null. The entry 
being
+        /// updated may or may not exist in the local cache where the 
CacheWriter is
+        /// installed.
+        /// </remarks>
+        /// <param name="ev">
+        /// EntryEvent denotes the event object associated with updating the 
entry
+        /// </param>
+        /// <seealso cref="Apache.Geode.Client.Region.Put" />
+        /// <seealso cref="Apache.Geode.Client.Region.Get" />
+        bool beforeUpdate(const EntryEvent& ev);
+
+        /// <summary>
+        /// Called before an entry is created. Entry creation is initiated by a
+        /// <c>create</c>, a <c>put</c>, or a <c>get</c>.
+        /// </summary>
+        /// <remarks>
+        /// The <c>CacheWriter</c> can determine whether this value comes from 
a
+        /// <c>get</c> or not from <c>load</c>. The entry being created may 
already
+        /// exist in the local cache where this <c>CacheWriter</c> is 
installed,
+        /// but it does not yet exist in the cache where the operation was 
initiated.
+        /// </remarks>
+        /// <param name="ev">
+        /// EntryEvent denotes the event object associated with creating the 
entry
+        /// </param>
+        /// <seealso cref="Apache.Geode.Client.Region.Create" />
+        /// <seealso cref="Apache.Geode.Client.Region.Put" />
+        /// <seealso cref="Apache.Geode.Client.Region.Get" />
+        bool beforeCreate(const EntryEvent& ev);
+
+        /// <summary>
+        /// Called before an entry is destroyed.
+        /// </summary>
+        /// <remarks>
+        /// The entry being destroyed may or may
+        /// not exist in the local cache where the CacheWriter is installed. 
This method
+        /// is <em>not</em> called as a result of expiration or
+        /// <see cref="Apache.Geode.Client.Region.LocalDestroyRegion" />.
+        /// </remarks>
+        /// <param name="ev">
+        /// EntryEvent denotes the event object associated with destroying the 
entry
+        /// </param>
+        /// <seealso cref="Apache.Geode.Client.Region.Destroy" />
+        bool beforeDestroy(const EntryEvent& ev);
+
+        /// <summary>
+        /// called before this region is cleared
+        /// </summary>
+        bool beforeRegionClear(const RegionEvent& ev);
+
+        /// <summary>
+        /// called before this region is destroyed
+        /// </summary>
+        /// <param name="ev">
+        /// RegionEvent denotes the event object associated with destroying 
the region
+        /// </param>
+        /// <seealso cref="Apache.Geode.Client.Region.DestroyRegion" />
+        bool beforeRegionDestroy(const RegionEvent& ev);
+
+        /// <summary>
+        /// Called when the region containing this callback is destroyed, when
+        /// the cache is closed.
+        /// </summary>
+        /// <remarks>
+        /// Implementations should clean up any external
+        /// resources, such as database connections. Any runtime exceptions 
this method
+        /// throws will be logged.
+        /// <para>
+        /// It is possible for this method to be called multiple times on a 
single
+        /// callback instance, so implementations must be tolerant of this.
+        /// </para>
+        /// </remarks>
+        /// <seealso cref="Apache.Geode.Client.Cache.Close" />
+        /// <seealso cref="Apache.Geode.Client.Region.DestroyRegion" />
+        void close(const RegionPtr& rp);
+
+        /// <summary>
+        /// Returns the wrapped managed object reference.
+        /// </summary>
+        inline Apache::Geode::Client::ICacheWriter<Object^, Object^>^ ptr() 
const
+        {
+          return m_managedptr;
+        }
+
+        inline void setptr(Apache::Geode::Client::ICacheWriter<Object^, 
Object^>^ managedptr)
+        {
+          m_managedptr = managedptr;
+        }
+
+        inline Object^ userptr() const
+        {
+          return m_userptr;
+        }
+
+
+      private:
+
+        /// <summary>
+        /// Using gcroot to hold the managed delegate pointer (since it cannot 
be stored directly).
+        /// Note: not using auto_gcroot since it will result in 'Dispose' of 
the ICacheWriter
+        /// to be called which is not what is desired when this object is 
destroyed. Normally this
+        /// managed object may be created by the user and will be handled 
automatically by the GC.
+        /// </summary>
+        gcroot<Apache::Geode::Client::ICacheWriter<Object^, Object^>^> 
m_managedptr;
+
+        gcroot<Object^> m_userptr;
+      };
+
+    }  // namespace client
+  }  // namespace geode
+}  // namespace apache

http://git-wip-us.apache.org/repos/asf/geode-native/blob/6cbd424f/clicache/src/impl/ManagedCacheableDelta.cpp
----------------------------------------------------------------------
diff --git a/clicache/src/impl/ManagedCacheableDelta.cpp 
b/clicache/src/impl/ManagedCacheableDelta.cpp
new file mode 100644
index 0000000..8c0c0d1
--- /dev/null
+++ b/clicache/src/impl/ManagedCacheableDelta.cpp
@@ -0,0 +1,282 @@
+/*
+ * 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.
+ */
+
+#include "begin_native.hpp"
+#include <GeodeTypeIdsImpl.hpp>
+#include "end_native.hpp"
+
+#include "ManagedCacheableDelta.hpp"
+#include "../DataInput.hpp"
+#include "../DataOutput.hpp"
+#include "../CacheableString.hpp"
+#include "../ExceptionTypes.hpp"
+#include "SafeConvert.hpp"
+
+
+using namespace System;
+
+namespace apache
+{
+  namespace geode
+  {
+    namespace client
+    {
+
+      void ManagedCacheableDeltaGeneric::toData(DataOutput& output) const
+      {
+        try {
+          System::UInt32 pos = (int)output.getBufferLength();
+          Apache::Geode::Client::DataOutput mg_output(&output, true);
+          m_managedSerializableptr->ToData(%mg_output);
+          //this will move the cursor in c++ layer
+          mg_output.WriteBytesToUMDataOutput();
+          ManagedCacheableDeltaGeneric* tmp = 
const_cast<ManagedCacheableDeltaGeneric*>(this);
+          tmp->m_objectSize = (int)(output.getBufferLength() - pos);
+        }
+        catch (Apache::Geode::Client::GeodeException^ ex) {
+          ex->ThrowNative();
+        }
+        catch (System::Exception^ ex) {
+          Apache::Geode::Client::GeodeException::ThrowNative(ex);
+        }
+      }
+
+      Serializable* ManagedCacheableDeltaGeneric::fromData(DataInput& input)
+      {
+        try {
+          int pos = input.getBytesRead();
+          Apache::Geode::Client::DataInput mg_input(&input, true, 
input.getCache());
+          m_managedSerializableptr->FromData(%mg_input);
+
+          //this will move the cursor in c++ layer
+          input.advanceCursor(mg_input.BytesReadInternally);
+
+          m_objectSize = input.getBytesRead() - pos;
+
+          if (m_hashcode == 0)
+            m_hashcode = m_managedptr->GetHashCode();
+
+        }
+        catch (Apache::Geode::Client::GeodeException^ ex) {
+          ex->ThrowNative();
+        }
+        catch (System::Exception^ ex) {
+          Apache::Geode::Client::GeodeException::ThrowNative(ex);
+        }
+        return this;
+      }
+
+      System::UInt32 ManagedCacheableDeltaGeneric::objectSize() const
+      {
+        try {
+          int ret = m_managedSerializableptr->ObjectSize;
+          if (ret > m_objectSize)
+            return ret;
+          else
+            return m_objectSize;
+        }
+        catch (Apache::Geode::Client::GeodeException^ ex) {
+          ex->ThrowNative();
+        }
+        catch (System::Exception^ ex) {
+          Apache::Geode::Client::GeodeException::ThrowNative(ex);
+        }
+        return 0;
+      }
+
+      System::Int32 ManagedCacheableDeltaGeneric::classId() const
+      {
+        System::UInt32 classId;
+        try {
+          classId = m_managedSerializableptr->ClassId;
+        }
+        catch (Apache::Geode::Client::GeodeException^ ex) {
+          ex->ThrowNative();
+        }
+        catch (System::Exception^ ex) {
+          Apache::Geode::Client::GeodeException::ThrowNative(ex);
+        }
+        return (classId >= 0x80000000 ? 0 : classId);
+      }
+
+      int8_t ManagedCacheableDeltaGeneric::typeId() const
+      {
+        try {
+          System::UInt32 classId = m_classId;
+          if (classId >= 0x80000000) {
+            return (int8_t)((classId - 0x80000000) % 0x20000000);
+          }
+          else if (classId <= 0x7F) {
+            return (int8_t)GeodeTypeIdsImpl::CacheableUserData;
+          }
+          else if (classId <= 0x7FFF) {
+            return (int8_t)GeodeTypeIdsImpl::CacheableUserData2;
+          }
+          else {
+            return (int8_t)GeodeTypeIdsImpl::CacheableUserData4;
+          }
+        }
+        catch (Apache::Geode::Client::GeodeException^ ex) {
+          ex->ThrowNative();
+        }
+        catch (System::Exception^ ex) {
+          Apache::Geode::Client::GeodeException::ThrowNative(ex);
+        }
+        return 0;
+      }
+
+      int8_t ManagedCacheableDeltaGeneric::DSFID() const
+      {
+        // convention that [0x8000000, 0xa0000000) is for FixedIDDefault,
+        // [0xa000000, 0xc0000000) is for FixedIDByte,
+        // [0xc0000000, 0xe0000000) is for FixedIDShort
+        // and [0xe0000000, 0xffffffff] is for FixedIDInt
+        // Note: depends on fact that FixedIDByte is 1, FixedIDShort is 2
+        // and FixedIDInt is 3; if this changes then correct this accordingly
+        System::UInt32 classId = m_managedSerializableptr->ClassId;
+        if (classId >= 0x80000000) {
+          return (int8_t)((classId - 0x80000000) / 0x20000000);
+        }
+        return 0;
+      }
+
+      bool ManagedCacheableDeltaGeneric::hasDelta()
+      {
+        return m_managedptr->HasDelta();
+      }
+
+      void ManagedCacheableDeltaGeneric::toDelta(DataOutput& output) const
+      {
+        try {
+          Apache::Geode::Client::DataOutput mg_output(&output, true);
+          m_managedptr->ToDelta(%mg_output);
+          //this will move the cursor in c++ layer
+          mg_output.WriteBytesToUMDataOutput();
+        }
+        catch (Apache::Geode::Client::GeodeException^ ex) {
+          ex->ThrowNative();
+        }
+        catch (System::Exception^ ex) {
+          Apache::Geode::Client::GeodeException::ThrowNative(ex);
+        }
+      }
+
+      void ManagedCacheableDeltaGeneric::fromDelta(DataInput& input)
+      {
+        try {
+          Apache::Geode::Client::DataInput mg_input(&input, true, 
input.getCache());
+          m_managedptr->FromDelta(%mg_input);
+
+          //this will move the cursor in c++ layer
+          input.advanceCursor(mg_input.BytesReadInternally);
+
+          m_hashcode = m_managedptr->GetHashCode();
+        }
+        catch (Apache::Geode::Client::GeodeException^ ex) {
+          ex->ThrowNative();
+        }
+        catch (System::Exception^ ex) {
+          Apache::Geode::Client::GeodeException::ThrowNative(ex);
+        }
+      }
+
+      DeltaPtr ManagedCacheableDeltaGeneric::clone()
+      {
+        try {
+          ICloneable^ cloneable = dynamic_cast<ICloneable^>((
+            Apache::Geode::Client::IGeodeDelta^) m_managedptr);
+          if (cloneable) {
+            Apache::Geode::Client::IGeodeSerializable^ Mclone =
+              
dynamic_cast<Apache::Geode::Client::IGeodeSerializable^>(cloneable->Clone());
+            return DeltaPtr(static_cast<ManagedCacheableDeltaGeneric*>(
+              SafeMSerializableConvertGeneric(Mclone)));
+          }
+          else {
+            return Delta::clone();
+          }
+        }
+        catch (Apache::Geode::Client::GeodeException^ ex) {
+          ex->ThrowNative();
+        }
+        catch (System::Exception^ ex) {
+          Apache::Geode::Client::GeodeException::ThrowNative(ex);
+        }
+        return nullptr;
+      }
+
+      bool ManagedCacheableDeltaGeneric::operator ==(const 
apache::geode::client::CacheableKey& other) const
+      {
+        try {
+          // now checking classId(), typeId(), DSFID() etc. will be much more
+          // expensive than just a dynamic_cast
+          const ManagedCacheableDeltaGeneric* p_other =
+            dynamic_cast<const ManagedCacheableDeltaGeneric*>(&other);
+          if (p_other != NULL) {
+            return m_managedptr->Equals(p_other->ptr());
+          }
+          return false;
+        }
+        catch (Apache::Geode::Client::GeodeException^ ex) {
+          ex->ThrowNative();
+        }
+        catch (System::Exception^ ex) {
+          Apache::Geode::Client::GeodeException::ThrowNative(ex);
+        }
+        return false;
+      }
+
+      bool ManagedCacheableDeltaGeneric::operator == (const 
ManagedCacheableDeltaGeneric& other) const
+      {
+        try {
+          return m_managedptr->Equals(other.ptr());
+        }
+        catch (Apache::Geode::Client::GeodeException^ ex) {
+          ex->ThrowNative();
+        }
+        catch (System::Exception^ ex) {
+          Apache::Geode::Client::GeodeException::ThrowNative(ex);
+        }
+        return false;
+
+      }
+
+      System::Int32 ManagedCacheableDeltaGeneric::hashcode() const
+      {
+        throw gcnew System::NotSupportedException;
+      }
+
+      size_t ManagedCacheableDeltaGeneric::logString(char* buffer, size_t 
maxLength) const
+      {
+        try {
+          if (maxLength > 0) {
+            String^ logstr = m_managedptr->GetType()->Name + '(' +
+              m_managedptr->ToString() + ')';
+            Apache::Geode::Client::ManagedString mg_str(logstr);
+            return snprintf(buffer, maxLength, "%s", mg_str.CharPtr);
+          }
+        }
+        catch (Apache::Geode::Client::GeodeException^ ex) {
+          ex->ThrowNative();
+        }
+        catch (System::Exception^ ex) {
+          Apache::Geode::Client::GeodeException::ThrowNative(ex);
+        }
+        return 0;
+      }
+    }  // namespace client
+  }  // namespace geode
+}  // namespace apache

http://git-wip-us.apache.org/repos/asf/geode-native/blob/6cbd424f/clicache/src/impl/ManagedCacheableDelta.hpp
----------------------------------------------------------------------
diff --git a/clicache/src/impl/ManagedCacheableDelta.hpp 
b/clicache/src/impl/ManagedCacheableDelta.hpp
new file mode 100644
index 0000000..9211a8d
--- /dev/null
+++ b/clicache/src/impl/ManagedCacheableDelta.hpp
@@ -0,0 +1,189 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "../geode_defs.hpp"
+#include <vcclr.h>
+#include "begin_native.hpp"
+#include <geode/Delta.hpp>
+#include "end_native.hpp"
+
+#include "../IGeodeDelta.hpp"
+#include "../IGeodeSerializable.hpp"
+
+
+using namespace System;
+//using namespace apache::geode::client;
+
+namespace Apache
+{
+  namespace Geode
+  {
+    namespace Client
+    {
+
+      interface class IGeodeSerializable;
+      interface class IGeodeDelta;
+    }  // namespace Client
+  }  // namespace Geode
+}  // namespace Apache
+
+
+namespace apache
+{
+  namespace geode
+  {
+    namespace client
+    {
+
+      /// <summary>
+      /// Wraps the managed <see cref="Apache.Geode.Client.IGeodeDelta" />
+      /// object and implements the native 
<c>apache::geode::client::CacheableKey</c> interface.
+      /// </summary>
+      class ManagedCacheableDeltaGeneric
+        : public apache::geode::client::CacheableKey, public 
apache::geode::client::Delta
+      {
+      private:
+        int m_hashcode;
+        int m_classId;
+        int m_objectSize;
+      public:
+
+        /// <summary>
+        /// Constructor to initialize with the provided managed object.
+        /// </summary>
+        /// <param name="managedptr">
+        /// The managed object.
+        /// </param>
+        inline ManagedCacheableDeltaGeneric(
+          Apache::Geode::Client::IGeodeDelta^ managedptr)
+          : Delta(nullptr), m_managedptr(managedptr)
+        {
+          m_managedSerializableptr = dynamic_cast 
<Apache::Geode::Client::IGeodeSerializable^> (managedptr);
+          m_classId = m_managedSerializableptr->ClassId;
+          m_objectSize = 0;
+        }
+
+        inline ManagedCacheableDeltaGeneric(
+          Apache::Geode::Client::IGeodeDelta^ managedptr, int hashcode, int 
classId)
+          :Delta(nullptr),  m_managedptr(managedptr) {
+          m_hashcode = hashcode;
+          m_classId = classId;
+          m_managedSerializableptr = dynamic_cast 
<Apache::Geode::Client::IGeodeSerializable^> (managedptr);
+          m_objectSize = 0;
+        }
+
+        /// <summary>
+        /// serialize this object
+        /// </summary>
+        virtual void toData(apache::geode::client::DataOutput& output) const;
+
+        /// <summary>
+        /// deserialize this object, typical implementation should return
+        /// the 'this' pointer.
+        /// </summary>
+        virtual apache::geode::client::Serializable* 
fromData(apache::geode::client::DataInput& input);
+
+        virtual void toDelta(apache::geode::client::DataOutput& output) const;
+
+        virtual void fromDelta(apache::geode::client::DataInput& input);
+
+        /// <summary>
+        /// return the size of this object in bytes
+        /// </summary>
+        virtual System::UInt32 objectSize() const;
+
+        /// <summary>
+        /// return the classId of the instance being serialized.
+        /// This is used by deserialization to determine what instance
+        /// type to create and deserialize into.
+        /// </summary>
+        virtual System::Int32 classId() const;
+
+        /// <summary>
+        /// return the typeId of the instance being serialized.
+        /// This is used by deserialization to determine what instance
+        /// type to create and deserialize into.
+        /// </summary>
+        virtual int8_t typeId() const;
+
+        /// <summary>
+        /// return the Data Serialization Fixed ID type.
+        /// This is used to determine what instance type to create
+        /// and deserialize into.
+        ///
+        /// Note that this should not be overridden by custom implementations
+        /// and is reserved only for builtin types.
+        /// </summary>
+        virtual int8_t DSFID() const;
+
+        virtual bool hasDelta();
+
+        virtual apache::geode::client::DeltaPtr clone();
+
+        /// <summary>
+        /// return the hashcode for this key.
+        /// </summary>
+        virtual System::Int32 hashcode() const;
+
+        /// <summary>
+        /// return true if this key matches other CacheableKey
+        /// </summary>
+        virtual bool operator == (const CacheableKey& other) const;
+
+        /// <summary>
+        /// return true if this key matches other ManagedCacheableDeltaGeneric
+        /// </summary>
+        virtual bool operator == (const ManagedCacheableDeltaGeneric& other) 
const;
+
+        /// <summary>
+        /// Copy the string form of a key into a char* buffer for logging 
purposes.
+        /// implementations should only generate a string as long as maxLength 
chars,
+        /// and return the number of chars written. buffer is expected to be 
large 
+        /// enough to hold at least maxLength chars.
+        /// The default implementation renders the classname and instance 
address.
+        /// </summary>
+        virtual size_t logString(char* buffer, size_t maxLength) const;
+
+        /// <summary>
+        /// Returns the wrapped managed object reference.
+        /// </summary>
+        inline Apache::Geode::Client::IGeodeDelta^ ptr() const
+        {
+          return m_managedptr;
+        }
+
+
+      private:
+
+        /// <summary>
+        /// Using gcroot to hold the managed delegate pointer (since it cannot 
be stored directly).
+        /// Note: not using auto_gcroot since it will result in 'Dispose' of 
the IGeodeDelta
+        /// to be called which is not what is desired when this object is 
destroyed. Normally this
+        /// managed object may be created by the user and will be handled 
automatically by the GC.
+        /// </summary>
+        gcroot<Apache::Geode::Client::IGeodeDelta^> m_managedptr;
+        gcroot<Apache::Geode::Client::IGeodeSerializable^> 
m_managedSerializableptr;
+        // Disable the copy and assignment constructors
+        ManagedCacheableDeltaGeneric(const ManagedCacheableDeltaGeneric&);
+        ManagedCacheableDeltaGeneric& operator = (const 
ManagedCacheableDeltaGeneric&);
+      };
+
+    }  // namespace client
+  }  // namespace geode
+}  // namespace apache

http://git-wip-us.apache.org/repos/asf/geode-native/blob/6cbd424f/clicache/src/impl/ManagedCacheableDeltaBytes.cpp
----------------------------------------------------------------------
diff --git a/clicache/src/impl/ManagedCacheableDeltaBytes.cpp 
b/clicache/src/impl/ManagedCacheableDeltaBytes.cpp
new file mode 100644
index 0000000..18472c4
--- /dev/null
+++ b/clicache/src/impl/ManagedCacheableDeltaBytes.cpp
@@ -0,0 +1,337 @@
+/*
+ * 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.
+ */
+
+#include "begin_native.hpp"
+#include <GeodeTypeIdsImpl.hpp>
+#include "end_native.hpp"
+
+#include "ManagedCacheableDeltaBytes.hpp"
+#include "../DataInput.hpp"
+#include "../DataOutput.hpp"
+#include "../CacheableString.hpp"
+#include "../ExceptionTypes.hpp"
+#include "SafeConvert.hpp"
+
+
+using namespace System;
+
+namespace apache
+{
+  namespace geode
+  {
+    namespace client
+    {
+
+      void ManagedCacheableDeltaBytesGeneric::toData(DataOutput& output) const
+      {
+        
Apache::Geode::Client::Log::Debug("ManagedCacheableDeltaBytesGeneric::toData: 
current domain ID: " + System::Threading::Thread::GetDomainID() + " for object: 
" + System::Convert::ToString((uint64_t) this) + " with its domain ID: " + 
m_domainId);
+        try {
+          output.writeBytesOnly(m_bytes, m_size);
+        }
+        catch (Apache::Geode::Client::GeodeException^ ex) {
+          ex->ThrowNative();
+        }
+        catch (System::Exception^ ex) {
+          Apache::Geode::Client::GeodeException::ThrowNative(ex);
+        }
+      }
+
+      Serializable* ManagedCacheableDeltaBytesGeneric::fromData(DataInput& 
input)
+      {
+        try {
+          
Apache::Geode::Client::Log::Debug("ManagedCacheableDeltaBytes::fromData: 
classid " + m_classId);
+          Apache::Geode::Client::DataInput mg_input(&input, true, 
input.getCache());
+          const System::Byte* objStartPos = input.currentBufferPosition();
+
+          Apache::Geode::Client::IGeodeSerializable^ obj =
+            
Apache::Geode::Client::Serializable::GetTypeFactoryMethodGeneric(m_classId)();
+          obj->FromData(%mg_input);
+          input.advanceCursor(mg_input.BytesReadInternally);
+
+          m_hashCode = obj->GetHashCode();
+
+          const System::Byte* objEndPos = input.currentBufferPosition();
+
+          //m_size = mg_input.BytesRead;
+          m_size = (System::UInt32)(objEndPos - objStartPos);
+          
Apache::Geode::Client::Log::Debug("ManagedCacheableDeltaBytes::fromData: 
objectSize = " + m_size + " m_hashCode = " + m_hashCode);
+          m_bytes = input.getBufferCopyFrom(objStartPos, m_size);
+        }
+        catch (Apache::Geode::Client::GeodeException^ ex) {
+          ex->ThrowNative();
+        }
+        catch (System::Exception^ ex) {
+          Apache::Geode::Client::GeodeException::ThrowNative(ex);
+        }
+        return this;
+      }
+
+      System::UInt32 ManagedCacheableDeltaBytesGeneric::objectSize() const
+      {
+        try {
+          return m_size;
+        }
+        catch (Apache::Geode::Client::GeodeException^ ex) {
+          ex->ThrowNative();
+        }
+        catch (System::Exception^ ex) {
+          Apache::Geode::Client::GeodeException::ThrowNative(ex);
+        }
+        return 0;
+      }
+
+      System::Int32 ManagedCacheableDeltaBytesGeneric::classId() const
+      {
+        System::UInt32 classId;
+        try {
+          classId = m_classId;
+        }
+        catch (Apache::Geode::Client::GeodeException^ ex) {
+          ex->ThrowNative();
+        }
+        catch (System::Exception^ ex) {
+          Apache::Geode::Client::GeodeException::ThrowNative(ex);
+        }
+        return (classId >= 0x80000000 ? 0 : classId);
+      }
+
+      int8_t ManagedCacheableDeltaBytesGeneric::typeId() const
+      {
+        try {
+          System::UInt32 classId = m_classId;
+          if (classId >= 0x80000000) {
+            return (int8_t)((classId - 0x80000000) % 0x20000000);
+          }
+          else if (classId <= 0x7F) {
+            return (int8_t)GeodeTypeIdsImpl::CacheableUserData;
+          }
+          else if (classId <= 0x7FFF) {
+            return (int8_t)GeodeTypeIdsImpl::CacheableUserData2;
+          }
+          else {
+            return (int8_t)GeodeTypeIdsImpl::CacheableUserData4;
+          }
+        }
+        catch (Apache::Geode::Client::GeodeException^ ex) {
+          ex->ThrowNative();
+        }
+        catch (System::Exception^ ex) {
+          Apache::Geode::Client::GeodeException::ThrowNative(ex);
+        }
+        return 0;
+      }
+
+      int8_t ManagedCacheableDeltaBytesGeneric::DSFID() const
+      {
+        // convention that [0x8000000, 0xa0000000) is for FixedIDDefault,
+        // [0xa000000, 0xc0000000) is for FixedIDByte,
+        // [0xc0000000, 0xe0000000) is for FixedIDShort
+        // and [0xe0000000, 0xffffffff] is for FixedIDInt
+        // Note: depends on fact that FixedIDByte is 1, FixedIDShort is 2
+        // and FixedIDInt is 3; if this changes then correct this accordingly
+        System::UInt32 classId = m_classId;
+        if (classId >= 0x80000000) {
+          return (int8_t)((classId - 0x80000000) / 0x20000000);
+        }
+        return 0;
+      }
+
+      bool ManagedCacheableDeltaBytesGeneric::hasDelta()
+      {
+        //Apache::Geode::Client::IGeodeDelta^ deltaObj = 
this->getManagedObject();
+        //return deltaObj->HasDelta();
+        return m_hasDelta;
+      }
+
+      void ManagedCacheableDeltaBytesGeneric::toDelta(DataOutput& output) const
+      {
+        try {
+          
Apache::Geode::Client::Log::Debug("ManagedCacheableDeltaBytes::toDelta: current 
domain ID: " + System::Threading::Thread::GetDomainID() + " for object: " + 
System::Convert::ToString((uint64_t) this) + " with its domain ID: " + 
m_domainId);
+          Apache::Geode::Client::IGeodeDelta^ deltaObj = 
this->getManagedObject();
+          Apache::Geode::Client::DataOutput mg_output(&output, true);
+          deltaObj->ToDelta(%mg_output);
+          mg_output.WriteBytesToUMDataOutput();
+        }
+        catch (Apache::Geode::Client::GeodeException^ ex) {
+          ex->ThrowNative();
+        }
+        catch (System::Exception^ ex) {
+          Apache::Geode::Client::GeodeException::ThrowNative(ex);
+        }
+      }
+
+      void ManagedCacheableDeltaBytesGeneric::fromDelta(DataInput& input)
+      {
+        try {
+          
Apache::Geode::Client::Log::Debug("ManagedCacheableDeltaBytes::fromDelta:");
+          Apache::Geode::Client::IGeodeDelta^ deltaObj = 
this->getManagedObject();
+          Apache::Geode::Client::DataInput mg_input(&input, true, 
input.getCache());
+          deltaObj->FromDelta(%mg_input);
+
+          Apache::Geode::Client::IGeodeSerializable^ managedptr =
+            dynamic_cast <Apache::Geode::Client::IGeodeSerializable^> 
(deltaObj);
+          if (managedptr != nullptr)
+          {
+            
Apache::Geode::Client::Log::Debug("ManagedCacheableDeltaBytes::fromDelta: 
current domain ID: " + System::Threading::Thread::GetDomainID() + " for object: 
" + System::Convert::ToString((uint64_t) this) + " with its domain ID: " + 
m_domainId);
+            
Apache::Geode::Client::Log::Debug("ManagedCacheableDeltaBytes::fromDelta: 
classid " + managedptr->ClassId + " : " + managedptr->ToString());
+            auto dataOut = input.getCache()->createDataOutput();
+            Apache::Geode::Client::DataOutput mg_output(dataOut.get(), true);
+            managedptr->ToData(%mg_output);
+
+            //move cursor
+            //dataOut.advanceCursor(mg_output.BufferLength);
+            mg_output.WriteBytesToUMDataOutput();
+
+            GF_SAFE_DELETE(m_bytes);
+            m_bytes = dataOut->getBufferCopy();
+            m_size = dataOut->getBufferLength();
+            
Apache::Geode::Client::Log::Debug("ManagedCacheableDeltaBytes::fromDelta 
objectSize = " + m_size + " m_hashCode = " + m_hashCode);
+            m_hashCode = managedptr->GetHashCode();
+          }
+        }
+        catch (Apache::Geode::Client::GeodeException^ ex) {
+          ex->ThrowNative();
+        }
+        catch (System::Exception^ ex) {
+          Apache::Geode::Client::GeodeException::ThrowNative(ex);
+        }
+      }
+
+      DeltaPtr ManagedCacheableDeltaBytesGeneric::clone()
+      {
+        try {
+          Apache::Geode::Client::IGeodeDelta^ deltaObj = 
this->getManagedObject();
+          ICloneable^ cloneable = 
dynamic_cast<ICloneable^>((Apache::Geode::Client::IGeodeDelta^) deltaObj);
+          if (cloneable) {
+            Apache::Geode::Client::IGeodeSerializable^ Mclone =
+              
dynamic_cast<Apache::Geode::Client::IGeodeSerializable^>(cloneable->Clone());
+            return DeltaPtr(static_cast<ManagedCacheableDeltaBytesGeneric*>(
+              SafeMSerializableConvertGeneric(Mclone)));
+          }
+          else {
+            return Delta::clone();
+          }
+        }
+        catch (Apache::Geode::Client::GeodeException^ ex) {
+          ex->ThrowNative();
+        }
+        catch (System::Exception^ ex) {
+          Apache::Geode::Client::GeodeException::ThrowNative(ex);
+        }
+        return nullptr;
+      }
+
+      Apache::Geode::Client::IGeodeDelta^
+        ManagedCacheableDeltaBytesGeneric::getManagedObject() const
+      {
+
+        
Apache::Geode::Client::Log::Debug("ManagedCacheableDeltaBytes::getManagedObject");
+
+        auto dinp = m_cache->createDataInput(m_bytes, m_size);
+        Apache::Geode::Client::DataInput mg_dinp(dinp.get(), true, m_cache);
+        Apache::Geode::Client::TypeFactoryMethodGeneric^ creationMethod =
+          
Apache::Geode::Client::Serializable::GetTypeFactoryMethodGeneric(m_classId);
+        Apache::Geode::Client::IGeodeSerializable^ newObj = creationMethod();
+
+        Apache::Geode::Client::IGeodeDelta^ managedDeltaptr =
+          dynamic_cast <Apache::Geode::Client::IGeodeDelta^> 
(newObj->FromData(%mg_dinp));
+        return managedDeltaptr;
+      }
+
+      bool ManagedCacheableDeltaBytesGeneric::operator ==(const 
apache::geode::client::CacheableKey& other) const
+      {
+        try {
+          
Apache::Geode::Client::Log::Debug("ManagedCacheableDeltaBytesGeneric::equal");
+          // now checking classId(), typeId(), DSFID() etc. will be much more
+          // expensive than just a dynamic_cast
+          const ManagedCacheableDeltaBytesGeneric* p_other =
+            dynamic_cast<const ManagedCacheableDeltaBytesGeneric*>(&other);
+          if (p_other != NULL) {
+            auto di = m_cache->createDataInput(m_bytes, m_size);
+            Apache::Geode::Client::DataInput mg_input(di.get(), true, m_cache);
+            Apache::Geode::Client::IGeodeSerializable^ obj =
+              
Apache::Geode::Client::Serializable::GetTypeFactoryMethodGeneric(m_classId)();
+            obj->FromData(%mg_input);
+            bool ret = obj->Equals(p_other->ptr());
+            
Apache::Geode::Client::Log::Debug("ManagedCacheableDeltaBytesGeneric::equal 
return VAL = " + ret);
+            return ret;
+          }
+        }
+        catch (Apache::Geode::Client::GeodeException^ ex) {
+          ex->ThrowNative();
+        }
+        catch (System::Exception^ ex) {
+          Apache::Geode::Client::GeodeException::ThrowNative(ex);
+        }
+        
Apache::Geode::Client::Log::Debug("ManagedCacheableDeltaBytesGeneric::equal 
returns false");
+        return false;
+      }
+
+      bool ManagedCacheableDeltaBytesGeneric::operator ==(const 
ManagedCacheableDeltaBytesGeneric& other) const
+      {
+        try {
+          
Apache::Geode::Client::Log::Debug("ManagedCacheableDeltaBytesGeneric::equal. ");
+          auto di = m_cache->createDataInput(m_bytes, m_size);
+          Apache::Geode::Client::DataInput mg_input(di.get(), true, m_cache);
+          Apache::Geode::Client::IGeodeSerializable^ obj =
+            
Apache::Geode::Client::Serializable::GetTypeFactoryMethodGeneric(m_classId)();
+          obj->FromData(%mg_input);
+          bool ret = obj->Equals(other.ptr());
+          
Apache::Geode::Client::Log::Debug("ManagedCacheableDeltaBytesGeneric::equal 
return VAL = " + ret);
+          return ret;
+          //return obj->Equals(other.get());
+        }
+        catch (Apache::Geode::Client::GeodeException^ ex) {
+          ex->ThrowNative();
+        }
+        catch (System::Exception^ ex) {
+          Apache::Geode::Client::GeodeException::ThrowNative(ex);
+        }
+        
Apache::Geode::Client::Log::Debug("ManagedCacheableDeltaBytesGeneric::equal 
return false");
+        return false;
+      }
+
+      System::Int32 ManagedCacheableDeltaBytesGeneric::hashcode() const
+      {
+        throw gcnew System::NotSupportedException;
+      }
+
+      size_t ManagedCacheableDeltaBytesGeneric::logString(char* buffer, size_t 
maxLength) const
+      {
+        try {
+          Apache::Geode::Client::IGeodeDelta^ manageObject = 
getManagedObject();
+          if (manageObject != nullptr)
+          {
+            if (maxLength > 0) {
+              String^ logstr = manageObject->GetType()->Name + '(' +
+                manageObject->ToString() + ')';
+              Apache::Geode::Client::ManagedString mg_str(logstr);
+              return snprintf(buffer, maxLength, "%s", mg_str.CharPtr);
+            }
+          }
+        }
+        catch (Apache::Geode::Client::GeodeException^ ex) {
+          ex->ThrowNative();
+        }
+        catch (System::Exception^ ex) {
+          Apache::Geode::Client::GeodeException::ThrowNative(ex);
+        }
+        return 0;
+      }
+    }  // namespace client
+  }  // namespace geode
+}  // namespace apache

http://git-wip-us.apache.org/repos/asf/geode-native/blob/6cbd424f/clicache/src/impl/ManagedCacheableDeltaBytes.hpp
----------------------------------------------------------------------
diff --git a/clicache/src/impl/ManagedCacheableDeltaBytes.hpp 
b/clicache/src/impl/ManagedCacheableDeltaBytes.hpp
new file mode 100644
index 0000000..c5fcbb2
--- /dev/null
+++ b/clicache/src/impl/ManagedCacheableDeltaBytes.hpp
@@ -0,0 +1,218 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "../geode_defs.hpp"
+#include <vcclr.h>
+#include "begin_native.hpp"
+#include "SerializationRegistry.hpp"
+#include <geode/Cache.hpp>
+#include <geode/Delta.hpp>
+#include <geode/DataOutput.hpp>
+#include "end_native.hpp"
+
+#include "../Log.hpp"
+#include "../DataOutput.hpp"
+
+using namespace System;
+
+namespace Apache
+{
+  namespace Geode
+  {
+    namespace Client
+    {
+
+      interface class IGeodeSerializable;
+      interface class IGeodeDelta;
+    }  // namespace Client
+  }  // namespace Geode
+}  // namespace Apache
+
+
+namespace apache
+{
+  namespace geode
+  {
+    namespace client
+    {
+
+
+      /// <summary>
+      /// Wraps the managed <see cref="Apache.Geode.Client.IGeodeDelta" />
+      /// object and implements the native 
<c>apache::geode::client::CacheableKey</c> interface.
+      /// </summary>
+      class ManagedCacheableDeltaBytesGeneric
+        : public CacheableKey, public Delta
+      {
+      public:
+
+        /// <summary>
+        /// Constructor to initialize with the provided managed object.
+        /// </summary>
+        /// <param name="managedDeltaptr">
+        /// The managed object.
+        /// </param>
+        inline ManagedCacheableDeltaBytesGeneric(
+          Apache::Geode::Client::IGeodeDelta^ managedDeltaptr, bool storeBytes)
+          :Delta(nullptr), 
m_domainId(System::Threading::Thread::GetDomainID()),
+          m_classId(0),
+          m_bytes(NULL),
+          m_size(0),
+          m_hasDelta(false),
+          m_hashCode(0)
+        {
+          if (storeBytes)
+            m_hasDelta = managedDeltaptr->HasDelta();
+          Apache::Geode::Client::IGeodeSerializable^ managedptr =
+            dynamic_cast <Apache::Geode::Client::IGeodeSerializable^> 
(managedDeltaptr);
+          if (managedptr != nullptr)
+          {
+            m_classId = managedptr->ClassId;
+            
Apache::Geode::Client::Log::Finer("ManagedCacheableDeltaBytes::Constructor: 
current AppDomain ID: " + System::Threading::Thread::GetDomainID() + " for 
object: " + System::Convert::ToString((uint64_t) this) + " with its AppDomain 
ID: " + m_domainId);
+            
Apache::Geode::Client::Log::Finer("ManagedCacheableDeltaBytes::Constructor: 
class ID " + managedptr->ClassId + " : " + managedptr->ToString() + " 
storeBytes:" + storeBytes);
+            if (storeBytes)
+            {
+              auto dataOut = m_cache->createDataOutput();
+              Apache::Geode::Client::DataOutput mg_output(dataOut.get(), true);
+              managedptr->ToData(%mg_output);
+
+              //move cursor
+              //dataOut.advanceCursor(mg_output.BufferLength);
+              mg_output.WriteBytesToUMDataOutput();
+
+              m_bytes = dataOut->getBufferCopy();
+              m_size = dataOut->getBufferLength();
+              m_hashCode = managedptr->GetHashCode();
+              
Apache::Geode::Client::Log::Finer("ManagedCacheableDeltaBytes::Constructor 
objectSize = " + m_size + " m_hashCode = " + m_hashCode);
+            }
+          }
+        }
+        
+        /// <summary>
+        /// serialize this object
+        /// </summary>
+        virtual void toData(apache::geode::client::DataOutput& output) const;
+
+        /// <summary>
+        /// deserialize this object, typical implementation should return
+        /// the 'this' pointer.
+        /// </summary>
+        virtual apache::geode::client::Serializable* 
fromData(apache::geode::client::DataInput& input);
+
+        virtual void toDelta(apache::geode::client::DataOutput& output) const;
+
+        virtual void fromDelta(apache::geode::client::DataInput& input);
+
+        /// <summary>
+        /// return the size of this object in bytes
+        /// </summary>
+        virtual System::UInt32 objectSize() const;
+
+        /// <summary>
+        /// return the classId of the instance being serialized.
+        /// This is used by deserialization to determine what instance
+        /// type to create and deserialize into.
+        /// </summary>
+        virtual System::Int32 classId() const;
+
+        /// <summary>
+        /// return the typeId of the instance being serialized.
+        /// This is used by deserialization to determine what instance
+        /// type to create and deserialize into.
+        /// </summary>
+        virtual int8_t typeId() const;
+
+        /// <summary>
+        /// return the Data Serialization Fixed ID type.
+        /// This is used to determine what instance type to create
+        /// and deserialize into.
+        ///
+        /// Note that this should not be overridden by custom implementations
+        /// and is reserved only for builtin types.
+        /// </summary>
+        virtual int8_t DSFID() const;
+
+        virtual bool hasDelta();
+
+        virtual apache::geode::client::DeltaPtr clone();
+
+        /// <summary>
+        /// return the hashcode for this key.
+        /// </summary>
+        virtual System::Int32 hashcode() const;
+
+        /// <summary>
+        /// return true if this key matches other CacheableKey
+        /// </summary>
+        virtual bool operator == (const CacheableKey& other) const;
+
+        /// <summary>
+        /// return true if this key matches other 
ManagedCacheableDeltaBytesGeneric
+        /// </summary>
+        virtual bool operator == (const ManagedCacheableDeltaBytesGeneric& 
other) const;
+
+        /// <summary>
+        /// Copy the string form of a key into a char* buffer for logging 
purposes.
+        /// implementations should only generate a string as long as maxLength 
chars,
+        /// and return the number of chars written. buffer is expected to be 
large 
+        /// enough to hold at least maxLength chars.
+        /// The default implementation renders the classname and instance 
address.
+        /// </summary>
+        virtual size_t logString(char* buffer, size_t maxLength) const;
+
+        /// <summary>
+        /// Returns the wrapped managed object reference.
+        /// </summary>
+        inline Apache::Geode::Client::IGeodeDelta^ ptr() const
+        {
+          return getManagedObject();
+        }
+
+        inline ~ManagedCacheableDeltaBytesGeneric()
+        {
+          
Apache::Geode::Client::Log::Finer("ManagedCacheableDeltaBytes::Destructor 
current AppDomain ID: " + System::Threading::Thread::GetDomainID() + " for 
object: " + System::Convert::ToString((uint64_t) this) + " with its AppDomain 
ID: " + m_domainId);
+          GF_SAFE_DELETE(m_bytes);
+        }
+
+      private:
+        Apache::Geode::Client::IGeodeDelta^ getManagedObject() const;
+        /// <summary>
+        /// Using gcroot to hold the managed delegate pointer (since it cannot 
be stored directly).
+        /// Note: not using auto_gcroot since it will result in 'Dispose' of 
the IGeodeDelta
+        /// to be called which is not what is desired when this object is 
destroyed. Normally this
+        /// managed object may be created by the user and will be handled 
automatically by the GC.
+        /// </summary>
+        //gcroot<Apache::Geode::Client::IGeodeDelta^> m_managedptr;
+        //gcroot<Apache::Geode::Client::IGeodeSerializable^> 
m_managedSerializableptr;
+
+        int m_domainId;
+        UInt32 m_classId;
+        System::Byte * m_bytes;
+        System::UInt32 m_size;
+        System::UInt32 m_hashCode;
+        bool m_hasDelta;
+
+        // Disable the copy and assignment constructors
+        ManagedCacheableDeltaBytesGeneric(const 
ManagedCacheableDeltaBytesGeneric&);
+        ManagedCacheableDeltaBytesGeneric& operator = (const 
ManagedCacheableDeltaBytesGeneric&);
+      };
+
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/geode-native/blob/6cbd424f/clicache/src/impl/ManagedCacheableKey.cpp
----------------------------------------------------------------------
diff --git a/clicache/src/impl/ManagedCacheableKey.cpp 
b/clicache/src/impl/ManagedCacheableKey.cpp
new file mode 100644
index 0000000..8cefef9
--- /dev/null
+++ b/clicache/src/impl/ManagedCacheableKey.cpp
@@ -0,0 +1,230 @@
+/*
+ * 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.
+ */
+
+#include "begin_native.hpp"
+#include <GeodeTypeIdsImpl.hpp>
+#include "end_native.hpp"
+
+#include "../ICacheableKey.hpp"
+#include "ManagedCacheableKey.hpp"
+#include "../DataInput.hpp"
+#include "../DataOutput.hpp"
+#include "../CacheableString.hpp"
+#include "../ExceptionTypes.hpp"
+#include "../Log.hpp"
+
+using namespace System;
+
+namespace apache
+{
+  namespace geode
+  {
+    namespace client
+    {
+
+      void 
ManagedCacheableKeyGeneric::toData(apache::geode::client::DataOutput& output) 
const
+      {
+        try {
+          System::UInt32 pos = (int)output.getBufferLength();
+          
//Apache::Geode::Client::Log::Debug("ManagedCacheableKeyGeneric::toData");      
+          Apache::Geode::Client::DataOutput mg_output(&output, true);
+          m_managedptr->ToData(%mg_output);
+          //this will move the cursor in c++ layer
+          mg_output.WriteBytesToUMDataOutput();
+
+          ManagedCacheableKeyGeneric* tmp = 
const_cast<ManagedCacheableKeyGeneric*>(this);
+          tmp->m_objectSize = (int)(output.getBufferLength() - pos);
+        }
+        catch (Apache::Geode::Client::GeodeException^ ex) {
+          ex->ThrowNative();
+        }
+        catch (System::Exception^ ex) {
+          Apache::Geode::Client::GeodeException::ThrowNative(ex);
+        }
+      }
+
+      apache::geode::client::Serializable* 
ManagedCacheableKeyGeneric::fromData(apache::geode::client::DataInput& input)
+      {
+        try {
+          int pos = input.getBytesRead();
+          
//Apache::Geode::Client::Log::Debug("ManagedCacheableKeyGeneric::fromData");    
  
+          Apache::Geode::Client::DataInput mg_input(&input, true, 
input.getCache());
+          m_managedptr = m_managedptr->FromData(%mg_input);
+
+          //this will move the cursor in c++ layer
+          input.advanceCursor(mg_input.BytesReadInternally);
+          m_objectSize = input.getBytesRead() - pos;
+          //if(m_hashcode == 0)
+          //m_hashcode = m_managedptr->GetHashCode();
+
+
+        }
+        catch (Apache::Geode::Client::GeodeException^ ex) {
+          ex->ThrowNative();
+        }
+        catch (System::Exception^ ex) {
+          Apache::Geode::Client::GeodeException::ThrowNative(ex);
+        }
+        return this;
+      }
+
+      System::UInt32 ManagedCacheableKeyGeneric::objectSize() const
+      {
+        try {
+          int ret = m_managedptr->ObjectSize;
+          if (ret > m_objectSize)
+            return ret;
+          else
+            return m_objectSize;
+        }
+        catch (Apache::Geode::Client::GeodeException^ ex) {
+          ex->ThrowNative();
+        }
+        catch (System::Exception^ ex) {
+          Apache::Geode::Client::GeodeException::ThrowNative(ex);
+        }
+        return 0;
+      }
+
+      System::Int32 ManagedCacheableKeyGeneric::classId() const
+      {
+        return (m_classId >= 0x80000000 ? 0 : m_classId);
+      }
+
+      int8_t ManagedCacheableKeyGeneric::typeId() const
+      {
+        if (m_classId >= 0x80000000) {
+          return (int8_t)((m_classId - 0x80000000) % 0x20000000);
+        }
+        else if (m_classId <= 0x7F) {
+          return (int8_t)GeodeTypeIdsImpl::CacheableUserData;
+        }
+        else if (m_classId <= 0x7FFF) {
+          return (int8_t)GeodeTypeIdsImpl::CacheableUserData2;
+        }
+        else {
+          return (int8_t)GeodeTypeIdsImpl::CacheableUserData4;
+        }
+      }
+
+      int8_t ManagedCacheableKeyGeneric::DSFID() const
+      {
+        if (m_classId >= 0x80000000) {
+          return (int8_t)((m_classId - 0x80000000) / 0x20000000);
+        }
+        return 0;
+      }
+
+      apache::geode::client::CacheableStringPtr 
ManagedCacheableKeyGeneric::toString() const
+      {
+        try {
+          apache::geode::client::CacheableStringPtr cStr;
+          Apache::Geode::Client::CacheableString::GetCacheableString(
+            m_managedptr->ToString(), cStr);
+          return cStr;
+        }
+        catch (Apache::Geode::Client::GeodeException^ ex) {
+          ex->ThrowNative();
+        }
+        catch (System::Exception^ ex) {
+          Apache::Geode::Client::GeodeException::ThrowNative(ex);
+        }
+        return nullptr;
+      }
+
+      bool ManagedCacheableKeyGeneric::operator ==(const 
apache::geode::client::CacheableKey& other) const
+      {
+        try {
+          // now checking classId(), typeId(), DSFID() etc. will be much more
+          // expensive than just a dynamic_cast
+          const ManagedCacheableKeyGeneric* p_other =
+            dynamic_cast<const ManagedCacheableKeyGeneric*>(&other);
+          if (p_other != NULL) {
+            return static_cast<Apache::Geode::Client::ICacheableKey^>(
+              
(static_cast<Apache::Geode::Client::IGeodeSerializable^>((Apache::Geode::Client::IGeodeSerializable^)m_managedptr)))->Equals(
+              
static_cast<Apache::Geode::Client::ICacheableKey^>(p_other->ptr()));
+          }
+          return false;
+        }
+        catch (Apache::Geode::Client::GeodeException^ ex) {
+          ex->ThrowNative();
+        }
+        catch (System::Exception^ ex) {
+          Apache::Geode::Client::GeodeException::ThrowNative(ex);
+        }
+        return false;
+      }
+
+      bool ManagedCacheableKeyGeneric::operator ==(const 
ManagedCacheableKeyGeneric& other) const
+      {
+        try {
+          return static_cast<Apache::Geode::Client::ICacheableKey^>(
+            
(Apache::Geode::Client::IGeodeSerializable^)(Apache::Geode::Client::IGeodeSerializable^)m_managedptr)->Equals(
+            static_cast<Apache::Geode::Client::ICacheableKey^>(other.ptr()));
+        }
+        catch (Apache::Geode::Client::GeodeException^ ex) {
+          ex->ThrowNative();
+        }
+        catch (System::Exception^ ex) {
+          Apache::Geode::Client::GeodeException::ThrowNative(ex);
+        }
+        return false;
+      }
+
+      System::Int32 ManagedCacheableKeyGeneric::hashcode() const
+      {
+        if (m_hashcode != 0)
+          return m_hashcode;
+        try {
+
+          ManagedCacheableKeyGeneric* tmp = 
const_cast<ManagedCacheableKeyGeneric*>(this);
+          tmp->m_hashcode = ((Apache::Geode::Client::ICacheableKey^)
+                             
(Apache::Geode::Client::IGeodeSerializable^)m_managedptr)
+                             ->GetHashCode();
+          return m_hashcode;
+        }
+        catch (Apache::Geode::Client::GeodeException^ ex) {
+          ex->ThrowNative();
+        }
+        catch (System::Exception^ ex) {
+          Apache::Geode::Client::GeodeException::ThrowNative(ex);
+        }
+        return 0;
+      }
+
+      size_t ManagedCacheableKeyGeneric::logString(char* buffer, size_t 
maxLength) const
+      {
+        try {
+          if (maxLength > 0) {
+            String^ logstr = m_managedptr->GetType()->Name + '(' +
+              m_managedptr->ToString() + ')';
+            Apache::Geode::Client::ManagedString mg_str(logstr);
+            return snprintf(buffer, maxLength, "%s", mg_str.CharPtr);
+          }
+        }
+        catch (Apache::Geode::Client::GeodeException^ ex) {
+          ex->ThrowNative();
+        }
+        catch (System::Exception^ ex) {
+          Apache::Geode::Client::GeodeException::ThrowNative(ex);
+        }
+        return 0;
+      }
+
+    }  // namespace client
+  }  // namespace geode
+}  // namespace apache

http://git-wip-us.apache.org/repos/asf/geode-native/blob/6cbd424f/clicache/src/impl/ManagedCacheableKey.hpp
----------------------------------------------------------------------
diff --git a/clicache/src/impl/ManagedCacheableKey.hpp 
b/clicache/src/impl/ManagedCacheableKey.hpp
new file mode 100644
index 0000000..1f3c27f
--- /dev/null
+++ b/clicache/src/impl/ManagedCacheableKey.hpp
@@ -0,0 +1,173 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "../geode_defs.hpp"
+#include <vcclr.h>
+#include "begin_native.hpp"
+#include <geode/CacheableKey.hpp>
+#include <GeodeTypeIdsImpl.hpp>
+#include "SerializationRegistry.hpp"
+#include "end_native.hpp"
+
+#include "../IGeodeSerializable.hpp"
+
+using namespace System;
+
+namespace apache
+{
+  namespace geode
+  {
+    namespace client
+    {
+      namespace native = apache::geode::client;
+
+      /// <summary>
+      /// Wraps the managed <see cref="Apache.Geode.Client.IGeodeSerializable" 
/>
+      /// object and implements the native 
<c>apache::geode::client::CacheableKey</c> interface.
+      /// </summary>
+      class ManagedCacheableKeyGeneric
+        : public apache::geode::client::CacheableKey
+      {
+      private:
+        int m_hashcode;
+        int m_classId;
+        native::SerializationRegistry* m_serializationRegistry;
+        int m_objectSize;
+      public:
+
+        inline ManagedCacheableKeyGeneric(
+          Apache::Geode::Client::IGeodeSerializable^ managedptr, int hashcode, 
int classId, native::SerializationRegistry * serializationRegistry)
+          : m_managedptr(managedptr) {
+          m_hashcode = hashcode;
+          m_classId = classId;
+          m_serializationRegistry = serializationRegistry;
+          m_objectSize = 0;
+        }
+        /// <summary>
+        /// Constructor to initialize with the provided managed object.
+        /// </summary>
+        /// <param name="managedptr">
+        /// The managed object.
+        /// </param>
+        inline 
ManagedCacheableKeyGeneric(Apache::Geode::Client::IGeodeSerializable^ 
managedptr, native::SerializationRegistry * serializationRegistry)
+          : m_managedptr(managedptr) {
+          // m_hashcode = managedptr->GetHashCode();
+          m_hashcode = 0;
+          m_classId = managedptr->ClassId;
+          m_serializationRegistry = serializationRegistry;
+          m_objectSize = 0;
+        }
+
+        /// <summary>
+        /// serialize this object
+        /// </summary>
+        virtual void toData(apache::geode::client::DataOutput& output) const;
+
+        /// <summary>
+        /// deserialize this object, typical implementation should return
+        /// the 'this' pointer.
+        /// </summary>
+        virtual apache::geode::client::Serializable* 
fromData(apache::geode::client::DataInput& input);
+
+
+        /// <summary>
+        /// return the size of this object in bytes
+        /// </summary>
+        virtual System::UInt32 objectSize() const;
+
+        /// <summary>
+        /// return the classId of the instance being serialized.
+        /// This is used by deserialization to determine what instance
+        /// type to create and deserialize into.
+        /// </summary>
+        virtual System::Int32 classId() const;
+
+        /// <summary>
+        /// return the typeId of the instance being serialized.
+        /// This is used by deserialization to determine what instance
+        /// type to create and deserialize into.
+        /// </summary>
+        virtual int8_t typeId() const;
+
+        /// <summary>
+        /// return the Data Serialization Fixed ID type.
+        /// This is used to determine what instance type to create
+        /// and deserialize into.
+        ///
+        /// Note that this should not be overridden by custom implementations
+        /// and is reserved only for builtin types.
+        /// </summary>
+        virtual int8_t DSFID() const;
+
+        /// <summary>
+        /// Display this object as 'string', which depends on the 
implementation in
+        /// the managed class
+        /// </summary>
+        virtual apache::geode::client::CacheableStringPtr toString() const;
+
+        /// <summary>
+        /// return true if this key matches other CacheableKey
+        /// </summary>
+        virtual bool operator == (const CacheableKey& other) const;
+        /// <summary>
+        /// return true if this key matches other ManagedCacheableKey
+        /// </summary>
+        virtual bool operator == (const ManagedCacheableKeyGeneric& other) 
const;
+
+        /// <summary>
+        /// return the hashcode for this key.
+        /// </summary>
+        virtual System::Int32 hashcode() const;
+
+        /// <summary>
+        /// Copy the string form of a key into a char* buffer for logging 
purposes.
+        /// implementations should only generate a string as long as maxLength 
chars,
+        /// and return the number of chars written. buffer is expected to be 
large 
+        /// enough to hold at least maxLength chars.
+        /// The default implementation renders the classname and instance 
address.
+        /// </summary>
+        virtual size_t logString(char* buffer, size_t maxLength) const;
+
+        /// <summary>
+        /// Returns the wrapped managed object reference.
+        /// </summary>
+        inline Apache::Geode::Client::IGeodeSerializable^ ptr() const
+        {
+          return m_managedptr;
+        }
+
+
+      private:
+
+        /// <summary>
+        /// Using gcroot to hold the managed delegate pointer (since it cannot 
be stored directly).
+        /// Note: not using auto_gcroot since it will result in 'Dispose' of 
the IGeodeSerializable
+        /// to be called which is not what is desired when this object is 
destroyed. Normally this
+        /// managed object may be created by the user and will be handled 
automatically by the GC.
+        /// </summary>
+        gcroot<Apache::Geode::Client::IGeodeSerializable^> m_managedptr;
+
+        // Disable the copy and assignment constructors
+        ManagedCacheableKeyGeneric(const ManagedCacheableKeyGeneric&);
+        ManagedCacheableKeyGeneric& operator = (const 
ManagedCacheableKeyGeneric&);
+      };
+
+    }  // namespace client
+  }  // namespace geode
+}  // namespace apache

Reply via email to