internal void AddPeer(IJavaPeerable value, IntPtr handle, JniHandleOwnership transfer, out IntPtr handleField)
        {
            if (handle == IntPtr.Zero)
            {
                handleField = handle;
                return;
            }

            var transferType = transfer & (JniHandleOwnership.DoNotTransfer | JniHandleOwnership.TransferLocalRef | JniHandleOwnership.TransferGlobalRef);

            switch (transferType)
            {
            case JniHandleOwnership.DoNotTransfer:
                handleField = JNIEnv.NewGlobalRef(handle);
                break;

            case JniHandleOwnership.TransferLocalRef:
                handleField = JNIEnv.NewGlobalRef(handle);
                JNIEnv.DeleteLocalRef(handle);
                break;

            case JniHandleOwnership.TransferGlobalRef:
                handleField = handle;
                break;

            default:
                throw new ArgumentOutOfRangeException("transfer", transfer,
                                                      "Invalid `transfer` value: " + transfer + " on type " + value.GetType());
            }
            if (handleField == IntPtr.Zero)
            {
                throw new InvalidOperationException("Unable to allocate Global Reference for object '" + value.ToString() + "'!");
            }

            IntPtr hash = JNIEnv.IdentityHash !(handleField);

            value.SetJniIdentityHashCode((int)hash);
            if ((transfer & JniHandleOwnership.DoNotRegister) == 0)
            {
                AddPeer(value, new JniObjectReference(handleField, JniObjectReferenceType.Global), hash);
            }

            if (Logger.LogGlobalRef)
            {
                JNIEnv._monodroid_gref_log("handle 0x" + handleField.ToString("x") +
                                           "; key_handle 0x" + hash.ToString("x") +
                                           ": Java Type: `" + JNIEnv.GetClassNameFromInstance(handleField) + "`; " +
                                           "MCW type: `" + value.GetType().FullName + "`\n");
            }
        }