// DO NOT EDIT! This is an autogenerated file. All changes will be
// overwritten!

//	Copyright (c) 2023 Vidyo, Inc. All rights reserved.


using System;
using System.Runtime.InteropServices;
using System.Collections.Generic;

namespace VidyoClient
{
	/// <summary>
	/// 
	/// </summary>
	public class Endpoint: IDisposable {
		private bool disposed = false; 
#if __IOS__
		const string importLib = "__Internal";
#else
		const string importLib = "libVidyoClient";
#endif
		private IntPtr objPtr; // opaque VidyoEndpoint reference.
		private GCHandle objHandle; // weak VidyoEndpoint reference.
		private Dictionary<string, RemoteCamera> remoteCamerasMap = new Dictionary<string, RemoteCamera>();
		private Dictionary<string, RemoteMicrophone> remoteMicrophonesMap = new Dictionary<string, RemoteMicrophone>();
		private Dictionary<string, RemoteWindowShare> remoteWindowSharesMap = new Dictionary<string, RemoteWindowShare>();
		private Dictionary<string, IRequestVideoForRemoteCamera> onRemoteCameraFirstFrameReceivedCallbacksMap = new Dictionary<string, IRequestVideoForRemoteCamera>();
		private Dictionary<string, IRequestVideoForRemoteWindowShare> onRemoteWindowShareFirstFrameReceivedCallbacksMap = new Dictionary<string, IRequestVideoForRemoteWindowShare>();
		private List<WeakReference> objects = new List<WeakReference>();

		private void DisposeWeakReferenceObjects() {
			foreach(var item in objects) {
				if (item == null || !item.IsAlive || item.Target == null) { continue; }
				switch (item.Target.GetType().Name) {
					case "Call": ((Call)item.Target).Dispose(false); break;
					case "LocalCamera": ((LocalCamera)item.Target).Dispose(false); break;
					case "LocalMicrophone": ((LocalMicrophone)item.Target).Dispose(false); break;
					case "LocalMonitor": ((LocalMonitor)item.Target).Dispose(false); break;
					case "LocalRenderer": ((LocalRenderer)item.Target).Dispose(false); break;
					case "LocalSpeaker": ((LocalSpeaker)item.Target).Dispose(false); break;
					case "LocalWindowShare": ((LocalWindowShare)item.Target).Dispose(false); break;
					case "NetworkInterface": ((NetworkInterface)item.Target).Dispose(false); break;
					case "Participant": ((Participant)item.Target).Dispose(false); break;
					case "RemoteCamera": ((RemoteCamera)item.Target).Dispose(false); break;
					case "RemoteMicrophone": ((RemoteMicrophone)item.Target).Dispose(false); break;
					case "RemoteRenderer": ((RemoteRenderer)item.Target).Dispose(false); break;
					case "RemoteSpeaker": ((RemoteSpeaker)item.Target).Dispose(false); break;
					case "RemoteWindowShare": ((RemoteWindowShare)item.Target).Dispose(false); break;
					case "Room": ((Room)item.Target).Dispose(false); break;
					case "User": ((User)item.Target).Dispose(false); break;
					case "VirtualAudioSource": ((VirtualAudioSource)item.Target).Dispose(false); break;
					case "VirtualVideoSource": ((VirtualVideoSource)item.Target).Dispose(false); break;
				}
			}
			objects.Clear();
		}
		public IntPtr GetObjectPtr() {
			return objPtr;
		}
		public Dictionary<string, RemoteCamera> GetRemoteCamerasMap() {
			return remoteCamerasMap;
		}
		public Dictionary<string, RemoteMicrophone> GetRemoteMicrophonesMap() {
			return remoteMicrophonesMap;
		}
		public Dictionary<string, RemoteWindowShare> GetRemoteWindowSharesMap() {
			return remoteWindowSharesMap;
		}
		public Dictionary<string, IRequestVideoForRemoteCamera> GetOnRemoteCameraFirstFrameReceivedCallbacksMap() {
			return onRemoteCameraFirstFrameReceivedCallbacksMap;
		}
		public Dictionary<string, IRequestVideoForRemoteWindowShare> GetOnRemoteWindowShareFirstFrameReceivedCallbacksMap() {
			return onRemoteWindowShareFirstFrameReceivedCallbacksMap;
		}
		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointAddAudioDeviceToWhitelistNative(IntPtr e, IntPtr deviceName);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointAddMessageClassNative(IntPtr e, IntPtr messageClass);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern void VidyoEndpointAppLogNative(IntPtr e, [MarshalAs(UnmanagedType.I4)]ClientAppLogLevel logLevel, IntPtr logMsg);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointAssignViewToCompositeRendererNative(IntPtr e, ref IntPtr viewId, [MarshalAs(UnmanagedType.I4)]LocalRenderer.LocalRendererViewStyle viewStyle, uint remoteParticipants);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointAssignViewToLocalCameraNative(IntPtr e, ref IntPtr viewId, IntPtr localCamera, Boolean displayCropped, Boolean allowZoom);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointAssignViewToLocalMonitorNative(IntPtr e, ref IntPtr viewId, IntPtr localMonitor, Boolean displayCropped, Boolean allowZoom);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointAssignViewToLocalWindowShareNative(IntPtr e, ref IntPtr viewId, IntPtr localWindowShare, Boolean displayCropped, Boolean allowZoom);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointAssignViewToRemoteCameraNative(IntPtr e, ref IntPtr viewId, IntPtr remoteCamera, Boolean displayCropped, Boolean allowZoom);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointAssignViewToRemoteWindowShareNative(IntPtr e, ref IntPtr viewId, IntPtr remoteWindowShare, Boolean displayCropped, Boolean allowZoom);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointAssignViewToVirtualVideoSourceNative(IntPtr e, ref IntPtr viewId, IntPtr virtualVideoSource, Boolean displayCropped, Boolean allowZoom);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointCompressLogsNative(IntPtr e, IntPtr compressedFileName, OnLogCompressionComplete onComplete);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern IntPtr VidyoEndpointConstructNative(ref IntPtr viewId, [MarshalAs(UnmanagedType.I4)]LocalRenderer.LocalRendererViewStyle viewStyle, uint remoteParticipants, IntPtr logFileFilter);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern IntPtr VidyoEndpointConstructCopyNative(IntPtr other);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointCreateRendererNative(IntPtr e, IntPtr monitor, uint width, uint height);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointCreateRendererFromViewIdNative(IntPtr e, ref IntPtr viewId, int x, int y, uint width, uint height);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointCreateRendererMultiScreenNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointCreateVirtualAudioSourceNative(IntPtr e, IntPtr name, IntPtr id, IntPtr configuration);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointCreateVirtualVideoSourceNative(IntPtr e, [MarshalAs(UnmanagedType.I4)]VirtualVideoSourceType type, IntPtr id, IntPtr name);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointCycleCameraNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointCycleMicrophoneNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointCycleSpeakerNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointDestroyVirtualAudioSourceNative(IntPtr e, IntPtr virtualAudioSource);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointDestroyVirtualVideoSourceNative(IntPtr e, IntPtr virtualVideoSource);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern void VidyoEndpointDestructNative(IntPtr obj);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern void VidyoEndpointDisableNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern void VidyoEndpointDisableDebugNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointEnableDebugNative(IntPtr e, uint port, IntPtr logFilter);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointEnableFileLoggerNative(IntPtr e, IntPtr logFileName, IntPtr logFileFilter);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointGetActiveNetworkInterfaceNative(IntPtr e, OnGetActiveNetworkInterface onGetActiveNetworkInterfaceCallback);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern IntPtr VidyoEndpointGetApplicationTagNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern uint VidyoEndpointGetAudioBitrateMultiplierNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I4)]
		private static extern EndpointAudioMode VidyoEndpointGetAudioModeNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern uint VidyoEndpointGetAudioPacketIntervalNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern uint VidyoEndpointGetAudioPacketLossPercentageNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointGetAutoReconnectNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern uint VidyoEndpointGetAutoReconnectAttemptBackOffNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern uint VidyoEndpointGetAutoReconnectMaxAttemptsNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointGetAutoReconnectSettingNative(IntPtr e, OnGetAutoReconnectSetting onGetAutoReconnectSettingCallback);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointGetCameraBackgroundEffectNative(IntPtr e, OnGetCameraBackgroundEffectInfo onGetEffectInfo);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern IntPtr VidyoEndpointGetConferenceNumberNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I4)]
		private static extern EndpointTradeOffProfile VidyoEndpointGetCpuTradeOffProfileNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointGetDisableVideoOnLowBandwidthNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern uint VidyoEndpointGetDisableVideoOnLowBandwidthAudioStreamsNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern uint VidyoEndpointGetDisableVideoOnLowBandwidthRecoveryTimeNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern uint VidyoEndpointGetDisableVideoOnLowBandwidthResponseTimeNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern uint VidyoEndpointGetDisableVideoOnLowBandwidthSampleTimeNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern uint VidyoEndpointGetDisableVideoOnLowBandwidthThresholdNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointGetFileLoggerCategoryListNative(IntPtr e, IntPtr categories);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern IntPtr VidyoEndpointGetFileLoggerCategoryListGetcategoriesArrayNative(IntPtr obj, ref int size);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern IntPtr VidyoEndpointGetFileLoggerCategoryListFreecategoriesArrayNative(IntPtr obj, int size);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern IntPtr VidyoEndpointVectorVidyoLoggerCategoryAllocateNative();

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern void VidyoEndpointVectorVidyoLoggerCategoryDeallocateNative(IntPtr param);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointGetFileLoggerCategoryListAsyncNative(IntPtr e, OnGetLoggerCategoryListComplete onComplete);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointGetGoogleAnalyticsEventTableNative(IntPtr e, OnGetAnalyticsEventTable onGetAnalyticsEventTableCallback);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointGetGoogleAnalyticsOptionsNative(IntPtr e, OnGetGoogleAnalyticsOptions onGetGoogleAnalyticsOptions);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern IntPtr VidyoEndpointGetIdNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern IntPtr VidyoEndpointGetInsightsServiceUrlNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern uint VidyoEndpointGetMaxReceiveBitRateNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern uint VidyoEndpointGetMaxSendBitRateNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern double VidyoEndpointGetMicrophoneMaxBoostLevelNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern uint VidyoEndpointGetMinMicrophoneVolumeNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern IntPtr VidyoEndpointGetOptionsNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I4)]
		private static extern EndpointPreferredAudioCodec VidyoEndpointGetPreferredAudioCodecNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointGetProductInfoNative(IntPtr e, IntPtr productInfo, IntPtr supportedFeature);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern IntPtr VidyoEndpointGetProductInfoGetproductInfoArrayNative(IntPtr obj, ref int size);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern IntPtr VidyoEndpointGetProductInfoFreeproductInfoArrayNative(IntPtr obj, int size);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern IntPtr VidyoEndpointVectorVidyoPropertyAllocateNative();

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern void VidyoEndpointVectorVidyoPropertyDeallocateNative(IntPtr param);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern IntPtr VidyoEndpointGetProductInfoGetsupportedFeatureArrayNative(IntPtr obj, ref int size);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern IntPtr VidyoEndpointGetProductInfoFreesupportedFeatureArrayNative(IntPtr obj, int size);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointGetProductInfoAsyncNative(IntPtr e, OnGetProductInfoComplete onComplete);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern IntPtr VidyoEndpointGetRendererOptionsForViewIdNative(IntPtr e, ref IntPtr viewId);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointGetStaticShareSvcStateNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern long VidyoEndpointGetStatisticRateNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern IntPtr VidyoEndpointGetStatsNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern IntPtr VidyoEndpointGetStatsJsonNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointGetWhitelistedAudioDevicesNative(IntPtr e, OnGetWhitelistedAudioDevices onGetCallback);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointGoogleAnalyticsControlEventActionNative(IntPtr e, [MarshalAs(UnmanagedType.I4)]EndpointGoogleAnalyticsEventCategory eventCategory, [MarshalAs(UnmanagedType.I4)]EndpointGoogleAnalyticsEventAction eventAction, Boolean enable);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointHideViewNative(IntPtr e, ref IntPtr viewId);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointInsightsNotifyApplicationEventNative(IntPtr e, IntPtr eventName, IntPtr parameters);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern IntPtr VidyoEndpointInsightsNotifyApplicationEventSetparametersArrayNative(IntPtr obj, IntPtr objArray, int size);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern IntPtr VidyoEndpointVectorLmiStringAllocateNative();

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern void VidyoEndpointVectorLmiStringDeallocateNative(IntPtr param);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointIsDebugEnabledNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointIsGoogleAnalyticsServiceEnabledNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointIsInsightsServiceEnabledNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern void VidyoEndpointLocalCameraSelectAdvancedNative(IntPtr e, IntPtr localCamera);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern void VidyoEndpointLocalCameraUnselectAdvancedNative(IntPtr e, IntPtr localCamera);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern void VidyoEndpointLocalMicrophoneSelectAdvancedNative(IntPtr e, IntPtr localMicrophone, Boolean previewedPreCall);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern void VidyoEndpointLocalMicrophoneUnselectAdvancedNative(IntPtr e, IntPtr localMicrophone);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern void VidyoEndpointLocalMonitorSelectAdvancedNative(IntPtr e, IntPtr localMonitor);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern void VidyoEndpointLocalMonitorUnselectAdvancedNative(IntPtr e, IntPtr localMonitor);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern void VidyoEndpointLocalRendererSelectAdvancedNative(IntPtr e, IntPtr localRenderer);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern void VidyoEndpointLocalRendererUnselectAdvancedNative(IntPtr e, IntPtr localRenderer);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern void VidyoEndpointLocalSpeakerSelectAdvancedNative(IntPtr e, IntPtr localSpeaker);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern void VidyoEndpointLocalSpeakerUnselectAdvancedNative(IntPtr e, IntPtr localSpeaker);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern void VidyoEndpointLocalWindowShareSelectAdvancedNative(IntPtr e, IntPtr localWindowShare);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern void VidyoEndpointLocalWindowShareUnselectAdvancedNative(IntPtr e, IntPtr localWindowShare);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointRegisterCameraEffectErrorListenerNative(IntPtr e, OnCameraEffectError onError);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern void VidyoEndpointRegisterDisableVideoOnLowBwEventListenerNative(IntPtr e, OnDisableVideoOnLowBwStarted onStarted, OnDisableVideoOnLowBwEnded onEnded);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointRegisterErrorEventListenerNative(IntPtr e, OnError onErrorCallback);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointRegisterLocalCameraEventListenerNative(IntPtr e, OnLocalCameraAdded onAdded, OnLocalCameraRemoved onRemoved, OnLocalCameraSelected onSelected, OnLocalCameraStateUpdated onStateUpdated);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointRegisterLocalCameraFrameListenerNative(IntPtr e, IntPtr localCamera, OnLocalCameraFrame onFrame, uint width, uint height, ulong frameInterval);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointRegisterLocalMicrophoneEnergyListenerNative(IntPtr e, OnLocalMicrophoneEnergy onEnergy);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointRegisterLocalMicrophoneEventListenerNative(IntPtr e, OnLocalMicrophoneAdded onAdded, OnLocalMicrophoneRemoved onRemoved, OnLocalMicrophoneSelected onSelected, OnLocalMicrophoneStateUpdated onStateUpdated);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointRegisterLocalMicrophoneFrameListenerNative(IntPtr e, IntPtr localMicrophone, OnLocalMicrophoneFrame onFrame);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointRegisterLocalMonitorEventListenerNative(IntPtr e, OnLocalMonitorAdded onAdded, OnLocalMonitorRemoved onRemoved, OnLocalMonitorSelected onSelected, OnLocalMonitorStateUpdated onStateUpdated);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointRegisterLocalMonitorFrameListenerNative(IntPtr e, IntPtr localMonitor, OnLocalMonitorFrame onFrame, uint width, uint height, ulong frameInterval);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointRegisterLocalRendererEventListenerNative(IntPtr e, OnLocalRendererAdded onAdded, OnLocalRendererRemoved onRemoved, OnLocalRendererSelected onSelected, OnLocalRendererStateUpdated onStateUpdated);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointRegisterLocalSpeakerEventListenerNative(IntPtr e, OnLocalSpeakerAdded onAdded, OnLocalSpeakerRemoved onRemoved, OnLocalSpeakerSelected onSelected, OnLocalSpeakerStateUpdated onStateUpdated);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointRegisterLocalWindowShareEventListenerNative(IntPtr e, OnLocalWindowShareAdded onAdded, OnLocalWindowShareRemoved onRemoved, OnLocalWindowShareSelected onSelected, OnLocalWindowShareStateUpdated onStateUpdated);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointRegisterLocalWindowShareFrameListenerNative(IntPtr e, IntPtr localWindowShare, OnLocalWindowShareFrame onFrame, uint width, uint height, ulong frameInterval);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointRegisterLogEventListenerNative(IntPtr e, OnLog onLog, IntPtr filter);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointRegisterNGRResultEventListenerNative(IntPtr e, OnNGRResult onNGRResult);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointRegisterNetworkInterfaceEventListenerNative(IntPtr e, OnNetworkInterfaceAdded onAdded, OnNetworkInterfaceRemoved onRemoved, OnNetworkInterfaceSelected onSelected, OnNetworkInterfaceStateUpdated onStateUpdated);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern ulong VidyoEndpointRegisterPluginNative(IntPtr e, ulong plugin);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointRegisterReconnectEventListenerNative(IntPtr e, OnReconnecting onReconnecting, OnReconnected onReconnected, OnConferenceLost onConferenceLost);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointRegisterRemoteCameraEventListenerNative(IntPtr e, OnRemoteCameraAdded onAdded, OnRemoteCameraRemoved onRemoved, OnRemoteCameraStateUpdated onStateUpdated);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointRegisterRemoteCameraFrameListenerNative(IntPtr e, IntPtr remoteCamera, OnRemoteCameraFrame onFrame, uint width, uint height, ulong frameInterval);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointRegisterRemoteMicrophoneEnergyListenerNative(IntPtr e, OnRemoteMicrophoneEnergy onEnergy);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointRegisterRemoteMicrophoneEventListenerNative(IntPtr e, OnRemoteMicrophoneAdded onAdded, OnRemoteMicrophoneRemoved onRemoved, OnRemoteMicrophoneStateUpdated onStateUpdated);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointRegisterRemoteMicrophoneFrameListenerNative(IntPtr e, IntPtr remoteMicrophone, OnRemoteMicrophoneFrame onFrame);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointRegisterRemoteRendererEventListenerNative(IntPtr e, OnRemoteRendererAdded onAdded, OnRemoteRendererRemoved onRemoved, OnRemoteRendererStateUpdated onStateUpdated);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointRegisterRemoteSpeakerEventListenerNative(IntPtr e, OnRemoteSpeakerAdded onAdded, OnRemoteSpeakerRemoved onRemoved, OnRemoteSpeakerStateUpdated onStateUpdated);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointRegisterRemoteWindowShareEventListenerNative(IntPtr e, OnRemoteWindowShareAdded onAdded, OnRemoteWindowShareRemoved onRemoved, OnRemoteWindowShareStateUpdated onStateUpdated);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointRegisterRemoteWindowShareFrameListenerNative(IntPtr e, IntPtr remoteWindowShare, OnRemoteWindowShareFrame onFrame, uint width, uint height, ulong frameInterval);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointRegisterVirtualAudioSourceEventListenerNative(IntPtr e, OnVirtualAudioSourceAdded onAdded, OnVirtualAudioSourceRemoved onRemoved, OnVirtualAudioSourceStateUpdated onStateUpdated, OnVirtualAudioSourceSelected onSelected, OnVirtualAudioSourceExternalMediaBufferReleased onExternalMediaBufferReleased);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointRegisterVirtualVideoSourceEventListenerNative(IntPtr e, OnVirtualVideoSourceAdded onAdded, OnVirtualVideoSourceRemoved onRemoved, OnVirtualVideoSourceStateUpdated onStateUpdated, OnVirtualVideoSourceExternalMediaBufferReleased onExternalMediaBufferReleased);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointRemoveAudioDeviceFromWhitelistNative(IntPtr e, IntPtr deviceName);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern void VidyoEndpointRemoveRendererNative(IntPtr e, IntPtr localRenderer);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointRequestToResumeVideoNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointRequestToSpeakNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointRequestVideoForRemoteCameraNative(IntPtr e, IntPtr remoteCamera, uint width, uint height, ulong frameInterval, OnRemoteCameraFirstFrameReceived onFirstFrameReceived);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointRequestVideoForRemoteWindowShareNative(IntPtr e, IntPtr remoteWindowShare, uint width, uint height, ulong frameInterval, OnRemoteWindowShareFirstFrameReceived onFirstFrameReceived);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointSelectAudioContentShareNative(IntPtr e, IntPtr localMicrophone);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointSelectDefaultCameraNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointSelectDefaultMicrophoneNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointSelectDefaultNetworkInterfaceForMediaNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointSelectDefaultNetworkInterfaceForSignalingNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointSelectDefaultSpeakerNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointSelectLocalCameraNative(IntPtr e, IntPtr localCamera);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointSelectLocalMicrophoneNative(IntPtr e, IntPtr localMicrophone);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointSelectLocalMonitorNative(IntPtr e, IntPtr localMonitor);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointSelectLocalMonitorAdvancedNative(IntPtr e, IntPtr localMonitor, IntPtr options);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointSelectLocalSpeakerNative(IntPtr e, IntPtr localSpeaker);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointSelectLocalWindowShareNative(IntPtr e, IntPtr localWindowShare);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointSelectLocalWindowShareAdvancedNative(IntPtr e, IntPtr localWindowShare, IntPtr options);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointSelectNetworkInterfaceForMediaNative(IntPtr e, IntPtr networkInterface);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointSelectNetworkInterfaceForSignalingNative(IntPtr e, IntPtr networkInterface);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointSelectVideoContentShareNative(IntPtr e, IntPtr localCamera);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointSelectVirtualAudioContentShareNative(IntPtr e, IntPtr virtualAudioSource);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointSelectVirtualCameraNative(IntPtr e, IntPtr virtualCamera);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointSelectVirtualMicrophoneNative(IntPtr e, IntPtr virtualAudioSource);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointSelectVirtualRendererNative(IntPtr e, IntPtr renderer);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointSelectVirtualSourceWindowShareNative(IntPtr e, IntPtr virtualWindowShare);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointSendVirtualAudioSourceFrameNative(IntPtr e, IntPtr virtualAudioSource, IntPtr audioFrame);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointSendVirtualAudioSourceFrameWithExternalDataNative(IntPtr e, IntPtr virtualAudioSource, IntPtr buffer, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(SizeTMarshaler))]SizeT nbSamples, ulong elapsedTime);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointSetAdvancedOptionsNative(IntPtr e, IntPtr options);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointSetApplicationTagNative(IntPtr e, IntPtr applicationTag);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointSetAudioBitrateMultiplierNative(IntPtr e, uint bitrateMultiplier);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointSetAudioModeNative(IntPtr e, [MarshalAs(UnmanagedType.I4)]EndpointAudioMode audioMode);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointSetAudioPacketIntervalNative(IntPtr e, uint packetInterval);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointSetAudioPacketLossPercentageNative(IntPtr e, uint lossPercentage);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointSetAutoReconnectNative(IntPtr e, Boolean enable);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointSetAutoReconnectAttemptBackOffNative(IntPtr e, uint backOff);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointSetAutoReconnectMaxAttemptsNative(IntPtr e, uint maxAttempts);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointSetBlurIntensityNative(IntPtr e, uint intensity);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointSetCameraBackgroundEffectNative(IntPtr e, IntPtr effectInfo);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointSetCameraNudgeConfigurationNative(IntPtr e, IntPtr cameraNudgeConfig);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointSetCameraPrivacyNative(IntPtr e, Boolean privacy);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern void VidyoEndpointSetConferenceNumberNative(IntPtr e, IntPtr conferenceNumber);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointSetConsoleLoggerFilterNative(IntPtr e, IntPtr consoleLogFilter);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointSetConsoleLoggerLevelAndCategoryNative(IntPtr e, IntPtr levelName, IntPtr categoryName, Boolean on);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointSetConsoleLoggerUTCNative(IntPtr e, Boolean utc);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointSetCpuTradeOffProfileNative(IntPtr e, [MarshalAs(UnmanagedType.I4)]EndpointTradeOffProfile profile);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointSetDebugFilterNative(IntPtr e, IntPtr debugLogFilter);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointSetDisableVideoOnLowBandwidthNative(IntPtr e, Boolean enable);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointSetDisableVideoOnLowBandwidthAudioStreamsNative(IntPtr e, uint audioStreams);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointSetDisableVideoOnLowBandwidthRecoveryTimeNative(IntPtr e, uint recoveryTime);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointSetDisableVideoOnLowBandwidthResponseTimeNative(IntPtr e, uint responseTime);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointSetDisableVideoOnLowBandwidthSampleTimeNative(IntPtr e, uint sampleTime);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointSetDisableVideoOnLowBandwidthThresholdNative(IntPtr e, uint kbps);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointSetFileLoggerFilterNative(IntPtr e, IntPtr logFileFilter);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointSetFileLoggerLevelAndCategoryNative(IntPtr e, IntPtr levelName, IntPtr categoryName, Boolean on);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointSetFileLoggerRotationParametersNative(IntPtr e, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(SizeTMarshaler))]SizeT maxSize, ulong wrapPeriod, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(SizeTMarshaler))]SizeT wrapCount);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointSetFileLoggerUTCNative(IntPtr e, Boolean utc);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointSetFontFileNameNative(IntPtr e, IntPtr fontFileName);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointSetLicenseKeyNative(IntPtr e, IntPtr licenseKey);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointSetLocationNative(IntPtr e, double latitude, double longitude);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointSetLogFilePathNative(IntPtr e, IntPtr filename);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern void VidyoEndpointSetMaxReceiveBitRateNative(IntPtr e, uint bitRate);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern void VidyoEndpointSetMaxSendBitRateNative(IntPtr e, uint bitRate);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern void VidyoEndpointSetMicrophoneMaxBoostLevelNative(IntPtr e, double boostLevel);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointSetMicrophonePrivacyNative(IntPtr e, Boolean privacy);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern void VidyoEndpointSetMinMicrophoneVolumeNative(IntPtr e, uint volumePercent);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointSetModeNative(IntPtr e, [MarshalAs(UnmanagedType.I4)]EndpointMode mode);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointSetOptionsNative(IntPtr e, IntPtr options);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointSetPoolNative(IntPtr e, IntPtr name);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointSetProductInfoNative(IntPtr e, IntPtr productInfo, IntPtr supportedFeature);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern IntPtr VidyoEndpointSetProductInfoSetproductInfoArrayNative(IntPtr obj, IntPtr objArray, int size);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern IntPtr VidyoEndpointSetProductInfoSetsupportedFeatureArrayNative(IntPtr obj, IntPtr objArray, int size);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointSetReceiveRawMessageNative(IntPtr e, Boolean receiveRawMessage);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointSetRendererOptionsForViewIdNative(IntPtr e, ref IntPtr viewId, IntPtr options);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointSetSpeakerPrivacyNative(IntPtr e, Boolean privacy);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointSetStaticShareSvcStateNative(IntPtr e, Boolean enable);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointSetStatisticRateNative(IntPtr e, long statRate);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointSetTURNAddressCredentialsNative(IntPtr e, IntPtr turnAddress, uint port, IntPtr username, IntPtr password, [MarshalAs(UnmanagedType.I4)]EndpointBaseTransportType baseTransport);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointSetTURNServerCertificateRequiredNative(IntPtr e, Boolean required);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointSetViewAnimationSpeedNative(IntPtr e, ref IntPtr viewId, uint speedPercentage);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointSetViewBackgroundColorNative(IntPtr e, ref IntPtr viewId, byte red, byte green, byte blue);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointSetVirtualBackgroundPictureNative(IntPtr e, IntPtr pathToPicture);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointShowAudioMetersNative(IntPtr e, ref IntPtr viewId, Boolean showMeters);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointShowPreviewNative(IntPtr e, Boolean preview);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointShowViewAtNative(IntPtr e, ref IntPtr viewId, int x, int y, uint width, uint height);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointShowViewAtPointsNative(IntPtr e, ref IntPtr viewId, int x, int y, uint width, uint height);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointShowViewLabelNative(IntPtr e, ref IntPtr viewId, Boolean showLabel);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointShowWindowSharePreviewNative(IntPtr e, Boolean preview);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointStartGoogleAnalyticsServiceNative(IntPtr e, IntPtr options);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointStartInsightsServiceNative(IntPtr e, IntPtr serverUrl);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointStartLocalCameraDetectionNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointStartLocalMicrophoneDetectionNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointStartLocalMonitorDetectionNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointStartLocalSpeakerDetectionNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointStartLocalWindowShareDetectionNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointStartLocationDetectionNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointStartNextLogFileNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointStopGoogleAnalyticsServiceNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointStopInsightsServiceNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern void VidyoEndpointStopLocalCameraDetectionNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern void VidyoEndpointStopLocalMicrophoneDetectionNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern void VidyoEndpointStopLocalMonitorDetectionNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern void VidyoEndpointStopLocalSpeakerDetectionNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern void VidyoEndpointStopLocalWindowShareDetectionNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern void VidyoEndpointStopLocationDetectionNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointSwapStreamsBetweenViewsNative(IntPtr e, ref IntPtr firstView, ref IntPtr secondView);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointUnregisterCameraEffectErrorListenerNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern void VidyoEndpointUnregisterDisableVideoOnLowBwEventListenerNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointUnregisterErrorEventListenerNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointUnregisterLocalCameraEventListenerNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointUnregisterLocalCameraFrameListenerNative(IntPtr e, IntPtr localCamera);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointUnregisterLocalMicrophoneEnergyListenerNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointUnregisterLocalMicrophoneEventListenerNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointUnregisterLocalMicrophoneFrameListenerNative(IntPtr e, IntPtr localMicrophone);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointUnregisterLocalMonitorEventListenerNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointUnregisterLocalMonitorFrameListenerNative(IntPtr e, IntPtr localMonitor);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointUnregisterLocalRendererEventListenerNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointUnregisterLocalSpeakerEventListenerNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointUnregisterLocalWindowShareEventListenerNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointUnregisterLocalWindowShareFrameListenerNative(IntPtr e, IntPtr localWindowShare);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointUnregisterLogEventListenerNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointUnregisterNGRResultEventListenerNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointUnregisterNetworkInterfaceEventListenerNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointUnregisterPluginNative(IntPtr e, ulong plugin);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointUnregisterReconnectEventListenerNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointUnregisterRemoteCameraEventListenerNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointUnregisterRemoteCameraFrameListenerNative(IntPtr e, IntPtr remoteCamera);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointUnregisterRemoteMicrophoneEnergyListenerNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointUnregisterRemoteMicrophoneEventListenerNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointUnregisterRemoteMicrophoneFrameListenerNative(IntPtr e, IntPtr remoteMicrophone);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointUnregisterRemoteRendererEventListenerNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointUnregisterRemoteSpeakerEventListenerNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointUnregisterRemoteWindowShareEventListenerNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointUnregisterRemoteWindowShareFrameListenerNative(IntPtr e, IntPtr remoteWindowShare);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointUnregisterVirtualAudioSourceEventListenerNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointUnregisterVirtualVideoSourceEventListenerNative(IntPtr e);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		[return: MarshalAs(UnmanagedType.I1)]
		private static extern Boolean VidyoEndpointValidateLicenseKeyNative(IntPtr e, IntPtr licenseKey, IntPtr userName);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern void VidyoEndpointVirtualCameraSelectAdvancedNative(IntPtr e, IntPtr virtualCamera);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern void VidyoEndpointVirtualSourceWindowShareSelectAdvancedNative(IntPtr e, IntPtr virtualWindowShare);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern void VidyoEndpointVirtualVideoSourceUnselectAdvancedNative(IntPtr e, IntPtr virtualVideoSource);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		public static extern IntPtr VidyoEndpointGetUserDataNative(IntPtr obj);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		public static extern void VidyoEndpointSetUserDataNative(IntPtr obj, IntPtr userData);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnCameraEffectError(IntPtr e, EndpointCameraEffectError error);
		private OnCameraEffectError _mOnCameraEffectError = OnCameraEffectErrorDelegate;
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnConferenceLost(IntPtr e, EndpointReconnectFailReason reason);
		private OnConferenceLost _mOnConferenceLost = OnConferenceLostDelegate;
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnDisableVideoOnLowBwEnded(IntPtr e);
		private OnDisableVideoOnLowBwEnded _mOnDisableVideoOnLowBwEnded = OnDisableVideoOnLowBwEndedDelegate;
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnDisableVideoOnLowBwStarted(IntPtr e);
		private OnDisableVideoOnLowBwStarted _mOnDisableVideoOnLowBwStarted = OnDisableVideoOnLowBwStartedDelegate;
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnError(IntPtr e, EndpointErrorCode error, IntPtr apiName);
		private OnError _mOnError = OnErrorDelegate;
		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern IntPtr VidyoEndpointOnErrorGetapiNameCStr(IntPtr apiName);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnGetActiveNetworkInterface(IntPtr e, IntPtr signalingInterface, IntPtr mediaInterface);
		private OnGetActiveNetworkInterface _mOnGetActiveNetworkInterface = OnGetActiveNetworkInterfaceDelegate;
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnGetAnalyticsEventTable(IntPtr e, IntPtr eventTables);
		private OnGetAnalyticsEventTable _mOnGetAnalyticsEventTable = OnGetAnalyticsEventTableDelegate;
		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern IntPtr VidyoEndpointOnGetAnalyticsEventTableGeteventTablesArrayNative(IntPtr obj, ref int size);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern IntPtr VidyoEndpointOnGetAnalyticsEventTableFreeeventTablesArrayNative(IntPtr obj, int size);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnGetAutoReconnectSetting(IntPtr e, Boolean enableAutoReconnect, uint reconnectBackoff, uint maxReconnectAttempts);
		private OnGetAutoReconnectSetting _mOnGetAutoReconnectSetting = OnGetAutoReconnectSettingDelegate;
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnGetCameraBackgroundEffectInfo(IntPtr e, IntPtr effectInfo);
		private OnGetCameraBackgroundEffectInfo _mOnGetCameraBackgroundEffectInfo = OnGetCameraBackgroundEffectInfoDelegate;
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnGetGoogleAnalyticsOptions(IntPtr e, IntPtr options);
		private OnGetGoogleAnalyticsOptions _mOnGetGoogleAnalyticsOptions = OnGetGoogleAnalyticsOptionsDelegate;
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnGetLoggerCategoryListComplete(IntPtr e, EndpointLoggerType loggerType, IntPtr categories, EndpointGetLoggerCategoryListResult result);
		private OnGetLoggerCategoryListComplete _mOnGetLoggerCategoryListComplete = OnGetLoggerCategoryListCompleteDelegate;
		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern IntPtr VidyoEndpointOnGetLoggerCategoryListCompleteGetcategoriesArrayNative(IntPtr obj, ref int size);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern IntPtr VidyoEndpointOnGetLoggerCategoryListCompleteFreecategoriesArrayNative(IntPtr obj, int size);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnGetProductInfoComplete(IntPtr e, IntPtr productInfo, IntPtr supportedFeature);
		private OnGetProductInfoComplete _mOnGetProductInfoComplete = OnGetProductInfoCompleteDelegate;
		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern IntPtr VidyoEndpointOnGetProductInfoCompleteGetproductInfoArrayNative(IntPtr obj, ref int size);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern IntPtr VidyoEndpointOnGetProductInfoCompleteFreeproductInfoArrayNative(IntPtr obj, int size);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern IntPtr VidyoEndpointOnGetProductInfoCompleteGetsupportedFeatureArrayNative(IntPtr obj, ref int size);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern IntPtr VidyoEndpointOnGetProductInfoCompleteFreesupportedFeatureArrayNative(IntPtr obj, int size);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnGetWhitelistedAudioDevices(IntPtr e, IntPtr audioDevices);
		private OnGetWhitelistedAudioDevices _mOnGetWhitelistedAudioDevices = OnGetWhitelistedAudioDevicesDelegate;
		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern IntPtr VidyoEndpointOnGetWhitelistedAudioDevicesGetaudioDevicesArrayNative(IntPtr obj, ref int size);

		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern IntPtr VidyoEndpointOnGetWhitelistedAudioDevicesFreeaudioDevicesArrayNative(IntPtr obj, int size);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnLocalCameraAdded(IntPtr e, IntPtr localCamera);
		private OnLocalCameraAdded _mOnLocalCameraAdded = OnLocalCameraAddedDelegate;
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnLocalCameraFrame(IntPtr e, IntPtr localCamera, IntPtr videoFrame);
		private OnLocalCameraFrame _mOnLocalCameraFrame = OnLocalCameraFrameDelegate;
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnLocalCameraRemoved(IntPtr e, IntPtr localCamera);
		private OnLocalCameraRemoved _mOnLocalCameraRemoved = OnLocalCameraRemovedDelegate;
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnLocalCameraSelected(IntPtr e, IntPtr localCamera);
		private OnLocalCameraSelected _mOnLocalCameraSelected = OnLocalCameraSelectedDelegate;
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnLocalCameraStateUpdated(IntPtr e, IntPtr localCamera, Device.DeviceState state);
		private OnLocalCameraStateUpdated _mOnLocalCameraStateUpdated = OnLocalCameraStateUpdatedDelegate;
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnLocalMicrophoneAdded(IntPtr e, IntPtr localMicrophone);
		private OnLocalMicrophoneAdded _mOnLocalMicrophoneAdded = OnLocalMicrophoneAddedDelegate;
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnLocalMicrophoneEnergy(IntPtr e, IntPtr localMicrophone, int audioEnergy);
		private OnLocalMicrophoneEnergy _mOnLocalMicrophoneEnergy = OnLocalMicrophoneEnergyDelegate;
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnLocalMicrophoneFrame(IntPtr e, IntPtr localMicrophone, IntPtr audioFrame);
		private OnLocalMicrophoneFrame _mOnLocalMicrophoneFrame = OnLocalMicrophoneFrameDelegate;
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnLocalMicrophoneRemoved(IntPtr e, IntPtr localMicrophone);
		private OnLocalMicrophoneRemoved _mOnLocalMicrophoneRemoved = OnLocalMicrophoneRemovedDelegate;
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnLocalMicrophoneSelected(IntPtr e, IntPtr localMicrophone);
		private OnLocalMicrophoneSelected _mOnLocalMicrophoneSelected = OnLocalMicrophoneSelectedDelegate;
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnLocalMicrophoneStateUpdated(IntPtr e, IntPtr localMicrophone, Device.DeviceState state);
		private OnLocalMicrophoneStateUpdated _mOnLocalMicrophoneStateUpdated = OnLocalMicrophoneStateUpdatedDelegate;
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnLocalMonitorAdded(IntPtr e, IntPtr localMonitor);
		private OnLocalMonitorAdded _mOnLocalMonitorAdded = OnLocalMonitorAddedDelegate;
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnLocalMonitorFrame(IntPtr e, IntPtr localMonitor, IntPtr videoFrame);
		private OnLocalMonitorFrame _mOnLocalMonitorFrame = OnLocalMonitorFrameDelegate;
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnLocalMonitorRemoved(IntPtr e, IntPtr localMonitor);
		private OnLocalMonitorRemoved _mOnLocalMonitorRemoved = OnLocalMonitorRemovedDelegate;
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnLocalMonitorSelected(IntPtr e, IntPtr localMonitor);
		private OnLocalMonitorSelected _mOnLocalMonitorSelected = OnLocalMonitorSelectedDelegate;
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnLocalMonitorStateUpdated(IntPtr e, IntPtr localMonitor, Device.DeviceState state);
		private OnLocalMonitorStateUpdated _mOnLocalMonitorStateUpdated = OnLocalMonitorStateUpdatedDelegate;
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnLocalRendererAdded(IntPtr e, IntPtr localRenderer);
		private OnLocalRendererAdded _mOnLocalRendererAdded = OnLocalRendererAddedDelegate;
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnLocalRendererRemoved(IntPtr e, IntPtr localRenderer);
		private OnLocalRendererRemoved _mOnLocalRendererRemoved = OnLocalRendererRemovedDelegate;
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnLocalRendererSelected(IntPtr e, IntPtr localRenderer);
		private OnLocalRendererSelected _mOnLocalRendererSelected = OnLocalRendererSelectedDelegate;
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnLocalRendererStateUpdated(IntPtr e, IntPtr localRenderer, Device.DeviceState state);
		private OnLocalRendererStateUpdated _mOnLocalRendererStateUpdated = OnLocalRendererStateUpdatedDelegate;
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnLocalSpeakerAdded(IntPtr e, IntPtr localSpeaker);
		private OnLocalSpeakerAdded _mOnLocalSpeakerAdded = OnLocalSpeakerAddedDelegate;
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnLocalSpeakerRemoved(IntPtr e, IntPtr localSpeaker);
		private OnLocalSpeakerRemoved _mOnLocalSpeakerRemoved = OnLocalSpeakerRemovedDelegate;
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnLocalSpeakerSelected(IntPtr e, IntPtr localSpeaker);
		private OnLocalSpeakerSelected _mOnLocalSpeakerSelected = OnLocalSpeakerSelectedDelegate;
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnLocalSpeakerStateUpdated(IntPtr e, IntPtr localSpeaker, Device.DeviceState state);
		private OnLocalSpeakerStateUpdated _mOnLocalSpeakerStateUpdated = OnLocalSpeakerStateUpdatedDelegate;
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnLocalWindowShareAdded(IntPtr e, IntPtr localWindowShare);
		private OnLocalWindowShareAdded _mOnLocalWindowShareAdded = OnLocalWindowShareAddedDelegate;
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnLocalWindowShareFrame(IntPtr e, IntPtr localWindowShare, IntPtr videoFrame);
		private OnLocalWindowShareFrame _mOnLocalWindowShareFrame = OnLocalWindowShareFrameDelegate;
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnLocalWindowShareRemoved(IntPtr e, IntPtr localWindowShare);
		private OnLocalWindowShareRemoved _mOnLocalWindowShareRemoved = OnLocalWindowShareRemovedDelegate;
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnLocalWindowShareSelected(IntPtr e, IntPtr localWindowShare);
		private OnLocalWindowShareSelected _mOnLocalWindowShareSelected = OnLocalWindowShareSelectedDelegate;
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnLocalWindowShareStateUpdated(IntPtr e, IntPtr localWindowShare, Device.DeviceState state);
		private OnLocalWindowShareStateUpdated _mOnLocalWindowShareStateUpdated = OnLocalWindowShareStateUpdatedDelegate;
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnLog(IntPtr e, IntPtr logRecord);
		private OnLog _mOnLog = OnLogDelegate;
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnLogCompressionComplete(IntPtr e, IntPtr compressedFileName, EndpointLogCompressionResult result);
		private OnLogCompressionComplete _mOnLogCompressionComplete = OnLogCompressionCompleteDelegate;
		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern IntPtr VidyoEndpointOnLogCompressionCompleteGetcompressedFileNameCStr(IntPtr compressedFileName);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnNGRResult(IntPtr e, EndpointNGRActionType type, Boolean success, IntPtr error);
		private OnNGRResult _mOnNGRResult = OnNGRResultDelegate;
		[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
		private static extern IntPtr VidyoEndpointOnNGRResultGeterrorCStr(IntPtr error);

		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnNetworkInterfaceAdded(IntPtr e, IntPtr networkInterface);
		private OnNetworkInterfaceAdded _mOnNetworkInterfaceAdded = OnNetworkInterfaceAddedDelegate;
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnNetworkInterfaceRemoved(IntPtr e, IntPtr networkInterface);
		private OnNetworkInterfaceRemoved _mOnNetworkInterfaceRemoved = OnNetworkInterfaceRemovedDelegate;
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnNetworkInterfaceSelected(IntPtr e, IntPtr networkInterface, NetworkInterface.NetworkInterfaceTransportType transportType);
		private OnNetworkInterfaceSelected _mOnNetworkInterfaceSelected = OnNetworkInterfaceSelectedDelegate;
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnNetworkInterfaceStateUpdated(IntPtr e, IntPtr networkInterface, NetworkInterface.NetworkInterfaceState state);
		private OnNetworkInterfaceStateUpdated _mOnNetworkInterfaceStateUpdated = OnNetworkInterfaceStateUpdatedDelegate;
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnReconnected(IntPtr e);
		private OnReconnected _mOnReconnected = OnReconnectedDelegate;
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnReconnecting(IntPtr e, uint attempt, uint attemptTimeout, EndpointReconnectFailReason reason);
		private OnReconnecting _mOnReconnecting = OnReconnectingDelegate;
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnRemoteCameraAdded(IntPtr e, IntPtr remoteCamera, IntPtr user, IntPtr call, IntPtr room, IntPtr participant);
		private OnRemoteCameraAdded _mOnRemoteCameraAdded = OnRemoteCameraAddedDelegate;
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnRemoteCameraFirstFrameReceived(IntPtr e, IntPtr remoteCamera);
		private OnRemoteCameraFirstFrameReceived _mOnRemoteCameraFirstFrameReceived = OnRemoteCameraFirstFrameReceivedDelegate;
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnRemoteCameraFrame(IntPtr e, IntPtr remoteCamera, IntPtr participant, IntPtr videoFrame);
		private OnRemoteCameraFrame _mOnRemoteCameraFrame = OnRemoteCameraFrameDelegate;
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnRemoteCameraRemoved(IntPtr e, IntPtr remoteCamera, IntPtr user, IntPtr call, IntPtr room, IntPtr participant);
		private OnRemoteCameraRemoved _mOnRemoteCameraRemoved = OnRemoteCameraRemovedDelegate;
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnRemoteCameraStateUpdated(IntPtr e, IntPtr remoteCamera, IntPtr user, IntPtr call, IntPtr room, IntPtr participant, Device.DeviceState state);
		private OnRemoteCameraStateUpdated _mOnRemoteCameraStateUpdated = OnRemoteCameraStateUpdatedDelegate;
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnRemoteMicrophoneAdded(IntPtr e, IntPtr remoteMicrophone, IntPtr user, IntPtr call, IntPtr room, IntPtr participant);
		private OnRemoteMicrophoneAdded _mOnRemoteMicrophoneAdded = OnRemoteMicrophoneAddedDelegate;
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnRemoteMicrophoneEnergy(IntPtr e, IntPtr remoteMicrophone, IntPtr participant, int audioEnergy);
		private OnRemoteMicrophoneEnergy _mOnRemoteMicrophoneEnergy = OnRemoteMicrophoneEnergyDelegate;
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnRemoteMicrophoneFrame(IntPtr e, IntPtr remoteMicrophone, IntPtr participant, IntPtr audioFrame);
		private OnRemoteMicrophoneFrame _mOnRemoteMicrophoneFrame = OnRemoteMicrophoneFrameDelegate;
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnRemoteMicrophoneRemoved(IntPtr e, IntPtr remoteMicrophone, IntPtr user, IntPtr call, IntPtr room, IntPtr participant);
		private OnRemoteMicrophoneRemoved _mOnRemoteMicrophoneRemoved = OnRemoteMicrophoneRemovedDelegate;
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnRemoteMicrophoneStateUpdated(IntPtr e, IntPtr remoteMicrophone, IntPtr user, IntPtr call, IntPtr room, IntPtr participant, Device.DeviceState state);
		private OnRemoteMicrophoneStateUpdated _mOnRemoteMicrophoneStateUpdated = OnRemoteMicrophoneStateUpdatedDelegate;
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnRemoteRendererAdded(IntPtr e, IntPtr remoteRenderer, IntPtr user, IntPtr call, IntPtr room);
		private OnRemoteRendererAdded _mOnRemoteRendererAdded = OnRemoteRendererAddedDelegate;
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnRemoteRendererRemoved(IntPtr e, IntPtr remoteRenderer, IntPtr user, IntPtr call, IntPtr room);
		private OnRemoteRendererRemoved _mOnRemoteRendererRemoved = OnRemoteRendererRemovedDelegate;
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnRemoteRendererStateUpdated(IntPtr e, IntPtr remoteRenderer, IntPtr user, IntPtr call, IntPtr room, Device.DeviceState state);
		private OnRemoteRendererStateUpdated _mOnRemoteRendererStateUpdated = OnRemoteRendererStateUpdatedDelegate;
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnRemoteSpeakerAdded(IntPtr e, IntPtr remoteSpeaker, IntPtr user, IntPtr call, IntPtr room);
		private OnRemoteSpeakerAdded _mOnRemoteSpeakerAdded = OnRemoteSpeakerAddedDelegate;
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnRemoteSpeakerRemoved(IntPtr e, IntPtr remoteSpeaker, IntPtr user, IntPtr call, IntPtr room);
		private OnRemoteSpeakerRemoved _mOnRemoteSpeakerRemoved = OnRemoteSpeakerRemovedDelegate;
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnRemoteSpeakerStateUpdated(IntPtr e, IntPtr remoteSpeaker, IntPtr user, IntPtr call, IntPtr room, Device.DeviceState state);
		private OnRemoteSpeakerStateUpdated _mOnRemoteSpeakerStateUpdated = OnRemoteSpeakerStateUpdatedDelegate;
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnRemoteWindowShareAdded(IntPtr e, IntPtr remoteWindowShare, IntPtr user, IntPtr call, IntPtr room, IntPtr participant);
		private OnRemoteWindowShareAdded _mOnRemoteWindowShareAdded = OnRemoteWindowShareAddedDelegate;
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnRemoteWindowShareFirstFrameReceived(IntPtr e, IntPtr remoteWindowShare);
		private OnRemoteWindowShareFirstFrameReceived _mOnRemoteWindowShareFirstFrameReceived = OnRemoteWindowShareFirstFrameReceivedDelegate;
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnRemoteWindowShareFrame(IntPtr e, IntPtr remoteWindowShare, IntPtr participant, IntPtr videoFrame);
		private OnRemoteWindowShareFrame _mOnRemoteWindowShareFrame = OnRemoteWindowShareFrameDelegate;
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnRemoteWindowShareRemoved(IntPtr e, IntPtr remoteWindowShare, IntPtr user, IntPtr call, IntPtr room, IntPtr participant);
		private OnRemoteWindowShareRemoved _mOnRemoteWindowShareRemoved = OnRemoteWindowShareRemovedDelegate;
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnRemoteWindowShareStateUpdated(IntPtr e, IntPtr remoteWindowShare, IntPtr user, IntPtr call, IntPtr room, IntPtr participant, Device.DeviceState state);
		private OnRemoteWindowShareStateUpdated _mOnRemoteWindowShareStateUpdated = OnRemoteWindowShareStateUpdatedDelegate;
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnVirtualAudioSourceAdded(IntPtr e, IntPtr virtualAudioSource);
		private OnVirtualAudioSourceAdded _mOnVirtualAudioSourceAdded = OnVirtualAudioSourceAddedDelegate;
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnVirtualAudioSourceExternalMediaBufferReleased(IntPtr e, IntPtr virtualAudioSource, IntPtr buffer, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(SizeTMarshaler))]SizeT size);
		private OnVirtualAudioSourceExternalMediaBufferReleased _mOnVirtualAudioSourceExternalMediaBufferReleased = OnVirtualAudioSourceExternalMediaBufferReleasedDelegate;
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnVirtualAudioSourceRemoved(IntPtr e, IntPtr virtualAudioSource);
		private OnVirtualAudioSourceRemoved _mOnVirtualAudioSourceRemoved = OnVirtualAudioSourceRemovedDelegate;
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnVirtualAudioSourceSelected(IntPtr e, IntPtr virtualAudioSource);
		private OnVirtualAudioSourceSelected _mOnVirtualAudioSourceSelected = OnVirtualAudioSourceSelectedDelegate;
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnVirtualAudioSourceStateUpdated(IntPtr e, IntPtr virtualAudioSource, Device.DeviceState state);
		private OnVirtualAudioSourceStateUpdated _mOnVirtualAudioSourceStateUpdated = OnVirtualAudioSourceStateUpdatedDelegate;
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnVirtualVideoSourceAdded(IntPtr e, IntPtr virtualVideoSource);
		private OnVirtualVideoSourceAdded _mOnVirtualVideoSourceAdded = OnVirtualVideoSourceAddedDelegate;
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnVirtualVideoSourceExternalMediaBufferReleased(IntPtr e, IntPtr virtualVideoSource, IntPtr buffer, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(SizeTMarshaler))]SizeT size);
		private OnVirtualVideoSourceExternalMediaBufferReleased _mOnVirtualVideoSourceExternalMediaBufferReleased = OnVirtualVideoSourceExternalMediaBufferReleasedDelegate;
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnVirtualVideoSourceRemoved(IntPtr e, IntPtr virtualVideoSource);
		private OnVirtualVideoSourceRemoved _mOnVirtualVideoSourceRemoved = OnVirtualVideoSourceRemovedDelegate;
		[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
		private delegate void OnVirtualVideoSourceStateUpdated(IntPtr e, IntPtr virtualVideoSource, Device.DeviceState state);
		private OnVirtualVideoSourceStateUpdated _mOnVirtualVideoSourceStateUpdated = OnVirtualVideoSourceStateUpdatedDelegate;
		/// <summary>
		/// 
		/// </summary>
		public enum ClientAppLogLevel {
			/// <summary></summary>
			ClientapploglevelInfo,
			/// <summary></summary>
			ClientapploglevelDebug,
			/// <summary></summary>
			ClientapploglevelWarning,
			/// <summary></summary>
			ClientapploglevelError
		}
		/// <summary>
		/// Indicates the audio mode.
		/// </summary>
		public enum EndpointAudioMode {
			/// <summary>Both audio devices (Speaker and Microphone) used in shared mode.</summary>
			EndpointaudiomodeSharedModeBoth,
			/// <summary>Both audio devices (Speaker and Microphone) used in exclusive mode.</summary>
			EndpointaudiomodeExclusiveModeBoth,
			/// <summary>Microphone is used in exclusive mode and speaker in shared mode..</summary>
			EndpointaudiomodeExclusiveModeMicrophone,
			/// <summary>Unknown audio mode.</summary>
			EndpointaudiomodeUnknown
		}
		/// <summary>
		/// Base transport type.
		/// </summary>
		public enum EndpointBaseTransportType {
			/// <summary>Use TLS as base transport.</summary>
			EndpointbasetransporttypeTLS,
			/// <summary>Use TCP as base transport.</summary>
			EndpointbasetransporttypeTCP,
			/// <summary>Use UDP as base transport.</summary>
			EndpointbasetransporttypeUDP
		}
		/// <summary>
		/// Provides the error codes for camera background effect.
		/// </summary>
		public enum EndpointCameraEffectError {
			/// <summary>No errors.</summary>
			EndpointcameraeffecterrorNone,
			/// <summary>The token is empty or expired.</summary>
			EndpointcameraeffecterrorInvalidToken,
			/// <summary>The path to resources is empty or does not contain some files.</summary>
			EndpointcameraeffecterrorInvalidResources,
			/// <summary>The path to effect is empty or does not contain some files.</summary>
			EndpointcameraeffecterrorInvalidEffect,
			/// <summary>The blur intensity is out of allowed range.</summary>
			EndpointcameraeffecterrorInvalidBlurIntensity,
			/// <summary>The path to background picture is empty or file doesn't exist or has unsupported format.</summary>
			EndpointcameraeffecterrorInvalidBackgroundPicture,
			/// <summary>Failed to load effect.</summary>
			EndpointcameraeffecterrorLoadEffectFailed,
			/// <summary>Effect was not started due to unsupported OpenGL version.</summary>
			EndpointcameraeffecterrorUnsupportedOpenGLVersion,
			/// <summary>Effect was not started due to unsupported Banuba library version.</summary>
			EndpointcameraeffecterrorUnsupportedLibraryVersion,
			/// <summary>Opperation is not allowed with the current effect.</summary>
			EndpointcameraeffecterrorNotAllowedForCurrectEffect,
			/// <summary>Miscellaneous error.</summary>
			EndpointcameraeffecterrorMiscError
		}
		/// <summary>
		/// Provides the supported camera background effects and used to enable or disable effect.
		/// </summary>
		public enum EndpointCameraEffectType {
			/// <summary>Disables active effects.</summary>
			EndpointcameraeffecttypeNone,
			/// <summary>Enables background blur effect.</summary>
			EndpointcameraeffecttypeBlur,
			/// <summary>Enables virtual background effect.</summary>
			EndpointcameraeffecttypeVirtualBackground
		}
		/// <summary>
		/// Provide the advanced error code to the application.
		/// </summary>
		public enum EndpointErrorCode {
			/// <summary>Not allowed.</summary>
			EndpointerrorcodeNotAllowed,
			/// <summary>Called in wrong state.</summary>
			EndpointerrorcodeWrongState,
			/// <summary>Invalid input.</summary>
			EndpointerrorcodeInvalidInput,
			/// <summary>Miscellaneous remote error.</summary>
			EndpointerrorcodeMisc
		}
		/// <summary>
		/// Result of getting the logger category list.
		/// </summary>
		public enum EndpointGetLoggerCategoryListResult {
			/// <summary>Logger category list was got successfully.</summary>
			EndpointgetloggercategorylistresultSUCCESS,
			/// <summary>The getting of logger category list failed some miscellaneous reason.</summary>
			EndpointgetloggercategorylistresultMiscError
		}
		/// <summary>
		/// Represents the event action of google analytics service.
		/// </summary>
		public enum EndpointGoogleAnalyticsEventAction {
			/// <summary>Action for success login.</summary>
			EndpointgoogleanalyticseventactionLoginSuccess,
			/// <summary>Action for login attempt.</summary>
			EndpointgoogleanalyticseventactionLoginAttempt,
			/// <summary>Action for login failed: authentication failed.</summary>
			EndpointgoogleanalyticseventactionLoginFailedAuthentication,
			/// <summary>Action for login failed: failed to connect.</summary>
			EndpointgoogleanalyticseventactionLoginFailedConnect,
			/// <summary>Action for login failed: response timeout.</summary>
			EndpointgoogleanalyticseventactionLoginFailedResponseTimeout,
			/// <summary>Action for login failed: misc error.</summary>
			EndpointgoogleanalyticseventactionLoginFailedMiscError,
			/// <summary>Action for login failed: webproxy authentication required.</summary>
			EndpointgoogleanalyticseventactionLoginFailedWebProxyAuthRequired,
			/// <summary>Action for login failed: unsupported tenant version.</summary>
			EndpointgoogleanalyticseventactionLoginFailedUnsupportedTenantVersion,
			/// <summary>Action to indicate if user type is guest.</summary>
			EndpointgoogleanalyticseventactionUserTypeGuest,
			/// <summary>Action to indicate if user type is regular: token.</summary>
			EndpointgoogleanalyticseventactionUserTypeRegularToken,
			/// <summary>Action to indicate if user type is regular: password.</summary>
			EndpointgoogleanalyticseventactionUserTypeRegularPassword,
			/// <summary>Action to indicate if user type is regular: saml.</summary>
			EndpointgoogleanalyticseventactionUserTypeRegularSaml,
			/// <summary>Action to indicate if user type is regular: extdata.</summary>
			EndpointgoogleanalyticseventactionUserTypeRegularExtdata,
			/// <summary>Action to indicate join conference success.</summary>
			EndpointgoogleanalyticseventactionJoinConferenceSuccess,
			/// <summary>Action to indicate join conference attempt.</summary>
			EndpointgoogleanalyticseventactionJoinConferenceAttempt,
			/// <summary>Action to indicate join conference reconnect requests.</summary>
			EndpointgoogleanalyticseventactionJoinConferenceReconnectRequests,
			/// <summary>Action to indicate join conference failed due to connection error.</summary>
			EndpointgoogleanalyticseventactionJoinConferenceFailedConnectionError,
			/// <summary>Action to indicate join conference failed due to wrong Pin.</summary>
			EndpointgoogleanalyticseventactionJoinConferenceFailedWrongPin,
			/// <summary>Action to indicate join conference failed because room is full.</summary>
			EndpointgoogleanalyticseventactionJoinConferenceFailedRoomFull,
			/// <summary>Action to indicate join conference failed because room disabled.</summary>
			EndpointgoogleanalyticseventactionJoinConferenceFailedRoomDisabled,
			/// <summary>Action to indicate join conference failed because conference is locked.</summary>
			EndpointgoogleanalyticseventactionJoinConferenceFailedConferenceLocked,
			/// <summary>Action to indicate join conference failed due to unknown error.</summary>
			EndpointgoogleanalyticseventactionJoinConferenceFailedUnknownError,
			/// <summary>Action to indicate conference left.</summary>
			EndpointgoogleanalyticseventactionConferenceEndLeft,
			/// <summary>Action to indicate conference end booted.</summary>
			EndpointgoogleanalyticseventactionConferenceEndBooted,
			/// <summary>Action to indicate conference end signaling connection lost.</summary>
			EndpointgoogleanalyticseventactionConferenceEndSignalingConnectionLost,
			/// <summary>Action to indicate conference end failed media connection lost.</summary>
			EndpointgoogleanalyticseventactionConferenceEndMediaConnectionLost,
			/// <summary>Action to indicate conference end unknown error.</summary>
			EndpointgoogleanalyticseventactionConferenceEndUnknownError,
			/// <summary>Action to indicate H264 video codec is used in a conference call.</summary>
			EndpointgoogleanalyticseventactionInCallCodecVideoH264,
			/// <summary>Action to indicate H264-SVC video codec is used in a conference call.</summary>
			EndpointgoogleanalyticseventactionInCallCodecVideoH264SVC,
			/// <summary>Action to indicate SPEEX RED audio codec is used in a conference call.</summary>
			EndpointgoogleanalyticseventactionInCallCodecAudioSPEEXRED,
			/// <summary>All actions in category should be sent.</summary>
			EndpointgoogleanalyticseventactionAll,
			/// <summary>Unknown event action.</summary>
			EndpointgoogleanalyticseventactionUnknown
		}
		/// <summary>
		/// Represents the event category of google analytics service.
		/// </summary>
		public enum EndpointGoogleAnalyticsEventCategory {
			/// <summary>The login event category.</summary>
			EndpointgoogleanalyticseventcategoryLogin,
			/// <summary>The user type event category.</summary>
			EndpointgoogleanalyticseventcategoryUserType,
			/// <summary>The join Conference event category.</summary>
			EndpointgoogleanalyticseventcategoryJoinConference,
			/// <summary>The conference end event category.</summary>
			EndpointgoogleanalyticseventcategoryConferenceEnd,
			/// <summary>The in-call codec event category.</summary>
			EndpointgoogleanalyticseventcategoryInCallCodec,
			/// <summary>Unknown event category.</summary>
			EndpointgoogleanalyticseventcategoryNone
		}
		/// <summary>
		/// Result of file log compression.
		/// </summary>
		public enum EndpointLogCompressionResult {
			/// <summary>File Compressed successfully.</summary>
			EndpointlogcompressionresultSuccess,
			/// <summary>The compression failed some miscellaneous reason.</summary>
			EndpointlogcompressionresultMiscError
		}
		/// <summary>
		/// Type of the logger.
		/// </summary>
		public enum EndpointLoggerType {
			/// <summary>Logger type is console logger.</summary>
			EndpointloggertypeCONSOLE,
			/// <summary>Logger type is file logger.</summary>
			EndpointloggertypeFILE,
			/// <summary>Logger type is feedback logger.</summary>
			EndpointloggertypeFEEDBACK,
			/// <summary>Logger type is HTTP logger.</summary>
			EndpointloggertypeHTTP
		}
		/// <summary>
		/// 
		/// </summary>
		public enum EndpointMediaState {
			/// <summary></summary>
			EndpointmediastateIdle,
			/// <summary></summary>
			EndpointmediastateGreenRoom,
			/// <summary></summary>
			EndpointmediastateLive
		}
		/// <summary>
		/// Operating modes of the VidyoEndpoint.
		/// </summary>
		public enum EndpointMode {
			/// <summary>The default operating mode.</summary>
			EndpointmodeDefault,
			/// <summary>Runs in the foreground.</summary>
			EndpointmodeForeground,
			/// <summary>Runs in the background.</summary>
			EndpointmodeBackground
		}
		/// <summary>
		/// Lists available actions for next generation renderer library.
		/// </summary>
		public enum EndpointNGRActionType {
			/// <summary>Sets the layout.</summary>
			EndpointngractiontypeSetLayout,
			/// <summary>Sets the view size.</summary>
			EndpointngractiontypeSetViewSize,
			/// <summary>Sets the visibility of debug information.</summary>
			EndpointngractiontypeSetDebugInfoVisible,
			/// <summary>Sets the visibility of labels on renderer.</summary>
			EndpointngractiontypeSetLabelVisible,
			/// <summary>Sets the visibility of audio meter on tiles.</summary>
			EndpointngractiontypeSetAudioMeterVisible,
			/// <summary>Sets the background color.</summary>
			EndpointngractiontypeSetBackgroundColor,
			/// <summary>Sets the density.</summary>
			EndpointngractiontypeSetDensity,
			/// <summary>Sets the max remote participants.</summary>
			EndpointngractiontypeSetMaxRemoteParticipants,
			/// <summary>Pin the participants.</summary>
			EndpointngractiontypePinParticipant,
			/// <summary>Sets whether to show audio only tiles.</summary>
			EndpointngractiontypeShowAudioTiles,
			/// <summary>Invalid action.</summary>
			EndpointngractiontypeInvalid
		}
		/// <summary>
		/// Preferred audio codec to be set.
		/// </summary>
		public enum EndpointPreferredAudioCodec {
			/// <summary>Preferred audio codec is OPUS RED.</summary>
			EndpointpreferredaudiocodecOpusRed,
			/// <summary>Preferred audio codec is OPUS.</summary>
			EndpointpreferredaudiocodecOpus,
			/// <summary>Preferred audio codec is SPEEX RED.</summary>
			EndpointpreferredaudiocodecSpeexRed,
			/// <summary>Preferred audio codec is Unknown.</summary>
			EndpointpreferredaudiocodecUnknown
		}
		/// <summary>
		/// This type indicates the reason why an attempt to reconnect failed.
		/// </summary>
		public enum EndpointReconnectFailReason {
			/// <summary>Media support was disabled (by calling VidyoRoomDisableMedia) before an attempt to enable it completed.</summary>
			EndpointreconnectfailreasonCancelled,
			/// <summary>There was an error determining which conference to join.</summary>
			EndpointreconnectfailreasonNoConference,
			/// <summary>Signaling Connection lost on current transport.</summary>
			EndpointreconnectfailreasonSignalingConnectionLost,
			/// <summary>Media Connection lost on current transport.</summary>
			EndpointreconnectfailreasonMediaConnectionLost,
			/// <summary>Signaling messages were sent to enable media, but no response was received within the allotted amount of time.</summary>
			EndpointreconnectfailreasonNoResponse,
			/// <summary>Media support was disabled because the room password has changed.</summary>
			EndpointreconnectfailreasonInvalidPassword,
			/// <summary>Media support was disabled because the room pin has changed.</summary>
			EndpointreconnectfailreasonInvalidRoomPin,
			/// <summary>Media support was disabled because the room is full.</summary>
			EndpointreconnectfailreasonRoomIsFull,
			/// <summary>Media support was disabled because the room is invalid.</summary>
			EndpointreconnectfailreasonInvalidRoomKey,
			/// <summary>Media support was disabled because the room is disabled.</summary>
			EndpointreconnectfailreasonRoomDisabled,
			/// <summary>Media support was disabled because all lines are in use.</summary>
			EndpointreconnectfailreasonAllLinesInUse,
			/// <summary>Media support was disabled because the of a connection error.</summary>
			EndpointreconnectfailreasonConnectionError,
			/// <summary></summary>
			EndpointreconnectfailreasonInvalidRoom,
			/// <summary>Media support was disabled because the room is locked.</summary>
			EndpointreconnectfailreasonConferenceLocked,
			/// <summary>Media support was disabled because the seat license has expired.</summary>
			EndpointreconnectfailreasonSeatLicenseExpired,
			/// <summary>Media support was disabled because the endpoint is not licensed.</summary>
			EndpointreconnectfailreasonNotLicensed,
			/// <summary>Attempt to enable media was rejected by the server</summary>
			EndpointreconnectfailreasonRejected,
			/// <summary>Media support was disabled as there an unknown fault from the portal.</summary>
			EndpointreconnectfailreasonUnknownError,
			/// <summary>Some miscellaneous problem occurred with this application.</summary>
			EndpointreconnectfailreasonMiscLocalError,
			/// <summary>Some miscellaneous problem occurred with the conferencing service.</summary>
			EndpointreconnectfailreasonMiscRemoteError
		}
		/// <summary>
		/// 
		/// </summary>
		public enum EndpointTone {
			/// <summary></summary>
			EndpointtoneJoin,
			/// <summary></summary>
			EndpointtoneLeave,
			/// <summary></summary>
			EndpointtoneMsgRecv,
			/// <summary></summary>
			EndpointtoneMsgSend,
			/// <summary></summary>
			EndpointtoneRing,
			/// <summary></summary>
			EndpointtoneMax
		}
		/// <summary>
		/// 
		/// </summary>
		public enum EndpointTradeOffProfile {
			/// <summary></summary>
			EndpointtradeoffprofileHigh,
			/// <summary></summary>
			EndpointtradeoffprofileMedium,
			/// <summary></summary>
			EndpointtradeoffprofileLow,
			/// <summary>an alternative low configuration driving CPU tradeoff lower than VIDYO_ENDPOINTTRADEOFFPROFILE_Low</summary>
			EndpointtradeoffprofileLowAlt
		}
		/// <summary>
		/// Type of the virtual video source.
		/// </summary>
		public enum VirtualVideoSourceType {
			/// <summary>The type of virtual video source is a share.</summary>
			VirtualvideosourcetypeSHARE,
			/// <summary>The type of virtual video source is a camera.</summary>
			VirtualvideosourcetypeCAMERA
		}
		public interface ICompressLogs{

			void OnLogCompressionComplete(String compressedFileName, EndpointLogCompressionResult result);
		}
		public interface IGetActiveNetworkInterface{

			void OnGetActiveNetworkInterface(NetworkInterface signalingInterface, NetworkInterface mediaInterface);
		}
		public interface IGetAutoReconnectSetting{

			void OnGetAutoReconnectSetting(Boolean enableAutoReconnect, uint reconnectBackoff, uint maxReconnectAttempts);
		}
		public interface IGetCameraBackgroundEffect{

			void OnGetCameraBackgroundEffectInfo(EndpointCameraEffectInfo effectInfo);
		}
		public interface IGetFileLoggerCategoryListAsync{

			void OnGetLoggerCategoryListComplete(EndpointLoggerType loggerType, List<LoggerCategory> categories, EndpointGetLoggerCategoryListResult result);
		}
		public interface IGetGoogleAnalyticsEventTable{

			void OnGetAnalyticsEventTable(List<EndpointGoogleAnalyticsEventTable> eventTables);
		}
		public interface IGetGoogleAnalyticsOptions{

			void OnGetGoogleAnalyticsOptions(EndpointGoogleAnalyticsOptions options);
		}
		public interface IGetProductInfoAsync{

			void OnGetProductInfoComplete(List<Property> productInfo, List<Property> supportedFeature);
		}
		public interface IGetWhitelistedAudioDevices{

			void OnGetWhitelistedAudioDevices(List<String> audioDevices);
		}
		public interface IRegisterCameraEffectErrorListener{

			void OnCameraEffectError(EndpointCameraEffectError error);
		}
		public interface IRegisterDisableVideoOnLowBwEventListener{

			void OnDisableVideoOnLowBwStarted();
			void OnDisableVideoOnLowBwEnded();
		}
		public interface IRegisterErrorEventListener{

			void OnError(EndpointErrorCode error, String apiName);
		}
		public interface IRegisterLocalCameraEventListener{

			void OnLocalCameraAdded(LocalCamera localCamera);
			void OnLocalCameraRemoved(LocalCamera localCamera);
			void OnLocalCameraSelected(LocalCamera localCamera);
			void OnLocalCameraStateUpdated(LocalCamera localCamera, Device.DeviceState state);
		}
		public interface IRegisterLocalCameraFrameListener{

			void OnLocalCameraFrame(LocalCamera localCamera, VideoFrame videoFrame);
		}
		public interface IRegisterLocalMicrophoneEnergyListener{

			void OnLocalMicrophoneEnergy(LocalMicrophone localMicrophone, int audioEnergy);
		}
		public interface IRegisterLocalMicrophoneEventListener{

			void OnLocalMicrophoneAdded(LocalMicrophone localMicrophone);
			void OnLocalMicrophoneRemoved(LocalMicrophone localMicrophone);
			void OnLocalMicrophoneSelected(LocalMicrophone localMicrophone);
			void OnLocalMicrophoneStateUpdated(LocalMicrophone localMicrophone, Device.DeviceState state);
		}
		public interface IRegisterLocalMicrophoneFrameListener{

			void OnLocalMicrophoneFrame(LocalMicrophone localMicrophone, AudioFrame audioFrame);
		}
		public interface IRegisterLocalMonitorEventListener{

			void OnLocalMonitorAdded(LocalMonitor localMonitor);
			void OnLocalMonitorRemoved(LocalMonitor localMonitor);
			void OnLocalMonitorSelected(LocalMonitor localMonitor);
			void OnLocalMonitorStateUpdated(LocalMonitor localMonitor, Device.DeviceState state);
		}
		public interface IRegisterLocalMonitorFrameListener{

			void OnLocalMonitorFrame(LocalMonitor localMonitor, VideoFrame videoFrame);
		}
		public interface IRegisterLocalRendererEventListener{

			void OnLocalRendererAdded(LocalRenderer localRenderer);
			void OnLocalRendererRemoved(LocalRenderer localRenderer);
			void OnLocalRendererSelected(LocalRenderer localRenderer);
			void OnLocalRendererStateUpdated(LocalRenderer localRenderer, Device.DeviceState state);
		}
		public interface IRegisterLocalSpeakerEventListener{

			void OnLocalSpeakerAdded(LocalSpeaker localSpeaker);
			void OnLocalSpeakerRemoved(LocalSpeaker localSpeaker);
			void OnLocalSpeakerSelected(LocalSpeaker localSpeaker);
			void OnLocalSpeakerStateUpdated(LocalSpeaker localSpeaker, Device.DeviceState state);
		}
		public interface IRegisterLocalWindowShareEventListener{

			void OnLocalWindowShareAdded(LocalWindowShare localWindowShare);
			void OnLocalWindowShareRemoved(LocalWindowShare localWindowShare);
			void OnLocalWindowShareSelected(LocalWindowShare localWindowShare);
			void OnLocalWindowShareStateUpdated(LocalWindowShare localWindowShare, Device.DeviceState state);
		}
		public interface IRegisterLocalWindowShareFrameListener{

			void OnLocalWindowShareFrame(LocalWindowShare localWindowShare, VideoFrame videoFrame);
		}
		public interface IRegisterLogEventListener{

			void OnLog(LogRecord logRecord);
		}
		public interface IRegisterNGRResultEventListener{

			void OnNGRResult(EndpointNGRActionType type, Boolean success, String error);
		}
		public interface IRegisterNetworkInterfaceEventListener{

			void OnNetworkInterfaceAdded(NetworkInterface networkInterface);
			void OnNetworkInterfaceRemoved(NetworkInterface networkInterface);
			void OnNetworkInterfaceSelected(NetworkInterface networkInterface, NetworkInterface.NetworkInterfaceTransportType transportType);
			void OnNetworkInterfaceStateUpdated(NetworkInterface networkInterface, NetworkInterface.NetworkInterfaceState state);
		}
		public interface IRegisterReconnectEventListener{

			void OnReconnecting(uint attempt, uint attemptTimeout, EndpointReconnectFailReason reason);
			void OnReconnected();
			void OnConferenceLost(EndpointReconnectFailReason reason);
		}
		public interface IRegisterRemoteCameraEventListener{

			void OnRemoteCameraAdded(RemoteCamera remoteCamera, User user, Call call, Room room, Participant participant);
			void OnRemoteCameraRemoved(RemoteCamera remoteCamera, User user, Call call, Room room, Participant participant);
			void OnRemoteCameraStateUpdated(RemoteCamera remoteCamera, User user, Call call, Room room, Participant participant, Device.DeviceState state);
		}
		public interface IRegisterRemoteCameraFrameListener{

			void OnRemoteCameraFrame(RemoteCamera remoteCamera, Participant participant, VideoFrame videoFrame);
		}
		public interface IRegisterRemoteMicrophoneEnergyListener{

			void OnRemoteMicrophoneEnergy(RemoteMicrophone remoteMicrophone, Participant participant, int audioEnergy);
		}
		public interface IRegisterRemoteMicrophoneEventListener{

			void OnRemoteMicrophoneAdded(RemoteMicrophone remoteMicrophone, User user, Call call, Room room, Participant participant);
			void OnRemoteMicrophoneRemoved(RemoteMicrophone remoteMicrophone, User user, Call call, Room room, Participant participant);
			void OnRemoteMicrophoneStateUpdated(RemoteMicrophone remoteMicrophone, User user, Call call, Room room, Participant participant, Device.DeviceState state);
		}
		public interface IRegisterRemoteMicrophoneFrameListener{

			void OnRemoteMicrophoneFrame(RemoteMicrophone remoteMicrophone, Participant participant, AudioFrame audioFrame);
		}
		public interface IRegisterRemoteRendererEventListener{

			void OnRemoteRendererAdded(RemoteRenderer remoteRenderer, User user, Call call, Room room);
			void OnRemoteRendererRemoved(RemoteRenderer remoteRenderer, User user, Call call, Room room);
			void OnRemoteRendererStateUpdated(RemoteRenderer remoteRenderer, User user, Call call, Room room, Device.DeviceState state);
		}
		public interface IRegisterRemoteSpeakerEventListener{

			void OnRemoteSpeakerAdded(RemoteSpeaker remoteSpeaker, User user, Call call, Room room);
			void OnRemoteSpeakerRemoved(RemoteSpeaker remoteSpeaker, User user, Call call, Room room);
			void OnRemoteSpeakerStateUpdated(RemoteSpeaker remoteSpeaker, User user, Call call, Room room, Device.DeviceState state);
		}
		public interface IRegisterRemoteWindowShareEventListener{

			void OnRemoteWindowShareAdded(RemoteWindowShare remoteWindowShare, User user, Call call, Room room, Participant participant);
			void OnRemoteWindowShareRemoved(RemoteWindowShare remoteWindowShare, User user, Call call, Room room, Participant participant);
			void OnRemoteWindowShareStateUpdated(RemoteWindowShare remoteWindowShare, User user, Call call, Room room, Participant participant, Device.DeviceState state);
		}
		public interface IRegisterRemoteWindowShareFrameListener{

			void OnRemoteWindowShareFrame(RemoteWindowShare remoteWindowShare, Participant participant, VideoFrame videoFrame);
		}
		public interface IRegisterVirtualAudioSourceEventListener{

			void OnVirtualAudioSourceAdded(VirtualAudioSource virtualAudioSource);
			void OnVirtualAudioSourceRemoved(VirtualAudioSource virtualAudioSource);
			void OnVirtualAudioSourceStateUpdated(VirtualAudioSource virtualAudioSource, Device.DeviceState state);
			void OnVirtualAudioSourceSelected(VirtualAudioSource virtualAudioSource);
			void OnVirtualAudioSourceExternalMediaBufferReleased(VirtualAudioSource virtualAudioSource, byte[] buffer, SizeT size);
		}
		public interface IRegisterVirtualVideoSourceEventListener{

			void OnVirtualVideoSourceAdded(VirtualVideoSource virtualVideoSource);
			void OnVirtualVideoSourceRemoved(VirtualVideoSource virtualVideoSource);
			void OnVirtualVideoSourceStateUpdated(VirtualVideoSource virtualVideoSource, Device.DeviceState state);
			void OnVirtualVideoSourceExternalMediaBufferReleased(VirtualVideoSource virtualVideoSource, byte[] buffer, SizeT size);
		}
		public interface IRequestVideoForRemoteCamera{

			void OnRemoteCameraFirstFrameReceived(RemoteCamera remoteCamera);
		}
		public interface IRequestVideoForRemoteWindowShare{

			void OnRemoteWindowShareFirstFrameReceived(RemoteWindowShare remoteWindowShare);
		}
		public class EndpointGoogleAnalyticsEventTableFactory
		{
			public static EndpointGoogleAnalyticsEventTable Create()
			{
				return new EndpointGoogleAnalyticsEventTable(IntPtr.Zero);
			}
			public static void Destroy(EndpointGoogleAnalyticsEventTable obj)
			{
			}
		}
		/// <summary>
		/// The event action from event table.
		/// </summary>
		public class EndpointGoogleAnalyticsEventTable {
#if __IOS__
			const string importLib = "__Internal";
#else
			const string importLib = "libVidyoClient";
#endif
			private IntPtr objPtr; // opaque VidyoEndpointGoogleAnalyticsEventTable reference.
			public IntPtr GetObjectPtr() {

				VidyoEndpointGoogleAnalyticsEventTableSetenableNative(objPtr, enable);
				VidyoEndpointGoogleAnalyticsEventTableSeteventActionNative(objPtr, eventAction);
				VidyoEndpointGoogleAnalyticsEventTableSeteventCategoryNative(objPtr, eventCategory);

				return objPtr;
			}
			[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
			[return: MarshalAs(UnmanagedType.I1)]
			private static extern Boolean VidyoEndpointGoogleAnalyticsEventTableGetenableNative(IntPtr obj);

			[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
			private static extern void VidyoEndpointGoogleAnalyticsEventTableSetenableNative(IntPtr obj, Boolean enable);

			[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
			[return: MarshalAs(UnmanagedType.I4)]
			private static extern Endpoint.EndpointGoogleAnalyticsEventAction VidyoEndpointGoogleAnalyticsEventTableGeteventActionNative(IntPtr obj);

			[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
			private static extern void VidyoEndpointGoogleAnalyticsEventTableSeteventActionNative(IntPtr obj, Endpoint.EndpointGoogleAnalyticsEventAction eventAction);

			[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
			[return: MarshalAs(UnmanagedType.I4)]
			private static extern Endpoint.EndpointGoogleAnalyticsEventCategory VidyoEndpointGoogleAnalyticsEventTableGeteventCategoryNative(IntPtr obj);

			[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
			private static extern void VidyoEndpointGoogleAnalyticsEventTableSeteventCategoryNative(IntPtr obj, Endpoint.EndpointGoogleAnalyticsEventCategory eventCategory);

			[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
			public static extern IntPtr VidyoEndpointGoogleAnalyticsEventTableConstructCopyNative(IntPtr obj);

			[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
			public static extern IntPtr VidyoEndpointGoogleAnalyticsEventTableConstructDefaultNative();

			[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
			public static extern void VidyoEndpointGoogleAnalyticsEventTableDestructNative(IntPtr obj);

			/// <summary>
			/// An enable flag for action.
			/// </summary>
			public Boolean enable;
			/// <summary>
			/// The event action.
			/// </summary>
			public Endpoint.EndpointGoogleAnalyticsEventAction eventAction;
			/// <summary>
			/// The event category.
			/// </summary>
			public Endpoint.EndpointGoogleAnalyticsEventCategory eventCategory;
			public EndpointGoogleAnalyticsEventTable(IntPtr obj){
				if(obj == IntPtr.Zero) {
					objPtr = VidyoEndpointGoogleAnalyticsEventTableConstructDefaultNative();
				}
				else {
					objPtr = VidyoEndpointGoogleAnalyticsEventTableConstructCopyNative(obj);
				}

				enable = VidyoEndpointGoogleAnalyticsEventTableGetenableNative(objPtr);
				eventAction = VidyoEndpointGoogleAnalyticsEventTableGeteventActionNative(objPtr);
				eventCategory = VidyoEndpointGoogleAnalyticsEventTableGeteventCategoryNative(objPtr);
			}
			~EndpointGoogleAnalyticsEventTable() {
				VidyoEndpointGoogleAnalyticsEventTableDestructNative(objPtr);
			 }
		};
		public class EndpointGoogleAnalyticsOptionsFactory
		{
			public static EndpointGoogleAnalyticsOptions Create()
			{
				return new EndpointGoogleAnalyticsOptions(IntPtr.Zero);
			}
			public static void Destroy(EndpointGoogleAnalyticsOptions obj)
			{
			}
		}
		/// <summary>
		/// Represent the options for google analytics.
		/// </summary>
		public class EndpointGoogleAnalyticsOptions {
#if __IOS__
			const string importLib = "__Internal";
#else
			const string importLib = "libVidyoClient";
#endif
			private IntPtr objPtr; // opaque VidyoEndpointGoogleAnalyticsOptions reference.
			public IntPtr GetObjectPtr() {
				IntPtr nId = MarshalPtrToUtf8.GetInstance().MarshalManagedToNative(id ?? string.Empty);
				IntPtr nKey = MarshalPtrToUtf8.GetInstance().MarshalManagedToNative(key ?? string.Empty);

				VidyoEndpointGoogleAnalyticsOptionsSetidNative(objPtr, nId);
				VidyoEndpointGoogleAnalyticsOptionsSetkeyNative(objPtr, nKey);

				Marshal.FreeHGlobal(nKey);
				Marshal.FreeHGlobal(nId);
				return objPtr;
			}
			[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
			private static extern IntPtr VidyoEndpointGoogleAnalyticsOptionsGetidNative(IntPtr obj);

			[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
			private static extern void VidyoEndpointGoogleAnalyticsOptionsSetidNative(IntPtr obj, IntPtr id);

			[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
			private static extern IntPtr VidyoEndpointGoogleAnalyticsOptionsGetkeyNative(IntPtr obj);

			[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
			private static extern void VidyoEndpointGoogleAnalyticsOptionsSetkeyNative(IntPtr obj, IntPtr key);

			[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
			public static extern IntPtr VidyoEndpointGoogleAnalyticsOptionsConstructCopyNative(IntPtr obj);

			[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
			public static extern IntPtr VidyoEndpointGoogleAnalyticsOptionsConstructDefaultNative();

			[DllImport(importLib, CallingConvention = CallingConvention.Cdecl)]
			public static extern void VidyoEndpointGoogleAnalyticsOptionsDestructNative(IntPtr obj);

			/// <summary>
			/// Represents the measurement is for google analytics service.
			/// </summary>
			public String id;
			/// <summary>
			/// Represents the configured API secret key for google analytics service.
			/// </summary>
			public String key;
			public EndpointGoogleAnalyticsOptions(IntPtr obj){
				if(obj == IntPtr.Zero) {
					objPtr = VidyoEndpointGoogleAnalyticsOptionsConstructDefaultNative();
				}
				else {
					objPtr = VidyoEndpointGoogleAnalyticsOptionsConstructCopyNative(obj);
				}

				id = (string)MarshalPtrToUtf8.GetInstance().MarshalNativeToManaged(VidyoEndpointGoogleAnalyticsOptionsGetidNative(objPtr));
				key = (string)MarshalPtrToUtf8.GetInstance().MarshalNativeToManaged(VidyoEndpointGoogleAnalyticsOptionsGetkeyNative(objPtr));
			}
			~EndpointGoogleAnalyticsOptions() {
				VidyoEndpointGoogleAnalyticsOptionsDestructNative(objPtr);
			 }
		};
		private ICompressLogs _mICompressLogs;
		private IGetActiveNetworkInterface _mIGetActiveNetworkInterface;
		private IGetAutoReconnectSetting _mIGetAutoReconnectSetting;
		private IGetCameraBackgroundEffect _mIGetCameraBackgroundEffect;
		private IGetFileLoggerCategoryListAsync _mIGetFileLoggerCategoryListAsync;
		private IGetGoogleAnalyticsEventTable _mIGetGoogleAnalyticsEventTable;
		private IGetGoogleAnalyticsOptions _mIGetGoogleAnalyticsOptions;
		private IGetProductInfoAsync _mIGetProductInfoAsync;
		private IGetWhitelistedAudioDevices _mIGetWhitelistedAudioDevices;
		private IRegisterCameraEffectErrorListener _mIRegisterCameraEffectErrorListener;
		private IRegisterDisableVideoOnLowBwEventListener _mIRegisterDisableVideoOnLowBwEventListener;
		private IRegisterErrorEventListener _mIRegisterErrorEventListener;
		private IRegisterLocalCameraEventListener _mIRegisterLocalCameraEventListener;
		private IRegisterLocalCameraFrameListener _mIRegisterLocalCameraFrameListener;
		private IRegisterLocalMicrophoneEnergyListener _mIRegisterLocalMicrophoneEnergyListener;
		private IRegisterLocalMicrophoneEventListener _mIRegisterLocalMicrophoneEventListener;
		private IRegisterLocalMicrophoneFrameListener _mIRegisterLocalMicrophoneFrameListener;
		private IRegisterLocalMonitorEventListener _mIRegisterLocalMonitorEventListener;
		private IRegisterLocalMonitorFrameListener _mIRegisterLocalMonitorFrameListener;
		private IRegisterLocalRendererEventListener _mIRegisterLocalRendererEventListener;
		private IRegisterLocalSpeakerEventListener _mIRegisterLocalSpeakerEventListener;
		private IRegisterLocalWindowShareEventListener _mIRegisterLocalWindowShareEventListener;
		private IRegisterLocalWindowShareFrameListener _mIRegisterLocalWindowShareFrameListener;
		private IRegisterLogEventListener _mIRegisterLogEventListener;
		private IRegisterNGRResultEventListener _mIRegisterNGRResultEventListener;
		private IRegisterNetworkInterfaceEventListener _mIRegisterNetworkInterfaceEventListener;
		private IRegisterReconnectEventListener _mIRegisterReconnectEventListener;
		private IRegisterRemoteCameraEventListener _mIRegisterRemoteCameraEventListener;
		private IRegisterRemoteCameraFrameListener _mIRegisterRemoteCameraFrameListener;
		private IRegisterRemoteMicrophoneEnergyListener _mIRegisterRemoteMicrophoneEnergyListener;
		private IRegisterRemoteMicrophoneEventListener _mIRegisterRemoteMicrophoneEventListener;
		private IRegisterRemoteMicrophoneFrameListener _mIRegisterRemoteMicrophoneFrameListener;
		private IRegisterRemoteRendererEventListener _mIRegisterRemoteRendererEventListener;
		private IRegisterRemoteSpeakerEventListener _mIRegisterRemoteSpeakerEventListener;
		private IRegisterRemoteWindowShareEventListener _mIRegisterRemoteWindowShareEventListener;
		private IRegisterRemoteWindowShareFrameListener _mIRegisterRemoteWindowShareFrameListener;
		private IRegisterVirtualAudioSourceEventListener _mIRegisterVirtualAudioSourceEventListener;
		private IRegisterVirtualVideoSourceEventListener _mIRegisterVirtualVideoSourceEventListener;
		/// <summary>
		/// On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e"></param>
		/// <param name="viewId">A platform specific parent view ID where the VidyoEndpoint's rendering window will be added as a child window. It will be used to render preview and composite remote participants. When running custom layout on macOS, the core animation layer should be disabled on this view.</param>
		/// <param name="viewStyle">Type of the composite renderer which represents the visual style and behaviour.</param>
		/// <param name="remoteParticipants">Number of remote participants to composite into the window. Setting the value to 0 will render preview only.</param>
		/// <param name="logFileFilter"><p>A space-separated (or comma-separated) sequence of names of log levels, each optionally followed by a category. Categories are separated from levels by the character '@'.</p> <p>Either a level or category may be specified as 'all' or '*' (interchangeably), meaning all levels or categories. A level specified without a category is equivalent to a level@*.</p> <p>The levels are: 'fatal', 'error', 'warning', 'info', 'debug', 'sent', 'received', 'enter', and 'leave'.</p> <p>The level may be prefixed by '-' or '!' (interchangeably), meaning to remove the given level (or levels, see below) from the given category. The string 'none' is equivalent to '-all'.</p> <p>The first level in the list may be prefixed by '+'. If the first level begins with a '+' or '-'/'!', the string is used to modify the listener's existing levels and categories. Otherwise, unless the <code>add</code> parameter is true, the levels and categories specified in the string replace all existing levels and categories for the listener. The leading character '+' may be present before other levels, but is ignored.</p> <p>Unless they are preceded by '=', level names imply other levels as well. In particular, each of the levels 'fatal', 'error', 'warning', 'info', and 'debug' implies the levels higher than it, when specified positively; 'sent' and 'received' always imply each other; and 'enter' and 'leave' always imply each other.</p> <p>See VidyoConnectorGetLogCategories for determining the names and descriptions of registered categories.</p> <p>Level names are case-insensitive; category names are case-sensitive.</p> <p>Example: "all" - all levels, all categories.</p> <p>Example: "all -enter" - all categories, all levels but enter and leave.</p> <p>Example: "*@VidyoClient" - all levels for the VidyoClient category.</p> <p>Example: "-*@VidyoClient" - remove all levels from the VidyoClient category.</p> <p>Example: "debug" - all categories, fatal, error, warning, info, and debug levels.</p> <p>Example: "=debug" - all categories, debug level only.</p> <p>Example: "all -=enter" - all categories, all levels but enter (leave is still included).</p> <p>Example: "error@VidyoClient" - fatal and error only for the VidyoClient category.</p> <p>Example: "warning debug@VidyoClient" - fatal, error, and warning for all categories; additionally, info and debug for the VidyoClient category.</p></param>
		/// <param name="alloc"></param>
		public Endpoint(IntPtr viewId, LocalRenderer.LocalRendererViewStyle viewStyle, uint remoteParticipants, String logFileFilter) {

			IntPtr nLogFileFilter = MarshalPtrToUtf8.GetInstance().MarshalManagedToNative(logFileFilter ?? string.Empty);
			objPtr = VidyoEndpointConstructNative(ref viewId, viewStyle, remoteParticipants, nLogFileFilter);
			objHandle = GCHandle.Alloc(this, GCHandleType.Weak);
			Marshal.FreeHGlobal(nLogFileFilter);
			if (objPtr != IntPtr.Zero) {
				VidyoEndpointSetUserDataNative(objPtr, GCHandle.ToIntPtr(objHandle));
				VidyoEndpointRegisterRemoteCameraEventListenerNative(objPtr, _mOnRemoteCameraAdded, _mOnRemoteCameraRemoved, _mOnRemoteCameraStateUpdated);
				VidyoEndpointRegisterRemoteMicrophoneEventListenerNative(objPtr, _mOnRemoteMicrophoneAdded, _mOnRemoteMicrophoneRemoved, _mOnRemoteMicrophoneStateUpdated);
				VidyoEndpointRegisterRemoteWindowShareEventListenerNative(objPtr, _mOnRemoteWindowShareAdded, _mOnRemoteWindowShareRemoved, _mOnRemoteWindowShareStateUpdated);
			}
		}
		public Endpoint(IntPtr other){
			objPtr = VidyoEndpointConstructCopyNative(other);
			if (objPtr != IntPtr.Zero) {
				objHandle = GCHandle.Alloc(this, GCHandleType.Weak);
				VidyoEndpointSetUserDataNative(objPtr, GCHandle.ToIntPtr(objHandle));
			}
		}
		~Endpoint(){
			Dispose(false);
		}
		public void Dispose(){
			Dispose(true);
			GC.SuppressFinalize(this);
		}

		public void Dispose(bool disposing){
			if(disposed) return;

			disposed = true;
			DisposeWeakReferenceObjects();
			if(objPtr != IntPtr.Zero) {
				VidyoEndpointSetUserDataNative(objPtr, IntPtr.Zero);
				VidyoEndpointDestructNative(objPtr);
				objPtr = IntPtr.Zero;
			}

			if(objHandle.IsAllocated) objHandle.Free();
		}

		/// <summary>
		/// Adds audio device to whitelist.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="deviceName">The name of audio device that will be whitelisted.</param>
		public Boolean AddAudioDeviceToWhitelist(String deviceName) {
			if (objPtr == IntPtr.Zero) { return default; }

			IntPtr nDeviceName = MarshalPtrToUtf8.GetInstance().MarshalManagedToNative(deviceName ?? string.Empty);
			Boolean ret = VidyoEndpointAddAudioDeviceToWhitelistNative(objPtr, nDeviceName);
			Marshal.FreeHGlobal(nDeviceName);

			return ret;
		}
		/// <summary>
		/// Add message class that application should receive.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="messageClass">Name of message class. MSGCLASS_HUNTER is added by default so application will receive only these message class.</param>
		public Boolean AddMessageClass(String messageClass) {
			if (objPtr == IntPtr.Zero) { return default; }

			IntPtr nMessageClass = MarshalPtrToUtf8.GetInstance().MarshalManagedToNative(messageClass ?? string.Empty);
			Boolean ret = VidyoEndpointAddMessageClassNative(objPtr, nMessageClass);
			Marshal.FreeHGlobal(nMessageClass);

			return ret;
		}
		/// <summary>
		/// Log an application log message into the VidyoClient logs under the log category 'Application'.
		/// </summary>
		/// <param name="e"></param>
		/// <param name="logLevel">Specify logging level using enum, allowed values defined in VidyoClientAppLogLevel</param>
		/// <param name="logMsg">Log message to write to logfile</param>
		public void AppLog(ClientAppLogLevel logLevel, String logMsg) {
			if (objPtr == IntPtr.Zero) { return; }

			IntPtr nLogMsg = MarshalPtrToUtf8.GetInstance().MarshalManagedToNative(logMsg ?? string.Empty);
			VidyoEndpointAppLogNative(objPtr, logLevel, nLogMsg);
			Marshal.FreeHGlobal(nLogMsg);
		}
		/// <summary>
		/// Composites the preview and remote participants in a view. On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="viewId">A platform specific view ID where the participant will be rendered.</param>
		/// <param name="viewStyle">Type of the composite renderer which represents the visual style and behaviour.</param>
		/// <param name="remoteParticipants">Number of remote participants to composite into the window. Setting the value to 0 will render preview only.</param>
		public Boolean AssignViewToCompositeRenderer(IntPtr viewId, LocalRenderer.LocalRendererViewStyle viewStyle, uint remoteParticipants) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointAssignViewToCompositeRendererNative(objPtr, ref viewId, viewStyle, remoteParticipants);

			return ret;
		}
		/// <summary>
		/// Shows a preview of a local camera in a view. On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="viewId">A platform specific view ID where the participant will be rendered.</param>
		/// <param name="localCamera">The VidyoLocalCamera that will be shown.</param>
		/// <param name="displayCropped">Render the image as cropped. Otherwise letterbox.</param>
		/// <param name="allowZoom">Allow zooming of the image with mouse or touch.</param>
		public Boolean AssignViewToLocalCamera(IntPtr viewId, LocalCamera localCamera, Boolean displayCropped, Boolean allowZoom) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointAssignViewToLocalCameraNative(objPtr, ref viewId, (localCamera != null) ? localCamera.GetObjectPtr():IntPtr.Zero, displayCropped, allowZoom);

			return ret;
		}
		/// <summary>
		/// Shows a VidyoLocalMonitor in a view. On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="viewId">A platform specific view ID where the VidyoLocalMonitor will be rendered.</param>
		/// <param name="localMonitor">The VidyoLocalMonitor that will be shown.</param>
		/// <param name="displayCropped">Render the image as cropped. Otherwise letterbox.</param>
		/// <param name="allowZoom">Allow zooming of the image with mouse or touch.</param>
		public Boolean AssignViewToLocalMonitor(IntPtr viewId, LocalMonitor localMonitor, Boolean displayCropped, Boolean allowZoom) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointAssignViewToLocalMonitorNative(objPtr, ref viewId, (localMonitor != null) ? localMonitor.GetObjectPtr():IntPtr.Zero, displayCropped, allowZoom);

			return ret;
		}
		/// <summary>
		/// Shows a VidyoLocalWindowShare in a view. On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="viewId">A platform specific view ID where the VidyoLocalWindowShare will be rendered.</param>
		/// <param name="localWindowShare">The VidyoLocalWindowShare that will be shown.</param>
		/// <param name="displayCropped">Render the image as cropped. Otherwise letterbox.</param>
		/// <param name="allowZoom">Allow zooming of the image with mouse or touch.</param>
		public Boolean AssignViewToLocalWindowShare(IntPtr viewId, LocalWindowShare localWindowShare, Boolean displayCropped, Boolean allowZoom) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointAssignViewToLocalWindowShareNative(objPtr, ref viewId, (localWindowShare != null) ? localWindowShare.GetObjectPtr():IntPtr.Zero, displayCropped, allowZoom);

			return ret;
		}
		/// <summary>
		/// Shows a participant in a view.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="viewId">A platform specific view ID where the participant will be rendered.</param>
		/// <param name="remoteCamera">The VidyoRemoteCamera that will be shown.</param>
		/// <param name="displayCropped">Render the image as cropped. Otherwise letterbox.</param>
		/// <param name="allowZoom">Allow zooming of the image with mouse or touch.</param>
		public Boolean AssignViewToRemoteCamera(IntPtr viewId, RemoteCamera remoteCamera, Boolean displayCropped, Boolean allowZoom) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointAssignViewToRemoteCameraNative(objPtr, ref viewId, (remoteCamera != null) ? remoteCamera.GetObjectPtr():IntPtr.Zero, displayCropped, allowZoom);

			return ret;
		}
		/// <summary>
		/// Shows a participant in a view. On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="viewId">A platform specific view ID where the participant will be rendered.</param>
		/// <param name="remoteWindowShare">The VidyoRemoteWindowShare that will be shown.</param>
		/// <param name="displayCropped">Render the image as cropped. Otherwise letterbox.</param>
		/// <param name="allowZoom">Allow zooming of the image with mouse or touch.</param>
		public Boolean AssignViewToRemoteWindowShare(IntPtr viewId, RemoteWindowShare remoteWindowShare, Boolean displayCropped, Boolean allowZoom) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointAssignViewToRemoteWindowShareNative(objPtr, ref viewId, (remoteWindowShare != null) ? remoteWindowShare.GetObjectPtr():IntPtr.Zero, displayCropped, allowZoom);

			return ret;
		}
		/// <summary>
		/// Shows a virtual video source in a view. On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="viewId">A platform specific view ID where the source will be rendered.</param>
		/// <param name="virtualVideoSource">The VidyoVirtualVideoSource that will be shown.</param>
		/// <param name="displayCropped">Render the image as cropped. Otherwise letterbox.</param>
		/// <param name="allowZoom">Allow zooming of the image with mouse or touch.</param>
		public Boolean AssignViewToVirtualVideoSource(IntPtr viewId, VirtualVideoSource virtualVideoSource, Boolean displayCropped, Boolean allowZoom) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointAssignViewToVirtualVideoSourceNative(objPtr, ref viewId, (virtualVideoSource != null) ? virtualVideoSource.GetObjectPtr():IntPtr.Zero, displayCropped, allowZoom);

			return ret;
		}
		/// <summary>
		/// 
		/// </summary>
		/// <param name="e"></param>
		/// <param name="compressedFileName">Name if the compression output file.</param>
		/// <param name="onComplete">Callback that is triggered when the compression completes.</param>
		public Boolean CompressLogs(String compressedFileName, ICompressLogs _iICompressLogs) {
			if (objPtr == IntPtr.Zero) { return default; }
			_mICompressLogs = _iICompressLogs;

			IntPtr nCompressedFileName = MarshalPtrToUtf8.GetInstance().MarshalManagedToNative(compressedFileName ?? string.Empty);
			Boolean ret = VidyoEndpointCompressLogsNative(objPtr, nCompressedFileName, _mOnLogCompressionComplete);
			Marshal.FreeHGlobal(nCompressedFileName);

			return ret;
		}
		/// <summary>
		/// 
		/// </summary>
		/// <param name="e"></param>
		/// <param name="monitor"></param>
		/// <param name="width"></param>
		/// <param name="height"></param>
		public Boolean CreateRenderer(LocalMonitor monitor, uint width, uint height) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointCreateRendererNative(objPtr, (monitor != null) ? monitor.GetObjectPtr():IntPtr.Zero, width, height);

			return ret;
		}
		/// <summary>
		/// 
		/// </summary>
		/// <param name="e"></param>
		/// <param name="viewId">A platform specific parent view ID where the rendering window will be added as a child window.</param>
		/// <param name="x">X coordinate of the child window within the parent view ID.</param>
		/// <param name="y">Y coordinate of the child window within the parent view ID.</param>
		/// <param name="width">Width of the child window within the parent view ID.</param>
		/// <param name="height">Height of the child window within the parent view ID.</param>
		public Boolean CreateRendererFromViewId(IntPtr viewId, int x, int y, uint width, uint height) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointCreateRendererFromViewIdNative(objPtr, ref viewId, x, y, width, height);

			return ret;
		}
		/// <summary>
		/// 
		/// </summary>
		/// <param name="e"></param>
		public Boolean CreateRendererMultiScreen() {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointCreateRendererMultiScreenNative(objPtr);

			return ret;
		}
		/// <summary>
		/// Create virtual audio source. This is an asynchronous interface. The VidyoEndpointOnVirtualAudioSourceAdded will trigger.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="name">The name for the virtual audio source.</param>
		/// <param name="id">The id for the virtual audio source.</param>
		/// <param name="configuration">The string in JSON format that contain audio configuration that will be used for virtual audio source. <p>format - Specifies the media format. Possible values are: fl32 or in16. The default is fl32.</p> <p>Example: {'format' : 'in16'}.</p> <p>sampleRate - Specifies the audio sample rate. Possible values are: 48000, 32000 and 16000. The default is 32000.</p> <p>Example: {'sampleRate' : 48000}.</p> <p>numberOfChannels - Specifies the number of channels. Possible values are: 1 or 2. The default is 1.</p> <p>Example: {'numberOfChannels' : 2}.</p> <p>frameInterval - Specifies the frame interval in ms. Possible values are: 20 or 40. The default is 20.</p> <p>Example: {'frameInterval' : 40}.</p></param>
		public Boolean CreateVirtualAudioSource(String name, String id, String configuration) {
			if (objPtr == IntPtr.Zero) { return default; }

			IntPtr nName = MarshalPtrToUtf8.GetInstance().MarshalManagedToNative(name ?? string.Empty);
			IntPtr nId = MarshalPtrToUtf8.GetInstance().MarshalManagedToNative(id ?? string.Empty);
			IntPtr nConfiguration = MarshalPtrToUtf8.GetInstance().MarshalManagedToNative(configuration ?? string.Empty);
			Boolean ret = VidyoEndpointCreateVirtualAudioSourceNative(objPtr, nName, nId, nConfiguration);
			Marshal.FreeHGlobal(nConfiguration);
			Marshal.FreeHGlobal(nId);
			Marshal.FreeHGlobal(nName);

			return ret;
		}
		/// <summary>
		/// Create a virtual video source. The user can create a maximum of 10 virtual video sources. On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="type">Type of the virtual video source.</param>
		/// <param name="id">Unique ID.</param>
		/// <param name="name">Name of the virtual video source.</param>
		public Boolean CreateVirtualVideoSource(VirtualVideoSourceType type, String id, String name) {
			if (objPtr == IntPtr.Zero) { return default; }

			IntPtr nId = MarshalPtrToUtf8.GetInstance().MarshalManagedToNative(id ?? string.Empty);
			IntPtr nName = MarshalPtrToUtf8.GetInstance().MarshalManagedToNative(name ?? string.Empty);
			Boolean ret = VidyoEndpointCreateVirtualVideoSourceNative(objPtr, type, nId, nName);
			Marshal.FreeHGlobal(nName);
			Marshal.FreeHGlobal(nId);

			return ret;
		}
		/// <summary>
		/// Cycles camera selection to the next available camera. On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		public Boolean CycleCamera() {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointCycleCameraNative(objPtr);

			return ret;
		}
		/// <summary>
		/// Cycles microphone selection to the next available microphone. On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		public Boolean CycleMicrophone() {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointCycleMicrophoneNative(objPtr);

			return ret;
		}
		/// <summary>
		/// Cycles speaker selection to the next available speaker. On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		public Boolean CycleSpeaker() {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointCycleSpeakerNative(objPtr);

			return ret;
		}
		/// <summary>
		/// Destroy virtual audio source. This is an asynchronous interface. The VidyoEndpointOnVirtualAudioSourceRemoved will trigger.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="virtualAudioSource">The virtual audio source that will be destroyed.</param>
		public Boolean DestroyVirtualAudioSource(VirtualAudioSource virtualAudioSource) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointDestroyVirtualAudioSourceNative(objPtr, (virtualAudioSource != null) ? virtualAudioSource.GetObjectPtr():IntPtr.Zero);

			return ret;
		}
		/// <summary>
		/// Destroy virtual video source. On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="virtualVideoSource">The virtual video source that will be destroyed.</param>
		public Boolean DestroyVirtualVideoSource(VirtualVideoSource virtualVideoSource) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointDestroyVirtualVideoSourceNative(objPtr, (virtualVideoSource != null) ? virtualVideoSource.GetObjectPtr():IntPtr.Zero);

			return ret;
		}
		/// <summary>
		/// Stop background tasks associated with an endpoint. On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e">The endpoint object to disable.</param>
		public void Disable() {
			if (objPtr == IntPtr.Zero) { return; }

			VidyoEndpointDisableNative(objPtr);
		}
		/// <summary>
		/// 
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		public void DisableDebug() {
			if (objPtr == IntPtr.Zero) { return; }

			VidyoEndpointDisableDebugNative(objPtr);
		}
		/// <summary>
		/// Enabled debug mode on the endpoint which will start debug logging and enable statistics.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="port">Debug port will output debug logging.</param>
		/// <param name="logFilter">Log filter to use on the debug port.</param>
		public Boolean EnableDebug(uint port, String logFilter) {
			if (objPtr == IntPtr.Zero) { return default; }

			IntPtr nLogFilter = MarshalPtrToUtf8.GetInstance().MarshalManagedToNative(logFilter ?? string.Empty);
			Boolean ret = VidyoEndpointEnableDebugNative(objPtr, port, nLogFilter);
			Marshal.FreeHGlobal(nLogFilter);

			return ret;
		}
		/// <summary>
		/// 
		/// </summary>
		/// <param name="e"></param>
		/// <param name="logFileName"></param>
		/// <param name="logFileFilter"></param>
		public Boolean EnableFileLogger(String logFileName, String logFileFilter) {
			if (objPtr == IntPtr.Zero) { return default; }

			IntPtr nLogFileName = MarshalPtrToUtf8.GetInstance().MarshalManagedToNative(logFileName ?? string.Empty);
			IntPtr nLogFileFilter = MarshalPtrToUtf8.GetInstance().MarshalManagedToNative(logFileFilter ?? string.Empty);
			Boolean ret = VidyoEndpointEnableFileLoggerNative(objPtr, nLogFileName, nLogFileFilter);
			Marshal.FreeHGlobal(nLogFileFilter);
			Marshal.FreeHGlobal(nLogFileName);

			return ret;
		}
		/// <summary>
		/// This is an asynchronous interface. Get the NetworkInterface for media and signaling.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="onGetActiveNetworkInterfaceCallback">Callback called upon completion.</param>
		public Boolean GetActiveNetworkInterface(IGetActiveNetworkInterface _iIGetActiveNetworkInterface) {
			if (objPtr == IntPtr.Zero) { return default; }
			_mIGetActiveNetworkInterface = _iIGetActiveNetworkInterface;

			Boolean ret = VidyoEndpointGetActiveNetworkInterfaceNative(objPtr, _mOnGetActiveNetworkInterface);

			return ret;
		}
		/// <summary>
		/// 
		/// </summary>
		/// <param name="e"></param>
		public String GetApplicationTag() {
			if (objPtr == IntPtr.Zero) { return default; }

			IntPtr ret = VidyoEndpointGetApplicationTagNative(objPtr);

			return (string)MarshalPtrToUtf8.GetInstance().MarshalNativeToManaged(ret);
		}
		/// <summary>
		/// Gets audio bitrate multiplier which is used when calculating the audio bitrate.
		/// </summary>
		/// <param name="e">The endpoint object.</param>
		public uint GetAudioBitrateMultiplier() {
			if (objPtr == IntPtr.Zero) { return default; }

			uint ret = VidyoEndpointGetAudioBitrateMultiplierNative(objPtr);

			return ret;
		}
		/// <summary>
		/// Gets the audio mode for both the audio devices (speaker and microphone).
		/// </summary>
		/// <param name="e">The endpoint object.</param>
		public EndpointAudioMode GetAudioMode() {
			if (objPtr == IntPtr.Zero) { return default; }

			EndpointAudioMode ret = VidyoEndpointGetAudioModeNative(objPtr);

			return ret;
		}
		/// <summary>
		/// Gets time interval between two packet of audio in miliseconds.
		/// </summary>
		/// <param name="e">The endpoint object.</param>
		public uint GetAudioPacketInterval() {
			if (objPtr == IntPtr.Zero) { return default; }

			uint ret = VidyoEndpointGetAudioPacketIntervalNative(objPtr);

			return ret;
		}
		/// <summary>
		/// Gets audio loss percantage - value that is used to configure encoder.
		/// </summary>
		/// <param name="e">The endpoint object.</param>
		public uint GetAudioPacketLossPercentage() {
			if (objPtr == IntPtr.Zero) { return default; }

			uint ret = VidyoEndpointGetAudioPacketLossPercentageNative(objPtr);

			return ret;
		}
		/// <summary>
		/// Gets state of auto-reconnect. It's either enabled or disabled.
		/// </summary>
		/// <param name="e">The endpoint object.</param>
		public Boolean GetAutoReconnect() {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointGetAutoReconnectNative(objPtr);

			return ret;
		}
		/// <summary>
		/// Gets back off for next reconnect attempt.
		/// </summary>
		/// <param name="e">The endpoint object.</param>
		public uint GetAutoReconnectAttemptBackOff() {
			if (objPtr == IntPtr.Zero) { return default; }

			uint ret = VidyoEndpointGetAutoReconnectAttemptBackOffNative(objPtr);

			return ret;
		}
		/// <summary>
		/// Gets maximum attempts to be done for reconnecting.
		/// </summary>
		/// <param name="e">The endpoint object.</param>
		public uint GetAutoReconnectMaxAttempts() {
			if (objPtr == IntPtr.Zero) { return default; }

			uint ret = VidyoEndpointGetAutoReconnectMaxAttemptsNative(objPtr);

			return ret;
		}
		/// <summary>
		/// This is an asynchronous interface. Gets the auto-reconnect setting.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="onGetAutoReconnectSettingCallback">Callback called upon completion.</param>
		public Boolean GetAutoReconnectSetting(IGetAutoReconnectSetting _iIGetAutoReconnectSetting) {
			if (objPtr == IntPtr.Zero) { return default; }
			_mIGetAutoReconnectSetting = _iIGetAutoReconnectSetting;

			Boolean ret = VidyoEndpointGetAutoReconnectSettingNative(objPtr, _mOnGetAutoReconnectSetting);

			return ret;
		}
		/// <summary>
		/// Gets the current configuration of camera background effect. This functionality is supported only for macOS 10.14 and above, iOS 10.0 and above and Windows VC++ 15 and above.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="onGetEffectInfo">Callback that reports the current configuration of camera background effect to the application. In case some error occurs NULL will be reported.</param>
		public Boolean GetCameraBackgroundEffect(IGetCameraBackgroundEffect _iIGetCameraBackgroundEffect) {
			if (objPtr == IntPtr.Zero) { return default; }
			_mIGetCameraBackgroundEffect = _iIGetCameraBackgroundEffect;

			Boolean ret = VidyoEndpointGetCameraBackgroundEffectNative(objPtr, _mOnGetCameraBackgroundEffectInfo);

			return ret;
		}
		/// <summary>
		/// Gets conference number - a special identifier that is showed up in the Portal CDR record for the conference.
		/// </summary>
		/// <param name="e">The endpoint object.</param>
		public String GetConferenceNumber() {
			if (objPtr == IntPtr.Zero) { return default; }

			IntPtr ret = VidyoEndpointGetConferenceNumberNative(objPtr);

			return (string)MarshalPtrToUtf8.GetInstance().MarshalNativeToManaged(ret);
		}
		/// <summary>
		/// Get current CPU profile setting.
		/// </summary>
		/// <param name="e">The endpoint object.</param>
		public EndpointTradeOffProfile GetCpuTradeOffProfile() {
			if (objPtr == IntPtr.Zero) { return default; }

			EndpointTradeOffProfile ret = VidyoEndpointGetCpuTradeOffProfileNative(objPtr);

			return ret;
		}
		/// <summary>
		/// Gets state of video on low bandwidth. It's either enabled or disabled.
		/// </summary>
		/// <param name="e">The endpoint object.</param>
		public Boolean GetDisableVideoOnLowBandwidth() {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointGetDisableVideoOnLowBandwidthNative(objPtr);

			return ret;
		}
		/// <summary>
		/// Gets number of audio streams requested while video is shut off.
		/// </summary>
		/// <param name="e">The endpoint object.</param>
		public uint GetDisableVideoOnLowBandwidthAudioStreams() {
			if (objPtr == IntPtr.Zero) { return default; }

			uint ret = VidyoEndpointGetDisableVideoOnLowBandwidthAudioStreamsNative(objPtr);

			return ret;
		}
		/// <summary>
		/// Gets time it takes to recover when video is shut off.
		/// </summary>
		/// <param name="e">The endpoint object.</param>
		public uint GetDisableVideoOnLowBandwidthRecoveryTime() {
			if (objPtr == IntPtr.Zero) { return default; }

			uint ret = VidyoEndpointGetDisableVideoOnLowBandwidthRecoveryTimeNative(objPtr);

			return ret;
		}
		/// <summary>
		/// Gets time it takes to shut off video due to low bandwidth.
		/// </summary>
		/// <param name="e">The endpoint object.</param>
		public uint GetDisableVideoOnLowBandwidthResponseTime() {
			if (objPtr == IntPtr.Zero) { return default; }

			uint ret = VidyoEndpointGetDisableVideoOnLowBandwidthResponseTimeNative(objPtr);

			return ret;
		}
		/// <summary>
		/// Gets how often checking for low bandwidth happens.
		/// </summary>
		/// <param name="e">The endpoint object.</param>
		public uint GetDisableVideoOnLowBandwidthSampleTime() {
			if (objPtr == IntPtr.Zero) { return default; }

			uint ret = VidyoEndpointGetDisableVideoOnLowBandwidthSampleTimeNative(objPtr);

			return ret;
		}
		/// <summary>
		/// Gets low bandwidth threshold.
		/// </summary>
		/// <param name="e">The endpoint object.</param>
		public uint GetDisableVideoOnLowBandwidthThreshold() {
			if (objPtr == IntPtr.Zero) { return default; }

			uint ret = VidyoEndpointGetDisableVideoOnLowBandwidthThresholdNative(objPtr);

			return ret;
		}
		/// <summary>
		/// 
		/// </summary>
		/// <param name="e"></param>
		/// <param name="categories"></param>
		public Boolean GetFileLoggerCategoryList(ref List<LoggerCategory> categories) {
			if (objPtr == IntPtr.Zero) { return default; }

			IntPtr nListCategories = VidyoEndpointVectorVidyoLoggerCategoryAllocateNative();

			Boolean ret = VidyoEndpointGetFileLoggerCategoryListNative(objPtr, nListCategories);

			List<LoggerCategory> csCategories = new List<LoggerCategory>();
			var nCategoriesSize = 0;
			var nCategories = VidyoEndpointGetFileLoggerCategoryListGetcategoriesArrayNative(nListCategories, ref nCategoriesSize);
			var nCategoriesIndex = 0;
			while (nCategoriesIndex < nCategoriesSize) {
				LoggerCategory csTcategories = new LoggerCategory(Marshal.ReadIntPtr(nCategories + (nCategoriesIndex * Marshal.SizeOf(nCategories))));
				csCategories.Add(csTcategories);
				nCategoriesIndex++;
			}

			categories = csCategories;
			VidyoEndpointGetFileLoggerCategoryListFreecategoriesArrayNative(nCategories, nCategoriesSize);
			VidyoEndpointVectorVidyoLoggerCategoryDeallocateNative(nListCategories);

			return ret;
		}
		/// <summary>
		/// 
		/// </summary>
		/// <param name="e">The endpoint object.</param>
		/// <param name="onComplete">The callback that is triggered when getting the logger category list completes.</param>
		public Boolean GetFileLoggerCategoryListAsync(IGetFileLoggerCategoryListAsync _iIGetFileLoggerCategoryListAsync) {
			if (objPtr == IntPtr.Zero) { return default; }
			_mIGetFileLoggerCategoryListAsync = _iIGetFileLoggerCategoryListAsync;

			Boolean ret = VidyoEndpointGetFileLoggerCategoryListAsyncNative(objPtr, _mOnGetLoggerCategoryListComplete);

			return ret;
		}
		/// <summary>
		/// This is an asynchronous interface. Get the analytics event table.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="onGetAnalyticsEventTableCallback">Callback called upon completion.</param>
		public Boolean GetGoogleAnalyticsEventTable(IGetGoogleAnalyticsEventTable _iIGetGoogleAnalyticsEventTable) {
			if (objPtr == IntPtr.Zero) { return default; }
			_mIGetGoogleAnalyticsEventTable = _iIGetGoogleAnalyticsEventTable;

			Boolean ret = VidyoEndpointGetGoogleAnalyticsEventTableNative(objPtr, _mOnGetAnalyticsEventTable);

			return ret;
		}
		/// <summary>
		/// Returns the configuration of Google Analytics 4 service.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="onGetGoogleAnalyticsOptions">Callback called upon completion.</param>
		public Boolean GetGoogleAnalyticsOptions(IGetGoogleAnalyticsOptions _iIGetGoogleAnalyticsOptions) {
			if (objPtr == IntPtr.Zero) { return default; }
			_mIGetGoogleAnalyticsOptions = _iIGetGoogleAnalyticsOptions;

			Boolean ret = VidyoEndpointGetGoogleAnalyticsOptionsNative(objPtr, _mOnGetGoogleAnalyticsOptions);

			return ret;
		}
		/// <summary>
		/// 
		/// </summary>
		/// <param name="e"></param>
		public String GetId() {
			if (objPtr == IntPtr.Zero) { return default; }

			IntPtr ret = VidyoEndpointGetIdNative(objPtr);

			return (string)MarshalPtrToUtf8.GetInstance().MarshalNativeToManaged(ret);
		}
		/// <summary>
		/// Returns Insights Url if service is running.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		public String GetInsightsServiceUrl() {
			if (objPtr == IntPtr.Zero) { return default; }

			IntPtr ret = VidyoEndpointGetInsightsServiceUrlNative(objPtr);

			return (string)MarshalPtrToUtf8.GetInstance().MarshalNativeToManaged(ret);
		}
		/// <summary>
		/// Return the max receive bit rate configured by application.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		public uint GetMaxReceiveBitRate() {
			if (objPtr == IntPtr.Zero) { return default; }

			uint ret = VidyoEndpointGetMaxReceiveBitRateNative(objPtr);

			return ret;
		}
		/// <summary>
		/// Return the max send bit rate configured by application.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		public uint GetMaxSendBitRate() {
			if (objPtr == IntPtr.Zero) { return default; }

			uint ret = VidyoEndpointGetMaxSendBitRateNative(objPtr);

			return ret;
		}
		/// <summary>
		/// Gets maximum microphone boost level that is applied only in the conference for the selected microphone in case the system is set to the higher value.
		/// </summary>
		/// <param name="e">The endpoint object.</param>
		public double GetMicrophoneMaxBoostLevel() {
			if (objPtr == IntPtr.Zero) { return default; }

			double ret = VidyoEndpointGetMicrophoneMaxBoostLevelNative(objPtr);

			return ret;
		}
		/// <summary>
		/// Gets minimum microphone value that is applied only in the conference for the selected microphone in case the system is set to the lower value.
		/// </summary>
		/// <param name="e">The endpoint object.</param>
		public uint GetMinMicrophoneVolume() {
			if (objPtr == IntPtr.Zero) { return default; }

			uint ret = VidyoEndpointGetMinMicrophoneVolumeNative(objPtr);

			return ret;
		}
		/// <summary>
		/// 
		/// </summary>
		/// <param name="e">The endpoint object.</param>
		public String GetOptions() {
			if (objPtr == IntPtr.Zero) { return default; }

			IntPtr ret = VidyoEndpointGetOptionsNative(objPtr);

			return (string)MarshalPtrToUtf8.GetInstance().MarshalNativeToManaged(ret);
		}
		/// <summary>
		/// Gets preferred audio codec type.
		/// </summary>
		/// <param name="e">The endpoint object.</param>
		public EndpointPreferredAudioCodec GetPreferredAudioCodec() {
			if (objPtr == IntPtr.Zero) { return default; }

			EndpointPreferredAudioCodec ret = VidyoEndpointGetPreferredAudioCodecNative(objPtr);

			return ret;
		}
		/// <summary>
		/// Get the product information of the endpoint.
		/// </summary>
		/// <param name="e">The endpoint object.</param>
		/// <param name="productInfo">The product info of the endpoint</param>
		/// <param name="supportedFeature">The features this endpoint can support</param>
		public Boolean GetProductInfo(ref List<Property> productInfo, ref List<Property> supportedFeature) {
			if (objPtr == IntPtr.Zero) { return default; }

			IntPtr nListProductInfo = VidyoEndpointVectorVidyoPropertyAllocateNative();

			IntPtr nListSupportedFeature = VidyoEndpointVectorVidyoPropertyAllocateNative();

			Boolean ret = VidyoEndpointGetProductInfoNative(objPtr, nListProductInfo, nListSupportedFeature);

			List<Property> csProductInfo = new List<Property>();
			var nProductInfoSize = 0;
			var nProductInfo = VidyoEndpointGetProductInfoGetproductInfoArrayNative(nListProductInfo, ref nProductInfoSize);
			var nProductInfoIndex = 0;
			while (nProductInfoIndex < nProductInfoSize) {
				Property csTproductInfo = new Property(Marshal.ReadIntPtr(nProductInfo + (nProductInfoIndex * Marshal.SizeOf(nProductInfo))));
				csProductInfo.Add(csTproductInfo);
				nProductInfoIndex++;
			}

			productInfo = csProductInfo;
			VidyoEndpointGetProductInfoFreeproductInfoArrayNative(nProductInfo, nProductInfoSize);

			List<Property> csSupportedFeature = new List<Property>();
			var nSupportedFeatureSize = 0;
			var nSupportedFeature = VidyoEndpointGetProductInfoGetsupportedFeatureArrayNative(nListSupportedFeature, ref nSupportedFeatureSize);
			var nSupportedFeatureIndex = 0;
			while (nSupportedFeatureIndex < nSupportedFeatureSize) {
				Property csTsupportedFeature = new Property(Marshal.ReadIntPtr(nSupportedFeature + (nSupportedFeatureIndex * Marshal.SizeOf(nSupportedFeature))));
				csSupportedFeature.Add(csTsupportedFeature);
				nSupportedFeatureIndex++;
			}

			supportedFeature = csSupportedFeature;
			VidyoEndpointGetProductInfoFreesupportedFeatureArrayNative(nSupportedFeature, nSupportedFeatureSize);
			VidyoEndpointVectorVidyoPropertyDeallocateNative(nListSupportedFeature);
			VidyoEndpointVectorVidyoPropertyDeallocateNative(nListProductInfo);

			return ret;
		}
		/// <summary>
		/// Get the product information of the endpoint.
		/// </summary>
		/// <param name="e">The endpoint object.</param>
		/// <param name="onComplete">The callback that is triggered when getting the product information completes.</param>
		public Boolean GetProductInfoAsync(IGetProductInfoAsync _iIGetProductInfoAsync) {
			if (objPtr == IntPtr.Zero) { return default; }
			_mIGetProductInfoAsync = _iIGetProductInfoAsync;

			Boolean ret = VidyoEndpointGetProductInfoAsyncNative(objPtr, _mOnGetProductInfoComplete);

			return ret;
		}
		/// <summary>
		/// Gets the local renderer and conference tiles displaying options.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="viewId">A platform-specific view ID.</param>
		public String GetRendererOptionsForViewId(IntPtr viewId) {
			if (objPtr == IntPtr.Zero) { return default; }

			IntPtr ret = VidyoEndpointGetRendererOptionsForViewIdNative(objPtr, ref viewId);

			return (string)MarshalPtrToUtf8.GetInstance().MarshalNativeToManaged(ret);
		}
		/// <summary>
		/// Gets whether SVC is enabled.
		/// </summary>
		/// <param name="e">The endpoint object.</param>
		public Boolean GetStaticShareSvcState() {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointGetStaticShareSvcStateNative(objPtr);

			return ret;
		}
		/// <summary>
		/// Gets conference room statistics gather interval in seconds.
		/// </summary>
		/// <param name="e">The endpoint object.</param>
		public long GetStatisticRate() {
			if (objPtr == IntPtr.Zero) { return default; }

			long ret = VidyoEndpointGetStatisticRateNative(objPtr);

			return ret;
		}
		/// <summary>
		/// Fill in data in VidyoEndpointStats from an endpoint.
		/// </summary>
		/// <param name="e">The endpoint object to extract stats.</param>
		public EndpointStats GetStats() {
			if (objPtr == IntPtr.Zero) { return default; }

			IntPtr ret = VidyoEndpointGetStatsNative(objPtr);
			EndpointStats csRet = new EndpointStats(ret);

			return csRet;
		}
		/// <summary>
		/// Fill in data in VidyoEndpointStats from an endpoint.
		/// </summary>
		/// <param name="e">The endpoint object to extract stats.</param>
		public String GetStatsJson() {
			if (objPtr == IntPtr.Zero) { return default; }

			IntPtr ret = VidyoEndpointGetStatsJsonNative(objPtr);

			return (string)MarshalPtrToUtf8.GetInstance().MarshalNativeToManaged(ret);
		}
		/// <summary>
		/// Gets the names of the audio devices that are whitelisted.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="onGetCallback">Callback that will report an array with the names of audio devices that are whitelisted.</param>
		public Boolean GetWhitelistedAudioDevices(IGetWhitelistedAudioDevices _iIGetWhitelistedAudioDevices) {
			if (objPtr == IntPtr.Zero) { return default; }
			_mIGetWhitelistedAudioDevices = _iIGetWhitelistedAudioDevices;

			Boolean ret = VidyoEndpointGetWhitelistedAudioDevicesNative(objPtr, _mOnGetWhitelistedAudioDevices);

			return ret;
		}
		/// <summary>
		/// Control type of event action and categories.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="eventCategory">Type of event category.</param>
		/// <param name="eventAction">Type of event action</param>
		/// <param name="enable">Event action state flag.</param>
		public Boolean GoogleAnalyticsControlEventAction(EndpointGoogleAnalyticsEventCategory eventCategory, EndpointGoogleAnalyticsEventAction eventAction, Boolean enable) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointGoogleAnalyticsControlEventActionNative(objPtr, eventCategory, eventAction, enable);

			return ret;
		}
		/// <summary>
		/// Hides a view which is used for custom layout of sources. On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="viewId">The view ID of the view to hide.</param>
		public Boolean HideView(IntPtr viewId) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointHideViewNative(objPtr, ref viewId);

			return ret;
		}
		/// <summary>
		/// Notify endpoint of an event. This data will be sent to Loki analytics. Event is automatically timestamped.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="eventName">Event name.</param>
		/// <param name="parameters">Event parameters as string vector. Can be NULL if no parameters are needed.</param>
		public Boolean InsightsNotifyApplicationEvent(String eventName, List<String> parameters) {
			if (objPtr == IntPtr.Zero) { return default; }

			IntPtr nEventName = MarshalPtrToUtf8.GetInstance().MarshalManagedToNative(eventName ?? string.Empty);
			IntPtr nListParameters = VidyoEndpointVectorLmiStringAllocateNative();

			IntPtr nParameters = Marshal.AllocHGlobal(Marshal.SizeOf<IntPtr>() * parameters.Count);
			int nParametersSize = 0;
			foreach (String iter in parameters) {
				Marshal.WriteIntPtr(nParameters + (nParametersSize * Marshal.SizeOf<IntPtr>()), MarshalPtrToUtf8.GetInstance().MarshalManagedToNative(iter ?? string.Empty));
				nParametersSize++;
			}
			VidyoEndpointInsightsNotifyApplicationEventSetparametersArrayNative(nListParameters, nParameters, nParametersSize);
			Marshal.FreeHGlobal(nParameters);
			Boolean ret = VidyoEndpointInsightsNotifyApplicationEventNative(objPtr, nEventName, nListParameters);
			VidyoEndpointVectorLmiStringDeallocateNative(nListParameters);
			Marshal.FreeHGlobal(nEventName);

			return ret;
		}
		/// <summary>
		/// Checks if debug mode is enabled on the endpoint.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		public Boolean IsDebugEnabled() {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointIsDebugEnabledNative(objPtr);

			return ret;
		}
		/// <summary>
		/// Checks whether Google Analytics service is running.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		public Boolean IsGoogleAnalyticsServiceEnabled() {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointIsGoogleAnalyticsServiceEnabledNative(objPtr);

			return ret;
		}
		/// <summary>
		/// Checks whether Insights service is running.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		public Boolean IsInsightsServiceEnabled() {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointIsInsightsServiceEnabledNative(objPtr);

			return ret;
		}
		/// <summary>
		/// On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e"></param>
		/// <param name="localCamera"></param>
		public void LocalCameraSelectAdvanced(LocalCamera localCamera) {
			if (objPtr == IntPtr.Zero) { return; }

			VidyoEndpointLocalCameraSelectAdvancedNative(objPtr, (localCamera != null) ? localCamera.GetObjectPtr():IntPtr.Zero);
		}
		/// <summary>
		/// On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e"></param>
		/// <param name="localCamera"></param>
		public void LocalCameraUnselectAdvanced(LocalCamera localCamera) {
			if (objPtr == IntPtr.Zero) { return; }

			VidyoEndpointLocalCameraUnselectAdvancedNative(objPtr, (localCamera != null) ? localCamera.GetObjectPtr():IntPtr.Zero);
		}
		/// <summary>
		/// On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e"></param>
		/// <param name="localMicrophone"></param>
		/// <param name="previewedPreCall"></param>
		public void LocalMicrophoneSelectAdvanced(LocalMicrophone localMicrophone, Boolean previewedPreCall) {
			if (objPtr == IntPtr.Zero) { return; }

			VidyoEndpointLocalMicrophoneSelectAdvancedNative(objPtr, (localMicrophone != null) ? localMicrophone.GetObjectPtr():IntPtr.Zero, previewedPreCall);
		}
		/// <summary>
		/// On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e"></param>
		/// <param name="localMicrophone"></param>
		public void LocalMicrophoneUnselectAdvanced(LocalMicrophone localMicrophone) {
			if (objPtr == IntPtr.Zero) { return; }

			VidyoEndpointLocalMicrophoneUnselectAdvancedNative(objPtr, (localMicrophone != null) ? localMicrophone.GetObjectPtr():IntPtr.Zero);
		}
		/// <summary>
		/// On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e"></param>
		/// <param name="localMonitor"></param>
		public void LocalMonitorSelectAdvanced(LocalMonitor localMonitor) {
			if (objPtr == IntPtr.Zero) { return; }

			VidyoEndpointLocalMonitorSelectAdvancedNative(objPtr, (localMonitor != null) ? localMonitor.GetObjectPtr():IntPtr.Zero);
		}
		/// <summary>
		/// On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e"></param>
		/// <param name="localMonitor"></param>
		public void LocalMonitorUnselectAdvanced(LocalMonitor localMonitor) {
			if (objPtr == IntPtr.Zero) { return; }

			VidyoEndpointLocalMonitorUnselectAdvancedNative(objPtr, (localMonitor != null) ? localMonitor.GetObjectPtr():IntPtr.Zero);
		}
		/// <summary>
		/// On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e"></param>
		/// <param name="localRenderer"></param>
		public void LocalRendererSelectAdvanced(LocalRenderer localRenderer) {
			if (objPtr == IntPtr.Zero) { return; }

			VidyoEndpointLocalRendererSelectAdvancedNative(objPtr, (localRenderer != null) ? localRenderer.GetObjectPtr():IntPtr.Zero);
		}
		/// <summary>
		/// On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e"></param>
		/// <param name="localRenderer"></param>
		public void LocalRendererUnselectAdvanced(LocalRenderer localRenderer) {
			if (objPtr == IntPtr.Zero) { return; }

			VidyoEndpointLocalRendererUnselectAdvancedNative(objPtr, (localRenderer != null) ? localRenderer.GetObjectPtr():IntPtr.Zero);
		}
		/// <summary>
		/// On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e"></param>
		/// <param name="localSpeaker"></param>
		public void LocalSpeakerSelectAdvanced(LocalSpeaker localSpeaker) {
			if (objPtr == IntPtr.Zero) { return; }

			VidyoEndpointLocalSpeakerSelectAdvancedNative(objPtr, (localSpeaker != null) ? localSpeaker.GetObjectPtr():IntPtr.Zero);
		}
		/// <summary>
		/// On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e"></param>
		/// <param name="localSpeaker"></param>
		public void LocalSpeakerUnselectAdvanced(LocalSpeaker localSpeaker) {
			if (objPtr == IntPtr.Zero) { return; }

			VidyoEndpointLocalSpeakerUnselectAdvancedNative(objPtr, (localSpeaker != null) ? localSpeaker.GetObjectPtr():IntPtr.Zero);
		}
		/// <summary>
		/// On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e"></param>
		/// <param name="localWindowShare"></param>
		public void LocalWindowShareSelectAdvanced(LocalWindowShare localWindowShare) {
			if (objPtr == IntPtr.Zero) { return; }

			VidyoEndpointLocalWindowShareSelectAdvancedNative(objPtr, (localWindowShare != null) ? localWindowShare.GetObjectPtr():IntPtr.Zero);
		}
		/// <summary>
		/// On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e"></param>
		/// <param name="localWindowShare"></param>
		public void LocalWindowShareUnselectAdvanced(LocalWindowShare localWindowShare) {
			if (objPtr == IntPtr.Zero) { return; }

			VidyoEndpointLocalWindowShareUnselectAdvancedNative(objPtr, (localWindowShare != null) ? localWindowShare.GetObjectPtr():IntPtr.Zero);
		}
		/// <summary>
		/// Registers callback to notify the user in case of any errors occur during enabling camera effect.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="onError">The callback that will reports camera effect errors.</param>
		public Boolean RegisterCameraEffectErrorListener(IRegisterCameraEffectErrorListener _iIRegisterCameraEffectErrorListener) {
			if (objPtr == IntPtr.Zero) { return default; }
			_mIRegisterCameraEffectErrorListener = _iIRegisterCameraEffectErrorListener;

			Boolean ret = VidyoEndpointRegisterCameraEffectErrorListenerNative(objPtr, _mOnCameraEffectError);

			return ret;
		}
		/// <summary>
		/// Register callbacks for disable video on low bandwidth.
		/// </summary>
		/// <param name="e">VidyoEndpoint object.</param>
		/// <param name="onStarted">Callback that will be triggered when disable video on low bandwidth is started.</param>
		/// <param name="onEnded">Callback that will be triggered when disable video on low bandwidth is ended.</param>
		public void RegisterDisableVideoOnLowBwEventListener(IRegisterDisableVideoOnLowBwEventListener _iIRegisterDisableVideoOnLowBwEventListener) {
			if (objPtr == IntPtr.Zero) { return; }
			_mIRegisterDisableVideoOnLowBwEventListener = _iIRegisterDisableVideoOnLowBwEventListener;

			VidyoEndpointRegisterDisableVideoOnLowBwEventListenerNative(objPtr, _mOnDisableVideoOnLowBwStarted, _mOnDisableVideoOnLowBwEnded);
		}
		/// <summary>
		/// Registers the advanced error event listeners.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="onErrorCallback">Callback that is triggered when an error occurs.</param>
		public Boolean RegisterErrorEventListener(IRegisterErrorEventListener _iIRegisterErrorEventListener) {
			if (objPtr == IntPtr.Zero) { return default; }
			_mIRegisterErrorEventListener = _iIRegisterErrorEventListener;

			Boolean ret = VidyoEndpointRegisterErrorEventListenerNative(objPtr, _mOnError);

			return ret;
		}
		/// <summary>
		/// Registers to get notified about camera events. On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="onAdded">Callback that is triggered for every new or existing camera added.</param>
		/// <param name="onRemoved">Callback that is triggered when the camera is removed.</param>
		/// <param name="onSelected">Callback that is triggered when a camera is selected for use.</param>
		/// <param name="onStateUpdated">Callback that is triggered when a camera state is updated.</param>
		public Boolean RegisterLocalCameraEventListener(IRegisterLocalCameraEventListener _iIRegisterLocalCameraEventListener) {
			if (objPtr == IntPtr.Zero) { return default; }
			_mIRegisterLocalCameraEventListener = _iIRegisterLocalCameraEventListener;

			Boolean ret = VidyoEndpointRegisterLocalCameraEventListenerNative(objPtr, _mOnLocalCameraAdded, _mOnLocalCameraRemoved, _mOnLocalCameraSelected, _mOnLocalCameraStateUpdated);

			return ret;
		}
		/// <summary>
		/// Registers to get notified about camera frames. On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="localCamera">The VidyoLocalCamera for which to receive the frames.</param>
		/// <param name="onFrame">Callback that is triggered for every frame from a remote camera.</param>
		/// <param name="width">Approximate width of the requested frame.</param>
		/// <param name="height">Approximate height of the requested frame.</param>
		/// <param name="frameInterval">Approximate frame interval of the requested frame.</param>
		public Boolean RegisterLocalCameraFrameListener(LocalCamera localCamera, IRegisterLocalCameraFrameListener _iIRegisterLocalCameraFrameListener, uint width, uint height, ulong frameInterval) {
			if (objPtr == IntPtr.Zero) { return default; }
			_mIRegisterLocalCameraFrameListener = _iIRegisterLocalCameraFrameListener;

			Boolean ret = VidyoEndpointRegisterLocalCameraFrameListenerNative(objPtr, (localCamera != null) ? localCamera.GetObjectPtr():IntPtr.Zero, _mOnLocalCameraFrame, width, height, frameInterval);

			return ret;
		}
		/// <summary>
		/// Registers to get notified about microphone energies.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="onEnergy">Callback that is triggered for every frame with energy from a microphone.</param>
		public Boolean RegisterLocalMicrophoneEnergyListener(IRegisterLocalMicrophoneEnergyListener _iIRegisterLocalMicrophoneEnergyListener) {
			if (objPtr == IntPtr.Zero) { return default; }
			_mIRegisterLocalMicrophoneEnergyListener = _iIRegisterLocalMicrophoneEnergyListener;

			Boolean ret = VidyoEndpointRegisterLocalMicrophoneEnergyListenerNative(objPtr, _mOnLocalMicrophoneEnergy);

			return ret;
		}
		/// <summary>
		/// Registers to get notified about microphone events. On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="onAdded">Callback that is triggered for every new or existing microphone added.</param>
		/// <param name="onRemoved">Callback that is triggered when the microphone is removed.</param>
		/// <param name="onSelected">Callback that is triggered when a microphone is selected for use.</param>
		/// <param name="onStateUpdated">Callback that is triggered when a microphone state is updated.</param>
		public Boolean RegisterLocalMicrophoneEventListener(IRegisterLocalMicrophoneEventListener _iIRegisterLocalMicrophoneEventListener) {
			if (objPtr == IntPtr.Zero) { return default; }
			_mIRegisterLocalMicrophoneEventListener = _iIRegisterLocalMicrophoneEventListener;

			Boolean ret = VidyoEndpointRegisterLocalMicrophoneEventListenerNative(objPtr, _mOnLocalMicrophoneAdded, _mOnLocalMicrophoneRemoved, _mOnLocalMicrophoneSelected, _mOnLocalMicrophoneStateUpdated);

			return ret;
		}
		/// <summary>
		/// Registers to get notified about microphone frames. On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="localMicrophone">The VidyoLocalMicrophone for which to receive the frames.</param>
		/// <param name="onFrame">Callback that is triggered for every frame from a microphone.</param>
		public Boolean RegisterLocalMicrophoneFrameListener(LocalMicrophone localMicrophone, IRegisterLocalMicrophoneFrameListener _iIRegisterLocalMicrophoneFrameListener) {
			if (objPtr == IntPtr.Zero) { return default; }
			_mIRegisterLocalMicrophoneFrameListener = _iIRegisterLocalMicrophoneFrameListener;

			Boolean ret = VidyoEndpointRegisterLocalMicrophoneFrameListenerNative(objPtr, (localMicrophone != null) ? localMicrophone.GetObjectPtr():IntPtr.Zero, _mOnLocalMicrophoneFrame);

			return ret;
		}
		/// <summary>
		/// Registers to get notified about monitor events. On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="onAdded">Callback that is triggered for every new or existing monitor added.</param>
		/// <param name="onRemoved">Callback that is triggered when the monitor is removed.</param>
		/// <param name="onSelected">Callback that is triggered when a monitor is selected for use.</param>
		/// <param name="onStateUpdated">Callback that is triggered when a monitor state is updated.</param>
		public Boolean RegisterLocalMonitorEventListener(IRegisterLocalMonitorEventListener _iIRegisterLocalMonitorEventListener) {
			if (objPtr == IntPtr.Zero) { return default; }
			_mIRegisterLocalMonitorEventListener = _iIRegisterLocalMonitorEventListener;

			Boolean ret = VidyoEndpointRegisterLocalMonitorEventListenerNative(objPtr, _mOnLocalMonitorAdded, _mOnLocalMonitorRemoved, _mOnLocalMonitorSelected, _mOnLocalMonitorStateUpdated);

			return ret;
		}
		/// <summary>
		/// Registers to get notified about monitor frames. On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="localMonitor">The VidyoLocalMonitor for which to receive the frames.</param>
		/// <param name="onFrame">Callback that is triggered for every frame from a monitor.</param>
		/// <param name="width">Approximate width of the requested frame.</param>
		/// <param name="height">Approximate height of the requested frame.</param>
		/// <param name="frameInterval">Approximate frame interval of the requested frame.</param>
		public Boolean RegisterLocalMonitorFrameListener(LocalMonitor localMonitor, IRegisterLocalMonitorFrameListener _iIRegisterLocalMonitorFrameListener, uint width, uint height, ulong frameInterval) {
			if (objPtr == IntPtr.Zero) { return default; }
			_mIRegisterLocalMonitorFrameListener = _iIRegisterLocalMonitorFrameListener;

			Boolean ret = VidyoEndpointRegisterLocalMonitorFrameListenerNative(objPtr, (localMonitor != null) ? localMonitor.GetObjectPtr():IntPtr.Zero, _mOnLocalMonitorFrame, width, height, frameInterval);

			return ret;
		}
		/// <summary>
		/// Registers to get notified about renderer events. On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="onAdded">Callback that is triggered for every new or existing window added.</param>
		/// <param name="onRemoved">Callback that is triggered when the window is removed.</param>
		/// <param name="onSelected">Callback that is triggered when a window is selected for use.</param>
		/// <param name="onStateUpdated">Callback that is triggered when a window state changes.</param>
		public Boolean RegisterLocalRendererEventListener(IRegisterLocalRendererEventListener _iIRegisterLocalRendererEventListener) {
			if (objPtr == IntPtr.Zero) { return default; }
			_mIRegisterLocalRendererEventListener = _iIRegisterLocalRendererEventListener;

			Boolean ret = VidyoEndpointRegisterLocalRendererEventListenerNative(objPtr, _mOnLocalRendererAdded, _mOnLocalRendererRemoved, _mOnLocalRendererSelected, _mOnLocalRendererStateUpdated);

			return ret;
		}
		/// <summary>
		/// Registers to get notified about speaker events. On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="onAdded">Callback that is triggered for every new or existing speaker added.</param>
		/// <param name="onRemoved">Callback that is triggered when the speaker is removed.</param>
		/// <param name="onSelected">Callback that is triggered when a speaker is selected for use.</param>
		/// <param name="onStateUpdated">Callback that is triggered when a speaker state is updated.</param>
		public Boolean RegisterLocalSpeakerEventListener(IRegisterLocalSpeakerEventListener _iIRegisterLocalSpeakerEventListener) {
			if (objPtr == IntPtr.Zero) { return default; }
			_mIRegisterLocalSpeakerEventListener = _iIRegisterLocalSpeakerEventListener;

			Boolean ret = VidyoEndpointRegisterLocalSpeakerEventListenerNative(objPtr, _mOnLocalSpeakerAdded, _mOnLocalSpeakerRemoved, _mOnLocalSpeakerSelected, _mOnLocalSpeakerStateUpdated);

			return ret;
		}
		/// <summary>
		/// Registers to get notified about window events. On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="onAdded">Callback that is triggered for every new or existing window added.</param>
		/// <param name="onRemoved">Callback that is triggered when the window is removed.</param>
		/// <param name="onSelected">Callback that is triggered when a window is selected for use.</param>
		/// <param name="onStateUpdated">Callback that is triggered when a window state changes.</param>
		public Boolean RegisterLocalWindowShareEventListener(IRegisterLocalWindowShareEventListener _iIRegisterLocalWindowShareEventListener) {
			if (objPtr == IntPtr.Zero) { return default; }
			_mIRegisterLocalWindowShareEventListener = _iIRegisterLocalWindowShareEventListener;

			Boolean ret = VidyoEndpointRegisterLocalWindowShareEventListenerNative(objPtr, _mOnLocalWindowShareAdded, _mOnLocalWindowShareRemoved, _mOnLocalWindowShareSelected, _mOnLocalWindowShareStateUpdated);

			return ret;
		}
		/// <summary>
		/// Registers to get notified about window frames. On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="localWindowShare">The VidyoLocalWindowShare for which to receive the frames.</param>
		/// <param name="onFrame">Callback that is triggered for every frame from a window.</param>
		/// <param name="width">Approximate width of the requested frame.</param>
		/// <param name="height">Approximate height of the requested frame.</param>
		/// <param name="frameInterval">Approximate frame interval of the requested frame.</param>
		public Boolean RegisterLocalWindowShareFrameListener(LocalWindowShare localWindowShare, IRegisterLocalWindowShareFrameListener _iIRegisterLocalWindowShareFrameListener, uint width, uint height, ulong frameInterval) {
			if (objPtr == IntPtr.Zero) { return default; }
			_mIRegisterLocalWindowShareFrameListener = _iIRegisterLocalWindowShareFrameListener;

			Boolean ret = VidyoEndpointRegisterLocalWindowShareFrameListenerNative(objPtr, (localWindowShare != null) ? localWindowShare.GetObjectPtr():IntPtr.Zero, _mOnLocalWindowShareFrame, width, height, frameInterval);

			return ret;
		}
		/// <summary>
		/// Registers to get notified about log events.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="onLog">Callback that is triggered for every new log record.</param>
		/// <param name="filter"><p>A space-separated (or comma-separated) sequence of names of log levels, each optionally followed by a category. Categories are separated from levels by the character '@'.</p> <p>Either a level or category may be specified as 'all' or '*' (interchangeably), meaning all levels or categories. A level specified without a category is equivalent to a level@*.</p> <p>The levels are: 'fatal', 'error', 'warning', 'info', 'debug', 'sent', 'received', 'enter', and 'leave'.</p> <p>The level may be prefixed by '-' or '!' (interchangeably), meaning to remove the given level (or levels, see below) from the given category. The string 'none' is equivalent to '-all'.</p> <p>The first level in the list may be prefixed by '+'. If the first level begins with a '+' or '-'/'!', the string is used to modify the listener's existing levels and 45categories. Otherwise, unless the <code>add</code> parameter is true, the levels and categories specified in the string replace all existing levels and categories for the listener. The leading character '+' may be present before other levels, but is ignored.</p> <p>Unless they are preceded by '=', level names imply other levels as well. In particular, each of the levels 'fatal', 'error', 'warning', 'info', and 'debug' implies the levels higher than it, when specified positively; 'sent' and 'received' always imply each other; and 'enter' and 'leave' always imply each other.</p> <p>See VidyoEndpointGetLogCategories for determining the names and descriptions of registered categories.</p> <p>Level names are case-insensitive; category names are case-sensitive.</p> <p>Example: "all" - all levels, all categories.</p> <p>Example: "all -enter" - all categories, all levels but enter and leave.</p> <p>Example: "*@VidyoClient" - all levels for the VidyoClient category.</p> <p>Example: "-*@VidyoClient" - remove all levels from the VidyoClient category.</p> <p>Example: "debug" - all categories, fatal, error, warning, info, and debug levels.</p> <p>Example: "=debug" - all categories, debug level only.</p> <p>Example: "all -=enter" - all categories, all levels but enter (leave is still included).</p> <p>Example: "error@VidyoClient" - fatal and error only for the VidyoClient category.</p> <p>Example: "warning debug@VidyoClient" - fatal, error, and warning for all categories; additionally, info and debug for the VidyoClient category.</p></param>
		public Boolean RegisterLogEventListener(IRegisterLogEventListener _iIRegisterLogEventListener, String filter) {
			if (objPtr == IntPtr.Zero) { return default; }
			_mIRegisterLogEventListener = _iIRegisterLogEventListener;

			IntPtr nFilter = MarshalPtrToUtf8.GetInstance().MarshalManagedToNative(filter ?? string.Empty);
			Boolean ret = VidyoEndpointRegisterLogEventListenerNative(objPtr, _mOnLog, nFilter);
			Marshal.FreeHGlobal(nFilter);

			return ret;
		}
		/// <summary>
		/// This is a synchronous interface. Register a callback to receive the final response for the Next Generation Renderer action.
		/// </summary>
		/// <param name="e">VidyoEndpoint object.</param>
		/// <param name="onNGRResult">Callback to be triggered upon receive the final response from next generation renderer library.</param>
		public Boolean RegisterNGRResultEventListener(IRegisterNGRResultEventListener _iIRegisterNGRResultEventListener) {
			if (objPtr == IntPtr.Zero) { return default; }
			_mIRegisterNGRResultEventListener = _iIRegisterNGRResultEventListener;

			Boolean ret = VidyoEndpointRegisterNGRResultEventListenerNative(objPtr, _mOnNGRResult);

			return ret;
		}
		/// <summary>
		/// Registers to get notified about network interface events.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="onAdded">Callback that is triggered for every new or existing network interface added.</param>
		/// <param name="onRemoved">Callback that is triggered when the network interface is removed.</param>
		/// <param name="onSelected">Callback that is triggered when a network interface is selected for use.</param>
		/// <param name="onStateUpdated">Callback that is triggered when a network interface state changes.</param>
		public Boolean RegisterNetworkInterfaceEventListener(IRegisterNetworkInterfaceEventListener _iIRegisterNetworkInterfaceEventListener) {
			if (objPtr == IntPtr.Zero) { return default; }
			_mIRegisterNetworkInterfaceEventListener = _iIRegisterNetworkInterfaceEventListener;

			Boolean ret = VidyoEndpointRegisterNetworkInterfaceEventListenerNative(objPtr, _mOnNetworkInterfaceAdded, _mOnNetworkInterfaceRemoved, _mOnNetworkInterfaceSelected, _mOnNetworkInterfaceStateUpdated);

			return ret;
		}
		/// <summary>
		/// Registers plugin.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="plugin">Plugin to register.</param>
		public ulong RegisterPlugin(ulong plugin) {
			if (objPtr == IntPtr.Zero) { return default; }

			ulong ret = VidyoEndpointRegisterPluginNative(objPtr, plugin);

			return ret;
		}
		/// <summary>
		/// Registers to get notified about reconnecting events. Note: You should not perform long action in the callbacks.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="onReconnecting">Callback that is triggered each time the new attempt to reconnect will be started.</param>
		/// <param name="onReconnected">Callback that is triggered when reconnecting was successful.</param>
		/// <param name="onConferenceLost">Callback that is triggered when reconnecting failed.</param>
		public Boolean RegisterReconnectEventListener(IRegisterReconnectEventListener _iIRegisterReconnectEventListener) {
			if (objPtr == IntPtr.Zero) { return default; }
			_mIRegisterReconnectEventListener = _iIRegisterReconnectEventListener;

			Boolean ret = VidyoEndpointRegisterReconnectEventListenerNative(objPtr, _mOnReconnecting, _mOnReconnected, _mOnConferenceLost);

			return ret;
		}
		/// <summary>
		/// Registers to get notified about camera events from other participants.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="onAdded">Callback that is triggered when another participant adds a camera into a conference.</param>
		/// <param name="onRemoved">Callback that is triggered when another participant removes a camera from a conference.</param>
		/// <param name="onStateUpdated">Callback that is triggered when another participant updates a camera state in a conference.</param>
		public Boolean RegisterRemoteCameraEventListener(IRegisterRemoteCameraEventListener _iIRegisterRemoteCameraEventListener) {
			if (objPtr == IntPtr.Zero) { return default; }
			_mIRegisterRemoteCameraEventListener = _iIRegisterRemoteCameraEventListener;

			Boolean ret = VidyoEndpointRegisterRemoteCameraEventListenerNative(objPtr, _mOnRemoteCameraAdded, _mOnRemoteCameraRemoved, _mOnRemoteCameraStateUpdated);

			return ret;
		}
		/// <summary>
		/// Registers to get notified about camera frames from other participants.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="remoteCamera">The VidyoRemoteCamera for which to receive the frames.</param>
		/// <param name="onFrame">Callback that is triggered for every frame from a remote camera.</param>
		/// <param name="width">Approximate width of the requested frame.</param>
		/// <param name="height">Approximate height of the requested frame.</param>
		/// <param name="frameInterval">Approximate frame interval of the requested frame.</param>
		public Boolean RegisterRemoteCameraFrameListener(RemoteCamera remoteCamera, IRegisterRemoteCameraFrameListener _iIRegisterRemoteCameraFrameListener, uint width, uint height, ulong frameInterval) {
			if (objPtr == IntPtr.Zero) { return default; }
			_mIRegisterRemoteCameraFrameListener = _iIRegisterRemoteCameraFrameListener;

			Boolean ret = VidyoEndpointRegisterRemoteCameraFrameListenerNative(objPtr, (remoteCamera != null) ? remoteCamera.GetObjectPtr():IntPtr.Zero, _mOnRemoteCameraFrame, width, height, frameInterval);

			return ret;
		}
		/// <summary>
		/// Registers to get notified about microphone energies from other participants.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="onEnergy">Callback that is triggered for every frame with energy from a remote microphone.</param>
		public Boolean RegisterRemoteMicrophoneEnergyListener(IRegisterRemoteMicrophoneEnergyListener _iIRegisterRemoteMicrophoneEnergyListener) {
			if (objPtr == IntPtr.Zero) { return default; }
			_mIRegisterRemoteMicrophoneEnergyListener = _iIRegisterRemoteMicrophoneEnergyListener;

			Boolean ret = VidyoEndpointRegisterRemoteMicrophoneEnergyListenerNative(objPtr, _mOnRemoteMicrophoneEnergy);

			return ret;
		}
		/// <summary>
		/// Registers to get notified about microphone events from other participants.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="onAdded">Callback that is triggered when another participant adds a microphone into a conference.</param>
		/// <param name="onRemoved">Callback that is triggered when another participant removes a microphone from a conference.</param>
		/// <param name="onStateUpdated">Callback that is triggered when another participant updates a microphone state in a conference.</param>
		public Boolean RegisterRemoteMicrophoneEventListener(IRegisterRemoteMicrophoneEventListener _iIRegisterRemoteMicrophoneEventListener) {
			if (objPtr == IntPtr.Zero) { return default; }
			_mIRegisterRemoteMicrophoneEventListener = _iIRegisterRemoteMicrophoneEventListener;

			Boolean ret = VidyoEndpointRegisterRemoteMicrophoneEventListenerNative(objPtr, _mOnRemoteMicrophoneAdded, _mOnRemoteMicrophoneRemoved, _mOnRemoteMicrophoneStateUpdated);

			return ret;
		}
		/// <summary>
		/// Registers to get notified about microphone frames from other participants.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="remoteMicrophone">The VidyoRemoteMicrophone for which to receive the frames.</param>
		/// <param name="onFrame">Callback that is triggered for every frame from a remote microphone.</param>
		public Boolean RegisterRemoteMicrophoneFrameListener(RemoteMicrophone remoteMicrophone, IRegisterRemoteMicrophoneFrameListener _iIRegisterRemoteMicrophoneFrameListener) {
			if (objPtr == IntPtr.Zero) { return default; }
			_mIRegisterRemoteMicrophoneFrameListener = _iIRegisterRemoteMicrophoneFrameListener;

			Boolean ret = VidyoEndpointRegisterRemoteMicrophoneFrameListenerNative(objPtr, (remoteMicrophone != null) ? remoteMicrophone.GetObjectPtr():IntPtr.Zero, _mOnRemoteMicrophoneFrame);

			return ret;
		}
		/// <summary>
		/// Registers to get notified about renderer events.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="onAdded">.</param>
		/// <param name="onRemoved"></param>
		/// <param name="onStateUpdated"></param>
		public Boolean RegisterRemoteRendererEventListener(IRegisterRemoteRendererEventListener _iIRegisterRemoteRendererEventListener) {
			if (objPtr == IntPtr.Zero) { return default; }
			_mIRegisterRemoteRendererEventListener = _iIRegisterRemoteRendererEventListener;

			Boolean ret = VidyoEndpointRegisterRemoteRendererEventListenerNative(objPtr, _mOnRemoteRendererAdded, _mOnRemoteRendererRemoved, _mOnRemoteRendererStateUpdated);

			return ret;
		}
		/// <summary>
		/// Registers to get notified about speaker events.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="onAdded">Callback that is triggered for every new or existing window added.</param>
		/// <param name="onRemoved">Callback that is triggered when the window is removed.</param>
		/// <param name="onStateUpdated"></param>
		public Boolean RegisterRemoteSpeakerEventListener(IRegisterRemoteSpeakerEventListener _iIRegisterRemoteSpeakerEventListener) {
			if (objPtr == IntPtr.Zero) { return default; }
			_mIRegisterRemoteSpeakerEventListener = _iIRegisterRemoteSpeakerEventListener;

			Boolean ret = VidyoEndpointRegisterRemoteSpeakerEventListenerNative(objPtr, _mOnRemoteSpeakerAdded, _mOnRemoteSpeakerRemoved, _mOnRemoteSpeakerStateUpdated);

			return ret;
		}
		/// <summary>
		/// Registers to get notified about window-shares from other participants.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="onAdded">Callback that is triggered when another participant adds a window-share into a conference.</param>
		/// <param name="onRemoved">Callback that is triggered when another participant removes a window-share from a conference.</param>
		/// <param name="onStateUpdated">Callback that is triggered when another participant updates a window-share state in a conference.</param>
		public Boolean RegisterRemoteWindowShareEventListener(IRegisterRemoteWindowShareEventListener _iIRegisterRemoteWindowShareEventListener) {
			if (objPtr == IntPtr.Zero) { return default; }
			_mIRegisterRemoteWindowShareEventListener = _iIRegisterRemoteWindowShareEventListener;

			Boolean ret = VidyoEndpointRegisterRemoteWindowShareEventListenerNative(objPtr, _mOnRemoteWindowShareAdded, _mOnRemoteWindowShareRemoved, _mOnRemoteWindowShareStateUpdated);

			return ret;
		}
		/// <summary>
		/// Registers to get notified about window-share frames from other participants.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="remoteWindowShare">The VidyoRemoteWindowShare for which to receive the frames.</param>
		/// <param name="onFrame">Callback that is triggered for every frame from a remote window share.</param>
		/// <param name="width">Approximate width of the requested frame.</param>
		/// <param name="height">Approximate height of the requested frame.</param>
		/// <param name="frameInterval">Approximate frame interval of the requested frame.</param>
		public Boolean RegisterRemoteWindowShareFrameListener(RemoteWindowShare remoteWindowShare, IRegisterRemoteWindowShareFrameListener _iIRegisterRemoteWindowShareFrameListener, uint width, uint height, ulong frameInterval) {
			if (objPtr == IntPtr.Zero) { return default; }
			_mIRegisterRemoteWindowShareFrameListener = _iIRegisterRemoteWindowShareFrameListener;

			Boolean ret = VidyoEndpointRegisterRemoteWindowShareFrameListenerNative(objPtr, (remoteWindowShare != null) ? remoteWindowShare.GetObjectPtr():IntPtr.Zero, _mOnRemoteWindowShareFrame, width, height, frameInterval);

			return ret;
		}
		/// <summary>
		/// Registers to get notified about virtual audio source events. This is a synchronous interface.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="onAdded">Callback that is triggered each time when virtual audio source is created.</param>
		/// <param name="onRemoved">Callback that is triggered each time when virtual audio source is removed.</param>
		/// <param name="onStateUpdated">Callback that is triggered each time when virtual audio source chagnes state.</param>
		/// <param name="onSelected">Callback that is triggered each time when virtual audio source is selected.</param>
		/// <param name="onExternalMediaBufferReleased">Callback that is triggered each time when VidyoClient is done with an application allocated buffer that holds raw audio frame data.</param>
		public Boolean RegisterVirtualAudioSourceEventListener(IRegisterVirtualAudioSourceEventListener _iIRegisterVirtualAudioSourceEventListener) {
			if (objPtr == IntPtr.Zero) { return default; }
			_mIRegisterVirtualAudioSourceEventListener = _iIRegisterVirtualAudioSourceEventListener;

			Boolean ret = VidyoEndpointRegisterVirtualAudioSourceEventListenerNative(objPtr, _mOnVirtualAudioSourceAdded, _mOnVirtualAudioSourceRemoved, _mOnVirtualAudioSourceStateUpdated, _mOnVirtualAudioSourceSelected, _mOnVirtualAudioSourceExternalMediaBufferReleased);

			return ret;
		}
		/// <summary>
		/// Registers to get notified about virtual video source events. On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="onAdded">Callback that is triggered for every new virtual video source added.</param>
		/// <param name="onRemoved">Callback that is triggered when the virtual video source is removed.</param>
		/// <param name="onStateUpdated">Callback that is triggered when a virtual video source state changes.</param>
		/// <param name="onExternalMediaBufferReleased">Callback that is triggered each time when VidyoClient is done with an application allocated buffer that holds raw video frame.</param>
		public Boolean RegisterVirtualVideoSourceEventListener(IRegisterVirtualVideoSourceEventListener _iIRegisterVirtualVideoSourceEventListener) {
			if (objPtr == IntPtr.Zero) { return default; }
			_mIRegisterVirtualVideoSourceEventListener = _iIRegisterVirtualVideoSourceEventListener;

			Boolean ret = VidyoEndpointRegisterVirtualVideoSourceEventListenerNative(objPtr, _mOnVirtualVideoSourceAdded, _mOnVirtualVideoSourceRemoved, _mOnVirtualVideoSourceStateUpdated, _mOnVirtualVideoSourceExternalMediaBufferReleased);

			return ret;
		}
		/// <summary>
		/// Removes audio device from whitelist.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="deviceName">The name of audio device that will be removed from whitelist.</param>
		public Boolean RemoveAudioDeviceFromWhitelist(String deviceName) {
			if (objPtr == IntPtr.Zero) { return default; }

			IntPtr nDeviceName = MarshalPtrToUtf8.GetInstance().MarshalManagedToNative(deviceName ?? string.Empty);
			Boolean ret = VidyoEndpointRemoveAudioDeviceFromWhitelistNative(objPtr, nDeviceName);
			Marshal.FreeHGlobal(nDeviceName);

			return ret;
		}
		/// <summary>
		/// 
		/// </summary>
		/// <param name="e"></param>
		/// <param name="localRenderer"></param>
		public void RemoveRenderer(LocalRenderer localRenderer) {
			if (objPtr == IntPtr.Zero) { return; }

			VidyoEndpointRemoveRendererNative(objPtr, (localRenderer != null) ? localRenderer.GetObjectPtr():IntPtr.Zero);
		}
		/// <summary>
		/// Request to resume sending video after sever paused video stream from selected local camera. Will resume both local and remote streams and show preview in case it is on. Allowed only in case of soft mute. On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		public Boolean RequestToResumeVideo() {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointRequestToResumeVideoNative(objPtr);

			return ret;
		}
		/// <summary>
		/// Request to speak after sever paused audio stream from selected local microphone. On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		public Boolean RequestToSpeak() {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointRequestToSpeakNative(objPtr);

			return ret;
		}
		/// <summary>
		/// Requests video for remote camera before assign.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="remoteCamera">The VidyoRemoteCamera for which to receive the video.</param>
		/// <param name="width">Approximate width of the requested video.</param>
		/// <param name="height">Approximate height of the requested video.</param>
		/// <param name="frameInterval">Approximate frame interval of the requested video.</param>
		/// <param name="onFirstFrameReceived">Callback that is triggered when first frame from a remote camera received.</param>
		public Boolean RequestVideoForRemoteCamera(RemoteCamera remoteCamera, uint width, uint height, ulong frameInterval, IRequestVideoForRemoteCamera _iIRequestVideoForRemoteCamera) {
			if (objPtr == IntPtr.Zero) { return default; }
			if(remoteCamera != null)
				onRemoteCameraFirstFrameReceivedCallbacksMap[remoteCamera.GetId()] =_iIRequestVideoForRemoteCamera;

			Boolean ret = VidyoEndpointRequestVideoForRemoteCameraNative(objPtr, (remoteCamera != null) ? remoteCamera.GetObjectPtr():IntPtr.Zero, width, height, frameInterval, _mOnRemoteCameraFirstFrameReceived);

			return ret;
		}
		/// <summary>
		/// Requests video for remote window share before assign.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="remoteWindowShare">The VidyoRemoteWindowShare for which to receive the video.</param>
		/// <param name="width">Approximate width of the requested video.</param>
		/// <param name="height">Approximate height of the requested video.</param>
		/// <param name="frameInterval">Approximate frame interval of the requested video.</param>
		/// <param name="onFirstFrameReceived">Callback that is triggered when first frame from a remote window share received.</param>
		public Boolean RequestVideoForRemoteWindowShare(RemoteWindowShare remoteWindowShare, uint width, uint height, ulong frameInterval, IRequestVideoForRemoteWindowShare _iIRequestVideoForRemoteWindowShare) {
			if (objPtr == IntPtr.Zero) { return default; }
			if(remoteWindowShare != null)
				onRemoteWindowShareFirstFrameReceivedCallbacksMap[remoteWindowShare.GetId()] =_iIRequestVideoForRemoteWindowShare;

			Boolean ret = VidyoEndpointRequestVideoForRemoteWindowShareNative(objPtr, (remoteWindowShare != null) ? remoteWindowShare.GetObjectPtr():IntPtr.Zero, width, height, frameInterval, _mOnRemoteWindowShareFirstFrameReceived);

			return ret;
		}
		/// <summary>
		/// Selects the microphone to be used for audio content share. On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="localMicrophone">Microphone to be selected for audio content share.</param>
		public Boolean SelectAudioContentShare(LocalMicrophone localMicrophone) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointSelectAudioContentShareNative(objPtr, (localMicrophone != null) ? localMicrophone.GetObjectPtr():IntPtr.Zero);

			return ret;
		}
		/// <summary>
		/// Resets the camera selection to pick the Default camera. On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		public Boolean SelectDefaultCamera() {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointSelectDefaultCameraNative(objPtr);

			return ret;
		}
		/// <summary>
		/// Resets the microphone selection to pick the Default microphone. On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		public Boolean SelectDefaultMicrophone() {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointSelectDefaultMicrophoneNative(objPtr);

			return ret;
		}
		/// <summary>
		/// Selects the default ANY network interface to be used for Media.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		public Boolean SelectDefaultNetworkInterfaceForMedia() {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointSelectDefaultNetworkInterfaceForMediaNative(objPtr);

			return ret;
		}
		/// <summary>
		/// Selects the default ANY network interface to be used for Signaling.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		public Boolean SelectDefaultNetworkInterfaceForSignaling() {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointSelectDefaultNetworkInterfaceForSignalingNative(objPtr);

			return ret;
		}
		/// <summary>
		/// Resets the speaker selection to pick the Default speaker. On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		public Boolean SelectDefaultSpeaker() {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointSelectDefaultSpeakerNative(objPtr);

			return ret;
		}
		/// <summary>
		/// Selects the camera to be used. On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="localCamera">Camera to be selected.</param>
		public Boolean SelectLocalCamera(LocalCamera localCamera) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointSelectLocalCameraNative(objPtr, (localCamera != null) ? localCamera.GetObjectPtr():IntPtr.Zero);

			return ret;
		}
		/// <summary>
		/// Selects the microphone to be used. On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="localMicrophone">Microphone to be selected.</param>
		public Boolean SelectLocalMicrophone(LocalMicrophone localMicrophone) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointSelectLocalMicrophoneNative(objPtr, (localMicrophone != null) ? localMicrophone.GetObjectPtr():IntPtr.Zero);

			return ret;
		}
		/// <summary>
		/// Selects the monitor to be used. On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="localMonitor">Monitor to be selected.</param>
		public Boolean SelectLocalMonitor(LocalMonitor localMonitor) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointSelectLocalMonitorNative(objPtr, (localMonitor != null) ? localMonitor.GetObjectPtr():IntPtr.Zero);

			return ret;
		}
		/// <summary>
		/// Selects the local monitor to share in a conference. On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="localMonitor">Monitor to be selected.</param>
		/// <param name="options">A structure that represent the sharing options.</param>
		public Boolean SelectLocalMonitorAdvanced(LocalMonitor localMonitor, EndpointShareOptions options) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointSelectLocalMonitorAdvancedNative(objPtr, (localMonitor != null) ? localMonitor.GetObjectPtr():IntPtr.Zero, (options != null) ? options.GetObjectPtr():IntPtr.Zero);

			return ret;
		}
		/// <summary>
		/// Selects the speaker to be used. On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="localSpeaker">Speaker to be selected.</param>
		public Boolean SelectLocalSpeaker(LocalSpeaker localSpeaker) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointSelectLocalSpeakerNative(objPtr, (localSpeaker != null) ? localSpeaker.GetObjectPtr():IntPtr.Zero);

			return ret;
		}
		/// <summary>
		/// Selects the window to be used. On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="localWindowShare">Window to be selected.</param>
		public Boolean SelectLocalWindowShare(LocalWindowShare localWindowShare) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointSelectLocalWindowShareNative(objPtr, (localWindowShare != null) ? localWindowShare.GetObjectPtr():IntPtr.Zero);

			return ret;
		}
		/// <summary>
		/// Selects the local window to share in a conference. On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="localWindowShare">Window to be selected.</param>
		/// <param name="options">A structure that represent the sharing options.</param>
		public Boolean SelectLocalWindowShareAdvanced(LocalWindowShare localWindowShare, EndpointShareOptions options) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointSelectLocalWindowShareAdvancedNative(objPtr, (localWindowShare != null) ? localWindowShare.GetObjectPtr():IntPtr.Zero, (options != null) ? options.GetObjectPtr():IntPtr.Zero);

			return ret;
		}
		/// <summary>
		/// Selects the network interface to be used for Media.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="networkInterface">Network interface to be selected.</param>
		public Boolean SelectNetworkInterfaceForMedia(NetworkInterface networkInterface) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointSelectNetworkInterfaceForMediaNative(objPtr, (networkInterface != null) ? networkInterface.GetObjectPtr():IntPtr.Zero);

			return ret;
		}
		/// <summary>
		/// Selects the network interface to be used for Signaling.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="networkInterface">Network interface to be selected.</param>
		public Boolean SelectNetworkInterfaceForSignaling(NetworkInterface networkInterface) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointSelectNetworkInterfaceForSignalingNative(objPtr, (networkInterface != null) ? networkInterface.GetObjectPtr():IntPtr.Zero);

			return ret;
		}
		/// <summary>
		/// Selects the camera to be used for video content share. On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="localCamera">Camera to be selected for video content share.</param>
		public Boolean SelectVideoContentShare(LocalCamera localCamera) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointSelectVideoContentShareNative(objPtr, (localCamera != null) ? localCamera.GetObjectPtr():IntPtr.Zero);

			return ret;
		}
		/// <summary>
		/// Selects the virtual audio source which will be used for content share. The selected microphone which currently using for content share will be unselected. This is a synchronous interface. The VidyoEndpointOnVirtualAudioSourceStateUpdated will trigger.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="virtualAudioSource">The virtual audio source that will be used for content share.</param>
		public Boolean SelectVirtualAudioContentShare(VirtualAudioSource virtualAudioSource) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointSelectVirtualAudioContentShareNative(objPtr, (virtualAudioSource != null) ? virtualAudioSource.GetObjectPtr():IntPtr.Zero);

			return ret;
		}
		/// <summary>
		/// Selects the virtual video source that will be shown to remote participants. The real camera will be unselected if it's selected. On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="virtualCamera">The virtual video source that will be shown to remote participants.</param>
		public Boolean SelectVirtualCamera(VirtualVideoSource virtualCamera) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointSelectVirtualCameraNative(objPtr, (virtualCamera != null) ? virtualCamera.GetObjectPtr():IntPtr.Zero);

			return ret;
		}
		/// <summary>
		/// Selects the virtual audio source which will be used as microphone. The real miicrophone will be unselected if it's selected. This is a synchronous interface. The VidyoEndpointOnVirtualAudioSourceStateUpdated will trigger.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="virtualAudioSource">The virtual audio source that will be used as microphone.</param>
		public Boolean SelectVirtualMicrophone(VirtualAudioSource virtualAudioSource) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointSelectVirtualMicrophoneNative(objPtr, (virtualAudioSource != null) ? virtualAudioSource.GetObjectPtr():IntPtr.Zero);

			return ret;
		}
		/// <summary>
		/// Selects the virtual renderer to receive all events required for rendering. On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="renderer">The virtual renderer object to select, NULL to unselect.</param>
		public Boolean SelectVirtualRenderer(VirtualRenderer renderer) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointSelectVirtualRendererNative(objPtr, (renderer != null) ? renderer.GetObjectPtr():IntPtr.Zero);

			return ret;
		}
		/// <summary>
		/// Selects the virtual video source which is window share that will be shown to remote participants. The local window share will be unselected if it's selected. On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="virtualWindowShare">The virtual video source that will be shown to remote participants.</param>
		public Boolean SelectVirtualSourceWindowShare(VirtualVideoSource virtualWindowShare) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointSelectVirtualSourceWindowShareNative(objPtr, (virtualWindowShare != null) ? virtualWindowShare.GetObjectPtr():IntPtr.Zero);

			return ret;
		}
		/// <summary>
		/// Sends already constructed audio frame to selected virtual audio source and then send it to local and/or remote streams. This is a synchronous interface.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="virtualAudioSource">The virtual audio source.</param>
		/// <param name="audioFrame">The audio frame to be sent.</param>
		public Boolean SendVirtualAudioSourceFrame(VirtualAudioSource virtualAudioSource, AudioFrame audioFrame) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointSendVirtualAudioSourceFrameNative(objPtr, (virtualAudioSource != null) ? virtualAudioSource.GetObjectPtr():IntPtr.Zero, (audioFrame != null) ? audioFrame.GetObjectPtr():IntPtr.Zero);

			return ret;
		}
		/// <summary>
		/// Pass raw buffer to selected virtual audio source, based on which the audio frame will be constructed and then send it to local and/or remote streams. This is an asynchronous interface. The VidyoEndpointOnVirtualAudioSourceExternalMediaBufferReleased will trigger when buffer is not needed anymore.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="virtualAudioSource">The virtual audio source.</param>
		/// <param name="buffer">The buffer with audio data to be sent.</param>
		/// <param name="nbSamples">The number of sample frames that will be represented in the audio data.</param>
		/// <param name="elapsedTime">The elapsed time.</param>
		public Boolean SendVirtualAudioSourceFrameWithExternalData(VirtualAudioSource virtualAudioSource, byte[] buffer, SizeT nbSamples, ulong elapsedTime) {
			if (objPtr == IntPtr.Zero) { return default; }

			IntPtr pointer = ByteArrayHelperSingleton.ByteArrayToRawPointer(buffer);
			Boolean ret = VidyoEndpointSendVirtualAudioSourceFrameWithExternalDataNative(objPtr, (virtualAudioSource != null) ? virtualAudioSource.GetObjectPtr():IntPtr.Zero, pointer, nbSamples, elapsedTime);

			return ret;
		}
		/// <summary>
		/// 
		/// </summary>
		/// <param name="e">The endpoint object.</param>
		/// <param name="options">The experimental optons in JSON format.</param>
		public Boolean SetAdvancedOptions(String options) {
			if (objPtr == IntPtr.Zero) { return default; }

			IntPtr nOptions = MarshalPtrToUtf8.GetInstance().MarshalManagedToNative(options ?? string.Empty);
			Boolean ret = VidyoEndpointSetAdvancedOptionsNative(objPtr, nOptions);
			Marshal.FreeHGlobal(nOptions);

			return ret;
		}
		/// <summary>
		/// 
		/// </summary>
		/// <param name="e"></param>
		/// <param name="applicationTag"></param>
		public Boolean SetApplicationTag(String applicationTag) {
			if (objPtr == IntPtr.Zero) { return default; }

			IntPtr nApplicationTag = MarshalPtrToUtf8.GetInstance().MarshalManagedToNative(applicationTag ?? string.Empty);
			Boolean ret = VidyoEndpointSetApplicationTagNative(objPtr, nApplicationTag);
			Marshal.FreeHGlobal(nApplicationTag);

			return ret;
		}
		/// <summary>
		/// Sets multiplier value to be used when calculating the audio bitrate. Default is 2.
		/// </summary>
		/// <param name="e">The endpoint object.</param>
		/// <param name="bitrateMultiplier">Bitrate multiplier for which possible values are 0, 1 and 2.</param>
		public Boolean SetAudioBitrateMultiplier(uint bitrateMultiplier) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointSetAudioBitrateMultiplierNative(objPtr, bitrateMultiplier);

			return ret;
		}
		/// <summary>
		/// Enables or disables usage of audio devices (speaker and microphone) in different audio modes. By default SharedModeBoth is enabled.
		/// </summary>
		/// <param name="e">The endpoint object.</param>
		/// <param name="audioMode">Indicates which audio mode is enabled/disabled for both audio devices. For possible values of the audio mode, refer VidyoEndpointAudioMode.</param>
		public Boolean SetAudioMode(EndpointAudioMode audioMode) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointSetAudioModeNative(objPtr, audioMode);

			return ret;
		}
		/// <summary>
		/// Sets time interval between two packet of audio in miliseconds. Default is 40 ms.
		/// </summary>
		/// <param name="e">The endpoint object.</param>
		/// <param name="packetInterval">Packet interval for which possible values are 20, and 40 ms.</param>
		public Boolean SetAudioPacketInterval(uint packetInterval) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointSetAudioPacketIntervalNative(objPtr, packetInterval);

			return ret;
		}
		/// <summary>
		/// Sets value that is used to configure encoder. If given higher value then encoder is configured to resistant to loss on the expense of quality. Default is 10%.
		/// </summary>
		/// <param name="e">The endpoint object.</param>
		/// <param name="lossPercentage">Loss percantage for which possible values are [0, 10, 20, 30] in percentage.</param>
		public Boolean SetAudioPacketLossPercentage(uint lossPercentage) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointSetAudioPacketLossPercentageNative(objPtr, lossPercentage);

			return ret;
		}
		/// <summary>
		/// Enables or disables auto-reconnect.
		/// </summary>
		/// <param name="e">The endpoint object.</param>
		/// <param name="enable">Indicates whether auto-reconnect is enabled or not.</param>
		public Boolean SetAutoReconnect(Boolean enable) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointSetAutoReconnectNative(objPtr, enable);

			return ret;
		}
		/// <summary>
		/// Sets back off for next reconnect attempt. By default, it is set to 5 seconds.
		/// </summary>
		/// <param name="e">The endpoint object.</param>
		/// <param name="backOff">Time in seconds before next reconnect attempt. Min value is 2 and the max is 20 seconds.</param>
		public Boolean SetAutoReconnectAttemptBackOff(uint backOff) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointSetAutoReconnectAttemptBackOffNative(objPtr, backOff);

			return ret;
		}
		/// <summary>
		/// Sets maximum attempts to be done for reconnecting. By default, it is set to 3.
		/// </summary>
		/// <param name="e">The endpoint object.</param>
		/// <param name="maxAttempts">Number of maximum attempts to be done for reconnecting. Min value is 1 and the max is 4.</param>
		public Boolean SetAutoReconnectMaxAttempts(uint maxAttempts) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointSetAutoReconnectMaxAttemptsNative(objPtr, maxAttempts);

			return ret;
		}
		/// <summary>
		/// Sets the intensity of the background blur effect. It is allowed to change blur intensity while the effect is enabled. This functionality is supported only for macOS 10.14 and above, iOS 10.0 and above and Windows VC++ 15 and above.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="intensity">The intensity of the background blur effect. Valid valies is [3-8]. Default value is 5.</param>
		public Boolean SetBlurIntensity(uint intensity) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointSetBlurIntensityNative(objPtr, intensity);

			return ret;
		}
		/// <summary>
		/// Enables the specified by VidyoEndpointCameraEffectType camera background effect or disables active effect if VIDYO_ENDPOINTCAMERAEFFECTTYPE_None passed. The application must provide token to enable this feature as part of VidyoConnectorCameraEffectInfo structure. This functionality is supported only for macOS 10.14 and above, iOS 10.0 and above and Windows VC++ 15 and above.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="effectInfo">Represents the configuration of camera background effect.</param>
		public Boolean SetCameraBackgroundEffect(EndpointCameraEffectInfo effectInfo) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointSetCameraBackgroundEffectNative(objPtr, (effectInfo != null) ? effectInfo.GetObjectPtr():IntPtr.Zero);

			return ret;
		}
		/// <summary>
		/// Sets camera PTZ nudge configuration.
		/// </summary>
		/// <param name="e">The endpoint object.</param>
		/// <param name="cameraNudgeConfig">Camera PTZ nudge configuration in JSON format.</param>
		public Boolean SetCameraNudgeConfiguration(String cameraNudgeConfig) {
			if (objPtr == IntPtr.Zero) { return default; }

			IntPtr nCameraNudgeConfig = MarshalPtrToUtf8.GetInstance().MarshalManagedToNative(cameraNudgeConfig ?? string.Empty);
			Boolean ret = VidyoEndpointSetCameraNudgeConfigurationNative(objPtr, nCameraNudgeConfig);
			Marshal.FreeHGlobal(nCameraNudgeConfig);

			return ret;
		}
		/// <summary>
		/// Sets the flag to show/hide the local camera for remote participants for composite/custom layout and local camera preview for composite layout only. Will also unmute a soft mute(Hunter only). On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="privacy">Flag to show/hide the camera.</param>
		public Boolean SetCameraPrivacy(Boolean privacy) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointSetCameraPrivacyNative(objPtr, privacy);

			return ret;
		}
		/// <summary>
		/// Sets conference number - a special identifier that will show up in the Portal CDR record for the conference. Should be set before joining the conference.
		/// </summary>
		/// <param name="e">The endpoint object.</param>
		/// <param name="conferenceNumber">Conference number to be set.</param>
		public void SetConferenceNumber(String conferenceNumber) {
			if (objPtr == IntPtr.Zero) { return; }

			IntPtr nConferenceNumber = MarshalPtrToUtf8.GetInstance().MarshalManagedToNative(conferenceNumber ?? string.Empty);
			VidyoEndpointSetConferenceNumberNative(objPtr, nConferenceNumber);
			Marshal.FreeHGlobal(nConferenceNumber);
		}
		/// <summary>
		/// 
		/// </summary>
		/// <param name="e"></param>
		/// <param name="consoleLogFilter"></param>
		public Boolean SetConsoleLoggerFilter(String consoleLogFilter) {
			if (objPtr == IntPtr.Zero) { return default; }

			IntPtr nConsoleLogFilter = MarshalPtrToUtf8.GetInstance().MarshalManagedToNative(consoleLogFilter ?? string.Empty);
			Boolean ret = VidyoEndpointSetConsoleLoggerFilterNative(objPtr, nConsoleLogFilter);
			Marshal.FreeHGlobal(nConsoleLogFilter);

			return ret;
		}
		/// <summary>
		/// 
		/// </summary>
		/// <param name="e"></param>
		/// <param name="levelName"></param>
		/// <param name="categoryName"></param>
		/// <param name="on"></param>
		public Boolean SetConsoleLoggerLevelAndCategory(String levelName, String categoryName, Boolean on) {
			if (objPtr == IntPtr.Zero) { return default; }

			IntPtr nLevelName = MarshalPtrToUtf8.GetInstance().MarshalManagedToNative(levelName ?? string.Empty);
			IntPtr nCategoryName = MarshalPtrToUtf8.GetInstance().MarshalManagedToNative(categoryName ?? string.Empty);
			Boolean ret = VidyoEndpointSetConsoleLoggerLevelAndCategoryNative(objPtr, nLevelName, nCategoryName, on);
			Marshal.FreeHGlobal(nCategoryName);
			Marshal.FreeHGlobal(nLevelName);

			return ret;
		}
		/// <summary>
		/// 
		/// </summary>
		/// <param name="e"></param>
		/// <param name="utc"></param>
		public Boolean SetConsoleLoggerUTC(Boolean utc) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointSetConsoleLoggerUTCNative(objPtr, utc);

			return ret;
		}
		/// <summary>
		/// Set CPU profile for the endpoint.
		/// </summary>
		/// <param name="e">The endpoint object.</param>
		/// <param name="profile">The CPU tradeoff profile.</param>
		public Boolean SetCpuTradeOffProfile(EndpointTradeOffProfile profile) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointSetCpuTradeOffProfileNative(objPtr, profile);

			return ret;
		}
		/// <summary>
		/// 
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="debugLogFilter">Log filter to use on the debug port.</param>
		public Boolean SetDebugFilter(String debugLogFilter) {
			if (objPtr == IntPtr.Zero) { return default; }

			IntPtr nDebugLogFilter = MarshalPtrToUtf8.GetInstance().MarshalManagedToNative(debugLogFilter ?? string.Empty);
			Boolean ret = VidyoEndpointSetDebugFilterNative(objPtr, nDebugLogFilter);
			Marshal.FreeHGlobal(nDebugLogFilter);

			return ret;
		}
		/// <summary>
		/// When enabled, all video feeds (video and content share) will be shut off to the client when the user experiences prolonged low network bandwidth.
		/// </summary>
		/// <param name="e">The endpoint object.</param>
		/// <param name="enable">Indicates whether disable video on low bandwidth is enabled or not.</param>
		public Boolean SetDisableVideoOnLowBandwidth(Boolean enable) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointSetDisableVideoOnLowBandwidthNative(objPtr, enable);

			return ret;
		}
		/// <summary>
		/// Sets number of audio streams requested while video is shut off. By default, it is set to 3.
		/// </summary>
		/// <param name="e">The endpoint object.</param>
		/// <param name="audioStreams">Number of audio streams requested while video is shut off. Min value is 1 and max is 3.</param>
		public Boolean SetDisableVideoOnLowBandwidthAudioStreams(uint audioStreams) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointSetDisableVideoOnLowBandwidthAudioStreamsNative(objPtr, audioStreams);

			return ret;
		}
		/// <summary>
		/// Sets time it takes to recover when video is shut off. By default, it is set to 0 seconds which means never.
		/// </summary>
		/// <param name="e">The endpoint object.</param>
		/// <param name="recoveryTime">Time it takes to recover when video is shut off. Recovery can only happen when there are no available video sources.</param>
		public Boolean SetDisableVideoOnLowBandwidthRecoveryTime(uint recoveryTime) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointSetDisableVideoOnLowBandwidthRecoveryTimeNative(objPtr, recoveryTime);

			return ret;
		}
		/// <summary>
		/// Sets time it takes to shut off video due to low bandwidth. By default, it is set to 30 seconds.
		/// </summary>
		/// <param name="e">The endpoint object.</param>
		/// <param name="responseTime">Time it takes to shut off video due to low bandwidth.</param>
		public Boolean SetDisableVideoOnLowBandwidthResponseTime(uint responseTime) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointSetDisableVideoOnLowBandwidthResponseTimeNative(objPtr, responseTime);

			return ret;
		}
		/// <summary>
		/// Sets how often to check for low bandwidth. By default, it is set to 5 seconds.
		/// </summary>
		/// <param name="e">The endpoint object.</param>
		/// <param name="sampleTime">How often to check for low bandwidth. Must divide evenly into responseTime.</param>
		public Boolean SetDisableVideoOnLowBandwidthSampleTime(uint sampleTime) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointSetDisableVideoOnLowBandwidthSampleTimeNative(objPtr, sampleTime);

			return ret;
		}
		/// <summary>
		/// Sets low bandwidth threshold. By default, it is set to 100kpbs.
		/// </summary>
		/// <param name="e">The endpoint object.</param>
		/// <param name="kbps">Threshold for low bandwidth in kilobits/sec.</param>
		public Boolean SetDisableVideoOnLowBandwidthThreshold(uint kbps) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointSetDisableVideoOnLowBandwidthThresholdNative(objPtr, kbps);

			return ret;
		}
		/// <summary>
		/// 
		/// </summary>
		/// <param name="e"></param>
		/// <param name="logFileFilter"></param>
		public Boolean SetFileLoggerFilter(String logFileFilter) {
			if (objPtr == IntPtr.Zero) { return default; }

			IntPtr nLogFileFilter = MarshalPtrToUtf8.GetInstance().MarshalManagedToNative(logFileFilter ?? string.Empty);
			Boolean ret = VidyoEndpointSetFileLoggerFilterNative(objPtr, nLogFileFilter);
			Marshal.FreeHGlobal(nLogFileFilter);

			return ret;
		}
		/// <summary>
		/// 
		/// </summary>
		/// <param name="e"></param>
		/// <param name="levelName"></param>
		/// <param name="categoryName"></param>
		/// <param name="on"></param>
		public Boolean SetFileLoggerLevelAndCategory(String levelName, String categoryName, Boolean on) {
			if (objPtr == IntPtr.Zero) { return default; }

			IntPtr nLevelName = MarshalPtrToUtf8.GetInstance().MarshalManagedToNative(levelName ?? string.Empty);
			IntPtr nCategoryName = MarshalPtrToUtf8.GetInstance().MarshalManagedToNative(categoryName ?? string.Empty);
			Boolean ret = VidyoEndpointSetFileLoggerLevelAndCategoryNative(objPtr, nLevelName, nCategoryName, on);
			Marshal.FreeHGlobal(nCategoryName);
			Marshal.FreeHGlobal(nLevelName);

			return ret;
		}
		/// <summary>
		/// Sets log file size limit, how often to initiate the wrap and number of log files.
		/// </summary>
		/// <param name="e">The endpoint object.</param>
		/// <param name="maxSize">The number of bytes of logged messages to save.</param>
		/// <param name="wrapPeriod">How often to initiate the wrap in nanoseconds. If this value is LMI_TIME_INFINITE, the log file will not be wrapped based on time.</param>
		/// <param name="wrapCount">The maximum number of files to keep.</param>
		public Boolean SetFileLoggerRotationParameters(SizeT maxSize, ulong wrapPeriod, SizeT wrapCount) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointSetFileLoggerRotationParametersNative(objPtr, maxSize, wrapPeriod, wrapCount);

			return ret;
		}
		/// <summary>
		/// 
		/// </summary>
		/// <param name="e"></param>
		/// <param name="utc"></param>
		public Boolean SetFileLoggerUTC(Boolean utc) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointSetFileLoggerUTCNative(objPtr, utc);

			return ret;
		}
		/// <summary>
		/// Set font file name. On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e"></param>
		/// <param name="fontFileName">Pointer to char array that contains font file name.</param>
		public Boolean SetFontFileName(String fontFileName) {
			if (objPtr == IntPtr.Zero) { return default; }

			IntPtr nFontFileName = MarshalPtrToUtf8.GetInstance().MarshalManagedToNative(fontFileName ?? string.Empty);
			Boolean ret = VidyoEndpointSetFontFileNameNative(objPtr, nFontFileName);
			Marshal.FreeHGlobal(nFontFileName);

			return ret;
		}
		/// <summary>
		/// Set the license key of the endpoint.
		/// </summary>
		/// <param name="e">The endpoint object.</param>
		/// <param name="licenseKey">The lincense key for the endpoint</param>
		public Boolean SetLicenseKey(String licenseKey) {
			if (objPtr == IntPtr.Zero) { return default; }

			IntPtr nLicenseKey = MarshalPtrToUtf8.GetInstance().MarshalManagedToNative(licenseKey ?? string.Empty);
			Boolean ret = VidyoEndpointSetLicenseKeyNative(objPtr, nLicenseKey);
			Marshal.FreeHGlobal(nLicenseKey);

			return ret;
		}
		/// <summary>
		/// 
		/// </summary>
		/// <param name="e"></param>
		/// <param name="latitude"></param>
		/// <param name="longitude"></param>
		public Boolean SetLocation(double latitude, double longitude) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointSetLocationNative(objPtr, latitude, longitude);

			return ret;
		}
		/// <summary>
		/// Sets new path to log file.
		/// </summary>
		/// <param name="e">The endpoint object.</param>
		/// <param name="filename">The name of the file to log to. Note: Can be passed just filename or with full path so that location will be changed.</param>
		public Boolean SetLogFilePath(String filename) {
			if (objPtr == IntPtr.Zero) { return default; }

			IntPtr nFilename = MarshalPtrToUtf8.GetInstance().MarshalManagedToNative(filename ?? string.Empty);
			Boolean ret = VidyoEndpointSetLogFilePathNative(objPtr, nFilename);
			Marshal.FreeHGlobal(nFilename);

			return ret;
		}
		/// <summary>
		/// Request server to limit bit rate sent to this client.
		/// </summary>
		/// <param name="e">The endpoint object.</param>
		/// <param name="bitRate">The maximum receiving bit rate request sent to server, in bps.</param>
		public void SetMaxReceiveBitRate(uint bitRate) {
			if (objPtr == IntPtr.Zero) { return; }

			VidyoEndpointSetMaxReceiveBitRateNative(objPtr, bitRate);
		}
		/// <summary>
		/// Sets the max send bit rate for all sources.
		/// </summary>
		/// <param name="e">The endpoint object.</param>
		/// <param name="bitRate">The max send bit rate for all sources, in bps.</param>
		public void SetMaxSendBitRate(uint bitRate) {
			if (objPtr == IntPtr.Zero) { return; }

			VidyoEndpointSetMaxSendBitRateNative(objPtr, bitRate);
		}
		/// <summary>
		/// Sets max boost level that will be applied only in the conference for the selected microphone in case the system is set to the higher value.
		/// </summary>
		/// <param name="e">The endpoint object.</param>
		/// <param name="boostLevel">Boost level for which possible values are devices specific, e.g. 0 - 20 dB. Default is 12 dB.</param>
		public void SetMicrophoneMaxBoostLevel(double boostLevel) {
			if (objPtr == IntPtr.Zero) { return; }

			VidyoEndpointSetMicrophoneMaxBoostLevelNative(objPtr, boostLevel);
		}
		/// <summary>
		/// Sets the flag to mute/unmute the microphone. On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="privacy">Flag to mute/unmute the microphone.</param>
		public Boolean SetMicrophonePrivacy(Boolean privacy) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointSetMicrophonePrivacyNative(objPtr, privacy);

			return ret;
		}
		/// <summary>
		/// Sets min volume that will be applied only in the conference for the selected microphone in case the system is set to the lower value.
		/// </summary>
		/// <param name="e">The endpoint object.</param>
		/// <param name="volumePercent">Volume percent for which possible values are 0 - 100 percentage. Default is 50 percent.</param>
		public void SetMinMicrophoneVolume(uint volumePercent) {
			if (objPtr == IntPtr.Zero) { return; }

			VidyoEndpointSetMinMicrophoneVolumeNative(objPtr, volumePercent);
		}
		/// <summary>
		/// Sets the operating mode of the VidyoEndpoint. This API have to be called before renderer is destructed: i.e. VidyoEndpointHideView will be called in case VIDYO_ENDPOINTMODE_Background and after renderer is constructed: i.e. VidyoEndpointAssignViewToCompositeRenderer, VidyoEndpointAssignViewToLocalCamera, VidyoEndpointAssignViewToRemoteCamera will be called in case VIDYO_ENDPOINTMODE_Foreground. This API is required only when user in the conference. On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="mode">Desired operating mode.</param>
		public Boolean SetMode(EndpointMode mode) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointSetModeNative(objPtr, mode);

			return ret;
		}
		/// <summary>
		/// 
		/// </summary>
		/// <param name="e">The endpoint object.</param>
		/// <param name="options">The options in JSON format. <p>conferenceReferenceNumber - a special identifier that will show up in the Portal CDR record for the conference. Should be set before joining the conference.</p> <p>Example: {'conferenceReferenceNumber' : 'reference number'}.</p> <p>microphoneMaxBoostLevel - sets max boost level that will be applied only in the conference for the selected microphone in case the system is set to the higher value. Possible values are devices specific, e.g. 0 - 20 dB. Default is 12 dB.</p> <p>Example: {'microphoneMaxBoostLevel' : 10}.</p> <p>minMicrophoneVolume - sets min volume that will be applied only in the conference for the selected microphone in case the system is set to the lower value. Possible values are 0 - 100 percentage. Default is 50 per cent.</p> <p>Example: {'minMicrophoneVolume' : 70}.</p> <p>Possible values for audio device modes are audioSharedModeBoth - use both audio devices (Speaker and Microphone) in shared mode. audioExclusiveModeBoth - use both audio devices (Speaker and Microphone) in exclusive mode. audioExclusiveModeMic - use microphone in exclusive mode and speaker in shared mode. By default VidyoClient is working with audioSharedModeBoth. A new mode will be applied only for the next conference or in case another device is selected.</p> <p>Example: {'audioSharedModeBoth' : true}.</p> <p>Example: {'audioExclusiveModeBoth' : true}.</p> <p>Example: {'audioExclusiveModeMic' : true}.</p> <p>preferredAudioCodec - sets VidyoClient to use preferred audio codec. Possible value are OPUS RED, OPUS and SPEEX RED. Default is OPUS RED.</p> <p>Example: {'preferredAudioCodec' : 'SPEEX RED'}.</p> <p>AudioBitrateMultiplier - A multiplier to be used when calculating the audio bitrate. Possible values are 0,1, and 2. Default is 2.</p> <p>Example: {'AudioBitrateMultiplier':1}.</p> <p>AudioPacketInterval - It decies audio frame duration to encoder. It sets time interval between two packet of audio in miliseconds Possible values are 20, and 40 ms. Default is 40 ms.</p> <p>Example: {'AudioPacketInterval':40}.</p> <p>AudioPacketLossPercentage - it values is used to configure encoder. If given higher value then encoder is configured to resistant to loss on the expense of quality. Possible values are [0, 10, 20, 30] in percentage. Default is 10%.</p> <p>Example: {'AudioPacketLossPercentage':20}.</p> <p>statRate - sets VidyoRoom statistics gather interval in seconds. Possible values are 2, 5, 10, 20 and 30. Default is 10.</p> <p>Example: {'statRate':10}.</p> <p>enableStaticShareSvc - Specifies whether SVC will be enabled or disabled for static sharing. Possible values are true or false. The default is false. Note: SVC is enabled by default for interactive video and high frame rate sharing.</p> <p>Example: {'enableStaticShareSvc' : true}.</p></param>
		public Boolean SetOptions(String options) {
			if (objPtr == IntPtr.Zero) { return default; }

			IntPtr nOptions = MarshalPtrToUtf8.GetInstance().MarshalManagedToNative(options ?? string.Empty);
			Boolean ret = VidyoEndpointSetOptionsNative(objPtr, nOptions);
			Marshal.FreeHGlobal(nOptions);

			return ret;
		}
		/// <summary>
		/// 
		/// </summary>
		/// <param name="e"></param>
		/// <param name="name"></param>
		public Boolean SetPool(String name) {
			if (objPtr == IntPtr.Zero) { return default; }

			IntPtr nName = MarshalPtrToUtf8.GetInstance().MarshalManagedToNative(name ?? string.Empty);
			Boolean ret = VidyoEndpointSetPoolNative(objPtr, nName);
			Marshal.FreeHGlobal(nName);

			return ret;
		}
		/// <summary>
		/// Set the product information of the endpoint.
		/// </summary>
		/// <param name="e">The endpoint object.</param>
		/// <param name="productInfo">The product info of the endpoint</param>
		/// <param name="supportedFeature">The features this endpoint can support</param>
		public Boolean SetProductInfo(List<Property> productInfo, List<Property> supportedFeature) {
			if (objPtr == IntPtr.Zero) { return default; }

			IntPtr nListProductInfo = VidyoEndpointVectorVidyoPropertyAllocateNative();

			IntPtr nListSupportedFeature = VidyoEndpointVectorVidyoPropertyAllocateNative();

			IntPtr nProductInfo = Marshal.AllocHGlobal(Marshal.SizeOf<IntPtr>() * productInfo.Count);
			int nProductInfoSize = 0;
			foreach (Property iter in productInfo) {
				Marshal.WriteIntPtr(nProductInfo + (nProductInfoSize * Marshal.SizeOf<IntPtr>()), iter.GetObjectPtr());
				nProductInfoSize++;
			}
			VidyoEndpointSetProductInfoSetproductInfoArrayNative(nListProductInfo, nProductInfo, nProductInfoSize);
			Marshal.FreeHGlobal(nProductInfo);
			IntPtr nSupportedFeature = Marshal.AllocHGlobal(Marshal.SizeOf<IntPtr>() * supportedFeature.Count);
			int nSupportedFeatureSize = 0;
			foreach (Property iter in supportedFeature) {
				Marshal.WriteIntPtr(nSupportedFeature + (nSupportedFeatureSize * Marshal.SizeOf<IntPtr>()), iter.GetObjectPtr());
				nSupportedFeatureSize++;
			}
			VidyoEndpointSetProductInfoSetsupportedFeatureArrayNative(nListSupportedFeature, nSupportedFeature, nSupportedFeatureSize);
			Marshal.FreeHGlobal(nSupportedFeature);
			Boolean ret = VidyoEndpointSetProductInfoNative(objPtr, nListProductInfo, nListSupportedFeature);
			VidyoEndpointVectorVidyoPropertyDeallocateNative(nListSupportedFeature);
			VidyoEndpointVectorVidyoPropertyDeallocateNative(nListProductInfo);

			return ret;
		}
		/// <summary>
		/// Tell the library to send the raw chat messages to the application.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="receiveRawMessage">Set it to LMI_TRUE to receive raw message with header, LMI_FALSE to reseive only the message body.</param>
		public Boolean SetReceiveRawMessage(Boolean receiveRawMessage) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointSetReceiveRawMessageNative(objPtr, receiveRawMessage);

			return ret;
		}
		/// <summary>
		/// Sets up the local renderer and conference tiles displaying options.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="viewId">A platform-specific view ID.</param>
		/// <param name="options">A char array that contains options in the JSON format. <p>EnableVerticalVideoCentering - Enable or disable the vertical centering of the video screen. Default is true.</p> <p>Example: {'EnableVerticalVideoCentering':true}.</p> <p>EnableFECCIconCustomLayout - Enable or disable the displaying of custom FECC icon in the right bottom corner. Default is false.</p> <p>Example: {'EnableFECCIconCustomLayout':false}.</p> <p>ViewingDistance - Sets viewing distance in feet. Default is 2.5f. Minimum and Maximum values are 1f & 15f respectively.</p> <p>Example: {'ViewingDistance':2.5}.</p> <p>ShowAudioTiles - Enable or disable the showing of audio tiles. Default is true.</p> <p>Example: {'ShowAudioTiles':false}.</p> <p>SetPipPosition - Sets the position of the preview when it is displayed using picture-in-picture mode. Possible values for x: "PipPositionLeft", "PipPositionCenter", "PipPositionRight". Possible values for y: "PipPositionBottom", "PipPositionCenter", "PipPositionTop". lockPip is a boolean indicating whether to lock the preview in this position (by default is false). When false, the user may drag the preview to another location using the mouse or a touch. setPipSize - Sets the size of the preview in picture-in-picture mode. The value is a positive integer representing the percentage of the screen size (1 to 50) default is 1. setPipToTileAfterNTiles - Sets the number of tiles after which the preview will be displayed as a tile instead of picture-in-picture (default value is 2). A value of 0 means the preview will always be visible in picture-in-picture mode whereas N means that the preview will be visible as tile if the number of tiles is greater than N (where N is a positive integer).</p> <p>Example: {'SetPipPosition':{'x':'PipPositionRight', 'y': 'PipPositionTop', 'lockPip':true, 'setPipSize':1, 'setPipToTileAfterNTiles':2}}.</p> <p>SetPixelDensity - Sets the rendering environment's pixel density.</p> <p>Example: {'SetPixelDensity':326.0f. However for latest rendering environment, being released for iOS only, this option is used to choose surface density with possible values as 0.5 (everything will be smaller) / 1.0 (default) / 2.0 (everything will be larger).}</p> <p>SetTouchAsInputDevice - Enable or disable touch as a input device. Default is false.</p> <p>Example: {'SetTouchAsInputDevice':false}.</p> <p>EnableExpandedCameraControl - Enable or disable expanded camera control. Default is true for mobile devices and false for non-mobile devices.</p> <p>Example: {'EnableExpandedCameraControl':false}.</p> <p>BorderStyle - Sets the border style of the preview. None: Do not put a border on any tiles. Same: Put the same colored border on each tile. Highlight: Put a border on each tile, but tiles associated with the highest ranked participant will have a different colored border than the others. Flash: Tiles associated with the highest ranked participant have a different colored border than the others. When the highest ranked participant changes, the border of the new highest ranked participant flashes momentarily. Possible values for BorderStyle: "None", "Same", "Highlight", "Flash"</p> <p>Example: {'BorderStyle':'Same'</p>} <p>enablePreviewMirroring - Specifies whether mirroring will be enabled or disabled for local cameras. Possible values are true or false. The default is true.</p> <p>Example: {'EnablePreviewMirroring' : true}.</p></param>
		public Boolean SetRendererOptionsForViewId(IntPtr viewId, String options) {
			if (objPtr == IntPtr.Zero) { return default; }

			IntPtr nOptions = MarshalPtrToUtf8.GetInstance().MarshalManagedToNative(options ?? string.Empty);
			Boolean ret = VidyoEndpointSetRendererOptionsForViewIdNative(objPtr, ref viewId, nOptions);
			Marshal.FreeHGlobal(nOptions);

			return ret;
		}
		/// <summary>
		/// Sets the flag to mute/unmute the speaker. On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="privacy">Flag to mute/unmute the speaker.</param>
		public Boolean SetSpeakerPrivacy(Boolean privacy) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointSetSpeakerPrivacyNative(objPtr, privacy);

			return ret;
		}
		/// <summary>
		/// Enables or disables SVC. The default is false. Note: SVC is enabled by default for interactive video and high frame rate sharing.
		/// </summary>
		/// <param name="e">The endpoint object.</param>
		/// <param name="enable">Indicates whether enable SVC or not.</param>
		public Boolean SetStaticShareSvcState(Boolean enable) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointSetStaticShareSvcStateNative(objPtr, enable);

			return ret;
		}
		/// <summary>
		/// Sets conference room statistics gather interval in seconds. Default is 10.
		/// </summary>
		/// <param name="e">The endpoint object.</param>
		/// <param name="statRate">Statistics gather interval for which possible values are 2, 5, 10, 20 and 30.</param>
		public Boolean SetStatisticRate(long statRate) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointSetStatisticRateNative(objPtr, statRate);

			return ret;
		}
		/// <summary>
		/// Set TURN server and credentials information.
		/// </summary>
		/// <param name="e">The endpoint object.</param>
		/// <param name="turnAddress">TURN server FQDN or IP address.</param>
		/// <param name="port">TURN server port.</param>
		/// <param name="username">TURN server user name.</param>
		/// <param name="password">TURN server password.</param>
		/// <param name="baseTransport">Base transport type.</param>
		public Boolean SetTURNAddressCredentials(String turnAddress, uint port, String username, String password, EndpointBaseTransportType baseTransport) {
			if (objPtr == IntPtr.Zero) { return default; }

			IntPtr nTurnAddress = MarshalPtrToUtf8.GetInstance().MarshalManagedToNative(turnAddress ?? string.Empty);
			IntPtr nUsername = MarshalPtrToUtf8.GetInstance().MarshalManagedToNative(username ?? string.Empty);
			IntPtr nPassword = MarshalPtrToUtf8.GetInstance().MarshalManagedToNative(password ?? string.Empty);
			Boolean ret = VidyoEndpointSetTURNAddressCredentialsNative(objPtr, nTurnAddress, port, nUsername, nPassword, baseTransport);
			Marshal.FreeHGlobal(nPassword);
			Marshal.FreeHGlobal(nUsername);
			Marshal.FreeHGlobal(nTurnAddress);

			return ret;
		}
		/// <summary>
		/// Set TURN server certificate requirement.
		/// </summary>
		/// <param name="e">The endpoint object.</param>
		/// <param name="required">LMI_TRUE if TURN server certificate is required.</param>
		public Boolean SetTURNServerCertificateRequired(Boolean required) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointSetTURNServerCertificateRequiredNative(objPtr, required);

			return ret;
		}
		/// <summary>
		/// Sets the speed of transition animaiton for windows moving around inside the view. On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="viewId">A platform specific view ID to be positioned.</param>
		/// <param name="speedPercentage">Percentage of animation speed with default of 50, 100 for slowest and 0 for instant.</param>
		public Boolean SetViewAnimationSpeed(IntPtr viewId, uint speedPercentage) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointSetViewAnimationSpeedNative(objPtr, ref viewId, speedPercentage);

			return ret;
		}
		/// <summary>
		/// Shows or hides the label on the view which displays the participant name or preview. On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="viewId">A platform specific view ID to be positioned.</param>
		/// <param name="red">Red component of the color 0-255.</param>
		/// <param name="green">Green component of the color 0-255.</param>
		/// <param name="blue">Blue component of the color 0-255.</param>
		public Boolean SetViewBackgroundColor(IntPtr viewId, byte red, byte green, byte blue) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointSetViewBackgroundColorNative(objPtr, ref viewId, red, green, blue);

			return ret;
		}
		/// <summary>
		/// Sets path and file name to the picture that will be used for the virtual background effect. It is allowed to change picture while the effect is enabled. This functionality is supported only for macOS 10.14 and above, iOS 10.0 and above and Windows VC++ 15 and above.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="pathToPicture">Path and file name to the picture. Currently, only PNG and JPG is supported..</param>
		public Boolean SetVirtualBackgroundPicture(String pathToPicture) {
			if (objPtr == IntPtr.Zero) { return default; }

			IntPtr nPathToPicture = MarshalPtrToUtf8.GetInstance().MarshalManagedToNative(pathToPicture ?? string.Empty);
			Boolean ret = VidyoEndpointSetVirtualBackgroundPictureNative(objPtr, nPathToPicture);
			Marshal.FreeHGlobal(nPathToPicture);

			return ret;
		}
		/// <summary>
		/// Shows or hides the audio meters in the view. On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="viewId">A platform specific view ID to be positioned.</param>
		/// <param name="showMeters">Boolean to show or hide the audio meters.</param>
		public Boolean ShowAudioMeters(IntPtr viewId, Boolean showMeters) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointShowAudioMetersNative(objPtr, ref viewId, showMeters);

			return ret;
		}
		/// <summary>
		/// Sets the flag to show/hide the camera preview for composite layout only. On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="preview">Flag to show/hide the camera preview.</param>
		public Boolean ShowPreview(Boolean preview) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointShowPreviewNative(objPtr, preview);

			return ret;
		}
		/// <summary>
		/// Sets the position of the view every time it's changed on the screen. On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="viewId">A platform specific view ID to be positioned.</param>
		/// <param name="x">X coordinate.</param>
		/// <param name="y">Y coordinate.</param>
		/// <param name="width">Width of the view.</param>
		/// <param name="height">Height of the view.</param>
		public Boolean ShowViewAt(IntPtr viewId, int x, int y, uint width, uint height) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointShowViewAtNative(objPtr, ref viewId, x, y, width, height);

			return ret;
		}
		/// <summary>
		/// Sets the position of the view every time it's changed on the screen. On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="viewId">A platform specific view ID to be positioned.</param>
		/// <param name="x">X coordinate (in points).</param>
		/// <param name="y">Y coordinate (in points).</param>
		/// <param name="width">Width of the view (in points).</param>
		/// <param name="height">Height of the view (in points).</param>
		public Boolean ShowViewAtPoints(IntPtr viewId, int x, int y, uint width, uint height) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointShowViewAtPointsNative(objPtr, ref viewId, x, y, width, height);

			return ret;
		}
		/// <summary>
		/// Shows or hides the label on the view which displays the participant name or preview. On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="viewId">A platform specific view ID to be positioned.</param>
		/// <param name="showLabel">Boolean to show or hide the label.</param>
		public Boolean ShowViewLabel(IntPtr viewId, Boolean showLabel) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointShowViewLabelNative(objPtr, ref viewId, showLabel);

			return ret;
		}
		/// <summary>
		/// Sets the flag to show/hide the window share preview. On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="preview">Flag to show/hide the window share preview.</param>
		public Boolean ShowWindowSharePreview(Boolean preview) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointShowWindowSharePreviewNative(objPtr, preview);

			return ret;
		}
		/// <summary>
		/// Start sending of analytics in VidyoEndpoint.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="options">A structure that represent the google analytics options, plz refer VidyoEndpointGoogleAnalyticsOptions. If the user set to NULL, Vidyo Client will use default option to use google analytics.</param>
		public Boolean StartGoogleAnalyticsService(EndpointGoogleAnalyticsOptions options) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointStartGoogleAnalyticsServiceNative(objPtr, (options != null) ? options.GetObjectPtr():IntPtr.Zero);

			return ret;
		}
		/// <summary>
		/// Start sending of Insights in VidyoEndpoint.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="serverUrl">Url of Insights server.</param>
		public Boolean StartInsightsService(String serverUrl) {
			if (objPtr == IntPtr.Zero) { return default; }

			IntPtr nServerUrl = MarshalPtrToUtf8.GetInstance().MarshalManagedToNative(serverUrl ?? string.Empty);
			Boolean ret = VidyoEndpointStartInsightsServiceNative(objPtr, nServerUrl);
			Marshal.FreeHGlobal(nServerUrl);

			return ret;
		}
		/// <summary>
		/// On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e"></param>
		public Boolean StartLocalCameraDetection() {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointStartLocalCameraDetectionNative(objPtr);

			return ret;
		}
		/// <summary>
		/// On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e"></param>
		public Boolean StartLocalMicrophoneDetection() {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointStartLocalMicrophoneDetectionNative(objPtr);

			return ret;
		}
		/// <summary>
		/// On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e"></param>
		public Boolean StartLocalMonitorDetection() {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointStartLocalMonitorDetectionNative(objPtr);

			return ret;
		}
		/// <summary>
		/// On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e"></param>
		public Boolean StartLocalSpeakerDetection() {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointStartLocalSpeakerDetectionNative(objPtr);

			return ret;
		}
		/// <summary>
		/// On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e"></param>
		public Boolean StartLocalWindowShareDetection() {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointStartLocalWindowShareDetectionNative(objPtr);

			return ret;
		}
		/// <summary>
		/// 
		/// </summary>
		/// <param name="e"></param>
		public Boolean StartLocationDetection() {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointStartLocationDetectionNative(objPtr);

			return ret;
		}
		/// <summary>
		/// Option to stop logging into current file and start logging to the next one.
		/// </summary>
		/// <param name="e">The endpoint object.</param>
		public Boolean StartNextLogFile() {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointStartNextLogFileNative(objPtr);

			return ret;
		}
		/// <summary>
		/// Stop sending of Google analytics in VidyoEndpoint.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		public Boolean StopGoogleAnalyticsService() {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointStopGoogleAnalyticsServiceNative(objPtr);

			return ret;
		}
		/// <summary>
		/// Stop sending of Insights in VidyoEndpoint.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		public Boolean StopInsightsService() {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointStopInsightsServiceNative(objPtr);

			return ret;
		}
		/// <summary>
		/// On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e"></param>
		public void StopLocalCameraDetection() {
			if (objPtr == IntPtr.Zero) { return; }

			VidyoEndpointStopLocalCameraDetectionNative(objPtr);
		}
		/// <summary>
		/// On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e"></param>
		public void StopLocalMicrophoneDetection() {
			if (objPtr == IntPtr.Zero) { return; }

			VidyoEndpointStopLocalMicrophoneDetectionNative(objPtr);
		}
		/// <summary>
		/// On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e"></param>
		public void StopLocalMonitorDetection() {
			if (objPtr == IntPtr.Zero) { return; }

			VidyoEndpointStopLocalMonitorDetectionNative(objPtr);
		}
		/// <summary>
		/// On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e"></param>
		public void StopLocalSpeakerDetection() {
			if (objPtr == IntPtr.Zero) { return; }

			VidyoEndpointStopLocalSpeakerDetectionNative(objPtr);
		}
		/// <summary>
		/// On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e"></param>
		public void StopLocalWindowShareDetection() {
			if (objPtr == IntPtr.Zero) { return; }

			VidyoEndpointStopLocalWindowShareDetectionNative(objPtr);
		}
		/// <summary>
		/// 
		/// </summary>
		/// <param name="e"></param>
		public void StopLocationDetection() {
			if (objPtr == IntPtr.Zero) { return; }

			VidyoEndpointStopLocationDetectionNative(objPtr);
		}
		/// <summary>
		/// Swap streams of the remote video sources between views.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="firstView">A platform specific view ID where the first remote video sources is displayed.</param>
		/// <param name="secondView">A platform specific view ID where the second remote video sources is displayed.</param>
		public Boolean SwapStreamsBetweenViews(IntPtr firstView, IntPtr secondView) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointSwapStreamsBetweenViewsNative(objPtr, ref firstView, ref secondView);

			return ret;
		}
		/// <summary>
		/// Unregisters callback to notify the user in case of any errors occur during enabling camera effect.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		public Boolean UnregisterCameraEffectErrorListener() {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointUnregisterCameraEffectErrorListenerNative(objPtr);

			return ret;
		}
		/// <summary>
		/// Unregister callbacks for disable video on low bandwidth.
		/// </summary>
		/// <param name="e">VidyoEndpoint object.</param>
		public void UnregisterDisableVideoOnLowBwEventListener() {
			if (objPtr == IntPtr.Zero) { return; }

			VidyoEndpointUnregisterDisableVideoOnLowBwEventListenerNative(objPtr);
		}
		/// <summary>
		/// Unregisters advanced error event notifications.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		public Boolean UnregisterErrorEventListener() {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointUnregisterErrorEventListenerNative(objPtr);

			return ret;
		}
		/// <summary>
		/// Unregisters local camera event notifications. On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		public Boolean UnregisterLocalCameraEventListener() {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointUnregisterLocalCameraEventListenerNative(objPtr);

			return ret;
		}
		/// <summary>
		/// Unregisters local camera frame notifications. On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="localCamera">The VidyoLocalCamera for which to stop notifications.</param>
		public Boolean UnregisterLocalCameraFrameListener(LocalCamera localCamera) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointUnregisterLocalCameraFrameListenerNative(objPtr, (localCamera != null) ? localCamera.GetObjectPtr():IntPtr.Zero);

			return ret;
		}
		/// <summary>
		/// Unregisters local microphone energy notifications.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		public Boolean UnregisterLocalMicrophoneEnergyListener() {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointUnregisterLocalMicrophoneEnergyListenerNative(objPtr);

			return ret;
		}
		/// <summary>
		/// Unregisters local microphone event notifications. On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		public Boolean UnregisterLocalMicrophoneEventListener() {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointUnregisterLocalMicrophoneEventListenerNative(objPtr);

			return ret;
		}
		/// <summary>
		/// Unregisters local microphone frame notifications. On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="localMicrophone">The VidyoLocalMicrophone for which to stop notifications.</param>
		public Boolean UnregisterLocalMicrophoneFrameListener(LocalMicrophone localMicrophone) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointUnregisterLocalMicrophoneFrameListenerNative(objPtr, (localMicrophone != null) ? localMicrophone.GetObjectPtr():IntPtr.Zero);

			return ret;
		}
		/// <summary>
		/// Unregisters local monitor event notifications. On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		public Boolean UnregisterLocalMonitorEventListener() {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointUnregisterLocalMonitorEventListenerNative(objPtr);

			return ret;
		}
		/// <summary>
		/// Unregisters local monitor frame notifications. On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="localMonitor">The VidyoLocalMonitor for which to stop notifications.</param>
		public Boolean UnregisterLocalMonitorFrameListener(LocalMonitor localMonitor) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointUnregisterLocalMonitorFrameListenerNative(objPtr, (localMonitor != null) ? localMonitor.GetObjectPtr():IntPtr.Zero);

			return ret;
		}
		/// <summary>
		/// Unregisters local renderer event notifications. On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		public Boolean UnregisterLocalRendererEventListener() {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointUnregisterLocalRendererEventListenerNative(objPtr);

			return ret;
		}
		/// <summary>
		/// Unregisters local speaker event notifications. On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		public Boolean UnregisterLocalSpeakerEventListener() {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointUnregisterLocalSpeakerEventListenerNative(objPtr);

			return ret;
		}
		/// <summary>
		/// Unregisters local window share event notifications. On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		public Boolean UnregisterLocalWindowShareEventListener() {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointUnregisterLocalWindowShareEventListenerNative(objPtr);

			return ret;
		}
		/// <summary>
		/// Unregisters local window share frame notifications. On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="localWindowShare">The VidyoLocalWindowShare for which to stop notifications.</param>
		public Boolean UnregisterLocalWindowShareFrameListener(LocalWindowShare localWindowShare) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointUnregisterLocalWindowShareFrameListenerNative(objPtr, (localWindowShare != null) ? localWindowShare.GetObjectPtr():IntPtr.Zero);

			return ret;
		}
		/// <summary>
		/// Unregisters log event notifications.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		public Boolean UnregisterLogEventListener() {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointUnregisterLogEventListenerNative(objPtr);

			return ret;
		}
		/// <summary>
		/// This is a synchronous interface. Unregister the callback to stop receiving the final response for the next generation renderer action.
		/// </summary>
		/// <param name="e">VidyoEndpoint object.</param>
		public Boolean UnregisterNGRResultEventListener() {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointUnregisterNGRResultEventListenerNative(objPtr);

			return ret;
		}
		/// <summary>
		/// Unregisters network interface event notifications.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		public Boolean UnregisterNetworkInterfaceEventListener() {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointUnregisterNetworkInterfaceEventListenerNative(objPtr);

			return ret;
		}
		/// <summary>
		/// Unregisters plugin.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="plugin">Plugin to unregister.</param>
		public Boolean UnregisterPlugin(ulong plugin) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointUnregisterPluginNative(objPtr, plugin);

			return ret;
		}
		/// <summary>
		/// Unregisters reconnecting event notifications.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		public Boolean UnregisterReconnectEventListener() {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointUnregisterReconnectEventListenerNative(objPtr);

			return ret;
		}
		/// <summary>
		/// Unregisters remote camera event notifications.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		public Boolean UnregisterRemoteCameraEventListener() {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointUnregisterRemoteCameraEventListenerNative(objPtr);
			_mIRegisterRemoteCameraEventListener = null;

			return ret;
		}
		/// <summary>
		/// Unregisters remote camera frame notifications.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="remoteCamera">The VidyoRemoteCamera for which to stop notifications.</param>
		public Boolean UnregisterRemoteCameraFrameListener(RemoteCamera remoteCamera) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointUnregisterRemoteCameraFrameListenerNative(objPtr, (remoteCamera != null) ? remoteCamera.GetObjectPtr():IntPtr.Zero);

			return ret;
		}
		/// <summary>
		/// Unregisters remote microphone energy notifications.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		public Boolean UnregisterRemoteMicrophoneEnergyListener() {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointUnregisterRemoteMicrophoneEnergyListenerNative(objPtr);

			return ret;
		}
		/// <summary>
		/// Unregisters remote microphone event notifications.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		public Boolean UnregisterRemoteMicrophoneEventListener() {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointUnregisterRemoteMicrophoneEventListenerNative(objPtr);
			_mIRegisterRemoteMicrophoneEventListener = null;

			return ret;
		}
		/// <summary>
		/// Unregisters remote microphone frame notifications.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="remoteMicrophone">The VidyoRemoteMicrophone for which to stop notifications.</param>
		public Boolean UnregisterRemoteMicrophoneFrameListener(RemoteMicrophone remoteMicrophone) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointUnregisterRemoteMicrophoneFrameListenerNative(objPtr, (remoteMicrophone != null) ? remoteMicrophone.GetObjectPtr():IntPtr.Zero);

			return ret;
		}
		/// <summary>
		/// Unregisters remote renderer event notifications.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		public Boolean UnregisterRemoteRendererEventListener() {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointUnregisterRemoteRendererEventListenerNative(objPtr);

			return ret;
		}
		/// <summary>
		/// Unregisters remote speaker event notifications.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		public Boolean UnregisterRemoteSpeakerEventListener() {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointUnregisterRemoteSpeakerEventListenerNative(objPtr);

			return ret;
		}
		/// <summary>
		/// Unregisters remote window share event notifications.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		public Boolean UnregisterRemoteWindowShareEventListener() {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointUnregisterRemoteWindowShareEventListenerNative(objPtr);
			_mIRegisterRemoteWindowShareEventListener = null;

			return ret;
		}
		/// <summary>
		/// Unregisters remote window share frame notifications.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="remoteWindowShare">The VidyoRemoteWindowShare for which to stop notifications.</param>
		public Boolean UnregisterRemoteWindowShareFrameListener(RemoteWindowShare remoteWindowShare) {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointUnregisterRemoteWindowShareFrameListenerNative(objPtr, (remoteWindowShare != null) ? remoteWindowShare.GetObjectPtr():IntPtr.Zero);

			return ret;
		}
		/// <summary>
		/// Unregisters virtual audio source event notifications. This is a synchronous interface.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		public Boolean UnregisterVirtualAudioSourceEventListener() {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointUnregisterVirtualAudioSourceEventListenerNative(objPtr);

			return ret;
		}
		/// <summary>
		/// Unregisters virtual video source event notifications. On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		public Boolean UnregisterVirtualVideoSourceEventListener() {
			if (objPtr == IntPtr.Zero) { return default; }

			Boolean ret = VidyoEndpointUnregisterVirtualVideoSourceEventListenerNative(objPtr);

			return ret;
		}
		/// <summary>
		/// 
		/// </summary>
		/// <param name="e"></param>
		/// <param name="licenseKey"></param>
		/// <param name="userName"></param>
		public Boolean ValidateLicenseKey(String licenseKey, String userName) {
			if (objPtr == IntPtr.Zero) { return default; }

			IntPtr nLicenseKey = MarshalPtrToUtf8.GetInstance().MarshalManagedToNative(licenseKey ?? string.Empty);
			IntPtr nUserName = MarshalPtrToUtf8.GetInstance().MarshalManagedToNative(userName ?? string.Empty);
			Boolean ret = VidyoEndpointValidateLicenseKeyNative(objPtr, nLicenseKey, nUserName);
			Marshal.FreeHGlobal(nUserName);
			Marshal.FreeHGlobal(nLicenseKey);

			return ret;
		}
		/// <summary>
		/// Select a specific virtual video source which is a camera and add it to all remote renderers. The real camera will be unselected. On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object</param>
		/// <param name="virtualCamera">The VidyoVirtualVideoSource object to select. NULL to unselect the selected virtual camera.</param>
		public void VirtualCameraSelectAdvanced(VirtualVideoSource virtualCamera) {
			if (objPtr == IntPtr.Zero) { return; }

			VidyoEndpointVirtualCameraSelectAdvancedNative(objPtr, (virtualCamera != null) ? virtualCamera.GetObjectPtr():IntPtr.Zero);
		}
		/// <summary>
		/// Select a specific virtual video source which is a window share and add it to all remote renderers. The local window share will be unselected. On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="virtualWindowShare">The VidyoVirtualVideoSource object to select. NULL to unselect the selected virtual window share.</param>
		public void VirtualSourceWindowShareSelectAdvanced(VirtualVideoSource virtualWindowShare) {
			if (objPtr == IntPtr.Zero) { return; }

			VidyoEndpointVirtualSourceWindowShareSelectAdvancedNative(objPtr, (virtualWindowShare != null) ? virtualWindowShare.GetObjectPtr():IntPtr.Zero);
		}
		/// <summary>
		/// Unselect a specific virtual video source. On, iOS, this API must be called from main(UI) thread.
		/// </summary>
		/// <param name="e">The VidyoEndpoint object.</param>
		/// <param name="virtualVideoSource">The VidyoVirtualVideoSource object to unselect.</param>
		public void VirtualVideoSourceUnselectAdvanced(VirtualVideoSource virtualVideoSource) {
			if (objPtr == IntPtr.Zero) { return; }

			VidyoEndpointVirtualVideoSourceUnselectAdvancedNative(objPtr, (virtualVideoSource != null) ? virtualVideoSource.GetObjectPtr():IntPtr.Zero);
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnCameraEffectError))]
#endif
		private static void OnCameraEffectErrorDelegate(IntPtr e, EndpointCameraEffectError error){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			csE?._mIRegisterCameraEffectErrorListener?.OnCameraEffectError(error);
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnConferenceLost))]
#endif
		private static void OnConferenceLostDelegate(IntPtr e, EndpointReconnectFailReason reason){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			csE?._mIRegisterReconnectEventListener?.OnConferenceLost(reason);
			csE?.objects?.RemoveAll(item => (!item.IsAlive || item.Target == null));
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnDisableVideoOnLowBwEnded))]
#endif
		private static void OnDisableVideoOnLowBwEndedDelegate(IntPtr e){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			csE?._mIRegisterDisableVideoOnLowBwEventListener?.OnDisableVideoOnLowBwEnded();
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnDisableVideoOnLowBwStarted))]
#endif
		private static void OnDisableVideoOnLowBwStartedDelegate(IntPtr e){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			csE?._mIRegisterDisableVideoOnLowBwEventListener?.OnDisableVideoOnLowBwStarted();
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnError))]
#endif
		private static void OnErrorDelegate(IntPtr e, EndpointErrorCode error, IntPtr apiName){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			var n_apiName = VidyoEndpointOnErrorGetapiNameCStr(apiName);

			csE?._mIRegisterErrorEventListener?.OnError(error, (string)MarshalPtrToUtf8.GetInstance().MarshalNativeToManaged(n_apiName));
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnGetActiveNetworkInterface))]
#endif
		private static void OnGetActiveNetworkInterfaceDelegate(IntPtr e, IntPtr signalingInterface, IntPtr mediaInterface){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			NetworkInterface csSignalingInterface = null;
			if(signalingInterface != IntPtr.Zero) {
				var csSignalingInterfacePtr = NetworkInterface.VidyoNetworkInterfaceGetUserDataNative(signalingInterface);
				if (csSignalingInterfacePtr == IntPtr.Zero) {
					csSignalingInterface = new NetworkInterface(signalingInterface);
					if (csSignalingInterface != null) {
						csE?.objects?.Add(new WeakReference(csSignalingInterface));
					}
				} else {
					csSignalingInterface = (NetworkInterface)GCHandle.FromIntPtr(csSignalingInterfacePtr).Target;
				}
			}

			NetworkInterface csMediaInterface = null;
			if(mediaInterface != IntPtr.Zero) {
				var csMediaInterfacePtr = NetworkInterface.VidyoNetworkInterfaceGetUserDataNative(mediaInterface);
				if (csMediaInterfacePtr == IntPtr.Zero) {
					csMediaInterface = new NetworkInterface(mediaInterface);
					if (csMediaInterface != null) {
						csE?.objects?.Add(new WeakReference(csMediaInterface));
					}
				} else {
					csMediaInterface = (NetworkInterface)GCHandle.FromIntPtr(csMediaInterfacePtr).Target;
				}
			}

			csE?._mIGetActiveNetworkInterface?.OnGetActiveNetworkInterface(csSignalingInterface, csMediaInterface);
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnGetAnalyticsEventTable))]
#endif
		private static void OnGetAnalyticsEventTableDelegate(IntPtr e, IntPtr eventTables){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			List<EndpointGoogleAnalyticsEventTable> csEventTables = new List<EndpointGoogleAnalyticsEventTable>();
			var nEventTablesSize = 0;
			var nEventTables = VidyoEndpointOnGetAnalyticsEventTableGeteventTablesArrayNative(eventTables, ref nEventTablesSize);
			var nEventTablesIndex = 0;
			while (nEventTablesIndex < nEventTablesSize) {
				EndpointGoogleAnalyticsEventTable csTeventTables = new EndpointGoogleAnalyticsEventTable(Marshal.ReadIntPtr(nEventTables + (nEventTablesIndex * Marshal.SizeOf(nEventTables))));
				csEventTables.Add(csTeventTables);
				nEventTablesIndex++;
			}

			csE?._mIGetGoogleAnalyticsEventTable?.OnGetAnalyticsEventTable(csEventTables);
			VidyoEndpointOnGetAnalyticsEventTableFreeeventTablesArrayNative(nEventTables, nEventTablesSize);
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnGetAutoReconnectSetting))]
#endif
		private static void OnGetAutoReconnectSettingDelegate(IntPtr e, Boolean enableAutoReconnect, uint reconnectBackoff, uint maxReconnectAttempts){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			csE?._mIGetAutoReconnectSetting?.OnGetAutoReconnectSetting(enableAutoReconnect, reconnectBackoff, maxReconnectAttempts);
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnGetCameraBackgroundEffectInfo))]
#endif
		private static void OnGetCameraBackgroundEffectInfoDelegate(IntPtr e, IntPtr effectInfo){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			EndpointCameraEffectInfo csEffectInfo = new EndpointCameraEffectInfo(effectInfo);
			csE?._mIGetCameraBackgroundEffect?.OnGetCameraBackgroundEffectInfo(csEffectInfo);
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnGetGoogleAnalyticsOptions))]
#endif
		private static void OnGetGoogleAnalyticsOptionsDelegate(IntPtr e, IntPtr options){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			EndpointGoogleAnalyticsOptions csOptions = new EndpointGoogleAnalyticsOptions(options);
			csE?._mIGetGoogleAnalyticsOptions?.OnGetGoogleAnalyticsOptions(csOptions);
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnGetLoggerCategoryListComplete))]
#endif
		private static void OnGetLoggerCategoryListCompleteDelegate(IntPtr e, EndpointLoggerType loggerType, IntPtr categories, EndpointGetLoggerCategoryListResult result){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			List<LoggerCategory> csCategories = new List<LoggerCategory>();
			var nCategoriesSize = 0;
			var nCategories = VidyoEndpointOnGetLoggerCategoryListCompleteGetcategoriesArrayNative(categories, ref nCategoriesSize);
			var nCategoriesIndex = 0;
			while (nCategoriesIndex < nCategoriesSize) {
				LoggerCategory csTcategories = new LoggerCategory(Marshal.ReadIntPtr(nCategories + (nCategoriesIndex * Marshal.SizeOf(nCategories))));
				csCategories.Add(csTcategories);
				nCategoriesIndex++;
			}

			csE?._mIGetFileLoggerCategoryListAsync?.OnGetLoggerCategoryListComplete(loggerType, csCategories, result);
			VidyoEndpointOnGetLoggerCategoryListCompleteFreecategoriesArrayNative(nCategories, nCategoriesSize);
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnGetProductInfoComplete))]
#endif
		private static void OnGetProductInfoCompleteDelegate(IntPtr e, IntPtr productInfo, IntPtr supportedFeature){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			List<Property> csProductInfo = new List<Property>();
			var nProductInfoSize = 0;
			var nProductInfo = VidyoEndpointOnGetProductInfoCompleteGetproductInfoArrayNative(productInfo, ref nProductInfoSize);
			var nProductInfoIndex = 0;
			while (nProductInfoIndex < nProductInfoSize) {
				Property csTproductInfo = new Property(Marshal.ReadIntPtr(nProductInfo + (nProductInfoIndex * Marshal.SizeOf(nProductInfo))));
				csProductInfo.Add(csTproductInfo);
				nProductInfoIndex++;
			}

			List<Property> csSupportedFeature = new List<Property>();
			var nSupportedFeatureSize = 0;
			var nSupportedFeature = VidyoEndpointOnGetProductInfoCompleteGetsupportedFeatureArrayNative(supportedFeature, ref nSupportedFeatureSize);
			var nSupportedFeatureIndex = 0;
			while (nSupportedFeatureIndex < nSupportedFeatureSize) {
				Property csTsupportedFeature = new Property(Marshal.ReadIntPtr(nSupportedFeature + (nSupportedFeatureIndex * Marshal.SizeOf(nSupportedFeature))));
				csSupportedFeature.Add(csTsupportedFeature);
				nSupportedFeatureIndex++;
			}

			csE?._mIGetProductInfoAsync?.OnGetProductInfoComplete(csProductInfo, csSupportedFeature);
			VidyoEndpointOnGetProductInfoCompleteFreesupportedFeatureArrayNative(nSupportedFeature, nSupportedFeatureSize);
			VidyoEndpointOnGetProductInfoCompleteFreeproductInfoArrayNative(nProductInfo, nProductInfoSize);
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnGetWhitelistedAudioDevices))]
#endif
		private static void OnGetWhitelistedAudioDevicesDelegate(IntPtr e, IntPtr audioDevices){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			List<String> csAudioDevices = new List<String>();
			var nAudioDevicesSize = 0;
			var nAudioDevices = VidyoEndpointOnGetWhitelistedAudioDevicesGetaudioDevicesArrayNative(audioDevices, ref nAudioDevicesSize);
			var nAudioDevicesIndex = 0;
			while (nAudioDevicesIndex < nAudioDevicesSize) {
				csAudioDevices.Add((string)MarshalPtrToUtf8.GetInstance().MarshalNativeToManaged(Marshal.ReadIntPtr(nAudioDevices + (nAudioDevicesIndex * Marshal.SizeOf(nAudioDevices)))));
				nAudioDevicesIndex++;
			}

			csE?._mIGetWhitelistedAudioDevices?.OnGetWhitelistedAudioDevices(csAudioDevices);
			VidyoEndpointOnGetWhitelistedAudioDevicesFreeaudioDevicesArrayNative(nAudioDevices, nAudioDevicesSize);
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnLocalCameraAdded))]
#endif
		private static void OnLocalCameraAddedDelegate(IntPtr e, IntPtr localCamera){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			LocalCamera csLocalCamera = null;
			if(localCamera != IntPtr.Zero) {
				var csLocalCameraPtr = LocalCamera.VidyoLocalCameraGetUserDataNative(localCamera);
				if (csLocalCameraPtr == IntPtr.Zero) {
					csLocalCamera = new LocalCamera(localCamera);
					if (csLocalCamera != null) {
						csE?.objects?.Add(new WeakReference(csLocalCamera));
					}
				} else {
					csLocalCamera = (LocalCamera)GCHandle.FromIntPtr(csLocalCameraPtr).Target;
				}
			}

			csE?._mIRegisterLocalCameraEventListener?.OnLocalCameraAdded(csLocalCamera);
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnLocalCameraFrame))]
#endif
		private static void OnLocalCameraFrameDelegate(IntPtr e, IntPtr localCamera, IntPtr videoFrame){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			LocalCamera csLocalCamera = null;
			if(localCamera != IntPtr.Zero) {
				var csLocalCameraPtr = LocalCamera.VidyoLocalCameraGetUserDataNative(localCamera);
				if (csLocalCameraPtr == IntPtr.Zero) {
					csLocalCamera = new LocalCamera(localCamera);
					if (csLocalCamera != null) {
						csE?.objects?.Add(new WeakReference(csLocalCamera));
					}
				} else {
					csLocalCamera = (LocalCamera)GCHandle.FromIntPtr(csLocalCameraPtr).Target;
				}
			}

			VideoFrame csVideoFrame = null;
			if(videoFrame != IntPtr.Zero) {
				var csVideoFramePtr = VideoFrame.VidyoVideoFrameGetUserDataNative(videoFrame);
				csVideoFrame = csVideoFramePtr == IntPtr.Zero ? new VideoFrame(videoFrame) : (VideoFrame)GCHandle.FromIntPtr(csVideoFramePtr).Target;
			}

			csE?._mIRegisterLocalCameraFrameListener?.OnLocalCameraFrame(csLocalCamera, csVideoFrame);
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnLocalCameraRemoved))]
#endif
		private static void OnLocalCameraRemovedDelegate(IntPtr e, IntPtr localCamera){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			LocalCamera csLocalCamera = null;
			if(localCamera != IntPtr.Zero) {
				var csLocalCameraPtr = LocalCamera.VidyoLocalCameraGetUserDataNative(localCamera);
				if (csLocalCameraPtr == IntPtr.Zero) {
					csLocalCamera = new LocalCamera(localCamera);
					if (csLocalCamera != null) {
						csE?.objects?.Add(new WeakReference(csLocalCamera));
					}
				} else {
					csLocalCamera = (LocalCamera)GCHandle.FromIntPtr(csLocalCameraPtr).Target;
				}
			}

			csE?._mIRegisterLocalCameraEventListener?.OnLocalCameraRemoved(csLocalCamera);
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnLocalCameraSelected))]
#endif
		private static void OnLocalCameraSelectedDelegate(IntPtr e, IntPtr localCamera){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			LocalCamera csLocalCamera = null;
			if(localCamera != IntPtr.Zero) {
				var csLocalCameraPtr = LocalCamera.VidyoLocalCameraGetUserDataNative(localCamera);
				if (csLocalCameraPtr == IntPtr.Zero) {
					csLocalCamera = new LocalCamera(localCamera);
					if (csLocalCamera != null) {
						csE?.objects?.Add(new WeakReference(csLocalCamera));
					}
				} else {
					csLocalCamera = (LocalCamera)GCHandle.FromIntPtr(csLocalCameraPtr).Target;
				}
			}

			csE?._mIRegisterLocalCameraEventListener?.OnLocalCameraSelected(csLocalCamera);
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnLocalCameraStateUpdated))]
#endif
		private static void OnLocalCameraStateUpdatedDelegate(IntPtr e, IntPtr localCamera, Device.DeviceState state){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			LocalCamera csLocalCamera = null;
			if(localCamera != IntPtr.Zero) {
				var csLocalCameraPtr = LocalCamera.VidyoLocalCameraGetUserDataNative(localCamera);
				if (csLocalCameraPtr == IntPtr.Zero) {
					csLocalCamera = new LocalCamera(localCamera);
					if (csLocalCamera != null) {
						csE?.objects?.Add(new WeakReference(csLocalCamera));
					}
				} else {
					csLocalCamera = (LocalCamera)GCHandle.FromIntPtr(csLocalCameraPtr).Target;
				}
			}

			csE?._mIRegisterLocalCameraEventListener?.OnLocalCameraStateUpdated(csLocalCamera, state);
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnLocalMicrophoneAdded))]
#endif
		private static void OnLocalMicrophoneAddedDelegate(IntPtr e, IntPtr localMicrophone){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			LocalMicrophone csLocalMicrophone = null;
			if(localMicrophone != IntPtr.Zero) {
				var csLocalMicrophonePtr = LocalMicrophone.VidyoLocalMicrophoneGetUserDataNative(localMicrophone);
				if (csLocalMicrophonePtr == IntPtr.Zero) {
					csLocalMicrophone = new LocalMicrophone(localMicrophone);
					if (csLocalMicrophone != null) {
						csE?.objects?.Add(new WeakReference(csLocalMicrophone));
					}
				} else {
					csLocalMicrophone = (LocalMicrophone)GCHandle.FromIntPtr(csLocalMicrophonePtr).Target;
				}
			}

			csE?._mIRegisterLocalMicrophoneEventListener?.OnLocalMicrophoneAdded(csLocalMicrophone);
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnLocalMicrophoneEnergy))]
#endif
		private static void OnLocalMicrophoneEnergyDelegate(IntPtr e, IntPtr localMicrophone, int audioEnergy){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			LocalMicrophone csLocalMicrophone = null;
			if(localMicrophone != IntPtr.Zero) {
				var csLocalMicrophonePtr = LocalMicrophone.VidyoLocalMicrophoneGetUserDataNative(localMicrophone);
				if (csLocalMicrophonePtr == IntPtr.Zero) {
					csLocalMicrophone = new LocalMicrophone(localMicrophone);
					if (csLocalMicrophone != null) {
						csE?.objects?.Add(new WeakReference(csLocalMicrophone));
					}
				} else {
					csLocalMicrophone = (LocalMicrophone)GCHandle.FromIntPtr(csLocalMicrophonePtr).Target;
				}
			}

			csE?._mIRegisterLocalMicrophoneEnergyListener?.OnLocalMicrophoneEnergy(csLocalMicrophone, audioEnergy);
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnLocalMicrophoneFrame))]
#endif
		private static void OnLocalMicrophoneFrameDelegate(IntPtr e, IntPtr localMicrophone, IntPtr audioFrame){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			LocalMicrophone csLocalMicrophone = null;
			if(localMicrophone != IntPtr.Zero) {
				var csLocalMicrophonePtr = LocalMicrophone.VidyoLocalMicrophoneGetUserDataNative(localMicrophone);
				if (csLocalMicrophonePtr == IntPtr.Zero) {
					csLocalMicrophone = new LocalMicrophone(localMicrophone);
					if (csLocalMicrophone != null) {
						csE?.objects?.Add(new WeakReference(csLocalMicrophone));
					}
				} else {
					csLocalMicrophone = (LocalMicrophone)GCHandle.FromIntPtr(csLocalMicrophonePtr).Target;
				}
			}

			AudioFrame csAudioFrame = null;
			if(audioFrame != IntPtr.Zero) {
				var csAudioFramePtr = AudioFrame.VidyoAudioFrameGetUserDataNative(audioFrame);
				csAudioFrame = csAudioFramePtr == IntPtr.Zero ? new AudioFrame(audioFrame) : (AudioFrame)GCHandle.FromIntPtr(csAudioFramePtr).Target;
			}

			csE?._mIRegisterLocalMicrophoneFrameListener?.OnLocalMicrophoneFrame(csLocalMicrophone, csAudioFrame);
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnLocalMicrophoneRemoved))]
#endif
		private static void OnLocalMicrophoneRemovedDelegate(IntPtr e, IntPtr localMicrophone){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			LocalMicrophone csLocalMicrophone = null;
			if(localMicrophone != IntPtr.Zero) {
				var csLocalMicrophonePtr = LocalMicrophone.VidyoLocalMicrophoneGetUserDataNative(localMicrophone);
				if (csLocalMicrophonePtr == IntPtr.Zero) {
					csLocalMicrophone = new LocalMicrophone(localMicrophone);
					if (csLocalMicrophone != null) {
						csE?.objects?.Add(new WeakReference(csLocalMicrophone));
					}
				} else {
					csLocalMicrophone = (LocalMicrophone)GCHandle.FromIntPtr(csLocalMicrophonePtr).Target;
				}
			}

			csE?._mIRegisterLocalMicrophoneEventListener?.OnLocalMicrophoneRemoved(csLocalMicrophone);
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnLocalMicrophoneSelected))]
#endif
		private static void OnLocalMicrophoneSelectedDelegate(IntPtr e, IntPtr localMicrophone){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			LocalMicrophone csLocalMicrophone = null;
			if(localMicrophone != IntPtr.Zero) {
				var csLocalMicrophonePtr = LocalMicrophone.VidyoLocalMicrophoneGetUserDataNative(localMicrophone);
				if (csLocalMicrophonePtr == IntPtr.Zero) {
					csLocalMicrophone = new LocalMicrophone(localMicrophone);
					if (csLocalMicrophone != null) {
						csE?.objects?.Add(new WeakReference(csLocalMicrophone));
					}
				} else {
					csLocalMicrophone = (LocalMicrophone)GCHandle.FromIntPtr(csLocalMicrophonePtr).Target;
				}
			}

			csE?._mIRegisterLocalMicrophoneEventListener?.OnLocalMicrophoneSelected(csLocalMicrophone);
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnLocalMicrophoneStateUpdated))]
#endif
		private static void OnLocalMicrophoneStateUpdatedDelegate(IntPtr e, IntPtr localMicrophone, Device.DeviceState state){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			LocalMicrophone csLocalMicrophone = null;
			if(localMicrophone != IntPtr.Zero) {
				var csLocalMicrophonePtr = LocalMicrophone.VidyoLocalMicrophoneGetUserDataNative(localMicrophone);
				if (csLocalMicrophonePtr == IntPtr.Zero) {
					csLocalMicrophone = new LocalMicrophone(localMicrophone);
					if (csLocalMicrophone != null) {
						csE?.objects?.Add(new WeakReference(csLocalMicrophone));
					}
				} else {
					csLocalMicrophone = (LocalMicrophone)GCHandle.FromIntPtr(csLocalMicrophonePtr).Target;
				}
			}

			csE?._mIRegisterLocalMicrophoneEventListener?.OnLocalMicrophoneStateUpdated(csLocalMicrophone, state);
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnLocalMonitorAdded))]
#endif
		private static void OnLocalMonitorAddedDelegate(IntPtr e, IntPtr localMonitor){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			LocalMonitor csLocalMonitor = null;
			if(localMonitor != IntPtr.Zero) {
				var csLocalMonitorPtr = LocalMonitor.VidyoLocalMonitorGetUserDataNative(localMonitor);
				if (csLocalMonitorPtr == IntPtr.Zero) {
					csLocalMonitor = new LocalMonitor(localMonitor);
					if (csLocalMonitor != null) {
						csE?.objects?.Add(new WeakReference(csLocalMonitor));
					}
				} else {
					csLocalMonitor = (LocalMonitor)GCHandle.FromIntPtr(csLocalMonitorPtr).Target;
				}
			}

			csE?._mIRegisterLocalMonitorEventListener?.OnLocalMonitorAdded(csLocalMonitor);
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnLocalMonitorFrame))]
#endif
		private static void OnLocalMonitorFrameDelegate(IntPtr e, IntPtr localMonitor, IntPtr videoFrame){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			LocalMonitor csLocalMonitor = null;
			if(localMonitor != IntPtr.Zero) {
				var csLocalMonitorPtr = LocalMonitor.VidyoLocalMonitorGetUserDataNative(localMonitor);
				if (csLocalMonitorPtr == IntPtr.Zero) {
					csLocalMonitor = new LocalMonitor(localMonitor);
					if (csLocalMonitor != null) {
						csE?.objects?.Add(new WeakReference(csLocalMonitor));
					}
				} else {
					csLocalMonitor = (LocalMonitor)GCHandle.FromIntPtr(csLocalMonitorPtr).Target;
				}
			}

			VideoFrame csVideoFrame = null;
			if(videoFrame != IntPtr.Zero) {
				var csVideoFramePtr = VideoFrame.VidyoVideoFrameGetUserDataNative(videoFrame);
				csVideoFrame = csVideoFramePtr == IntPtr.Zero ? new VideoFrame(videoFrame) : (VideoFrame)GCHandle.FromIntPtr(csVideoFramePtr).Target;
			}

			csE?._mIRegisterLocalMonitorFrameListener?.OnLocalMonitorFrame(csLocalMonitor, csVideoFrame);
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnLocalMonitorRemoved))]
#endif
		private static void OnLocalMonitorRemovedDelegate(IntPtr e, IntPtr localMonitor){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			LocalMonitor csLocalMonitor = null;
			if(localMonitor != IntPtr.Zero) {
				var csLocalMonitorPtr = LocalMonitor.VidyoLocalMonitorGetUserDataNative(localMonitor);
				if (csLocalMonitorPtr == IntPtr.Zero) {
					csLocalMonitor = new LocalMonitor(localMonitor);
					if (csLocalMonitor != null) {
						csE?.objects?.Add(new WeakReference(csLocalMonitor));
					}
				} else {
					csLocalMonitor = (LocalMonitor)GCHandle.FromIntPtr(csLocalMonitorPtr).Target;
				}
			}

			csE?._mIRegisterLocalMonitorEventListener?.OnLocalMonitorRemoved(csLocalMonitor);
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnLocalMonitorSelected))]
#endif
		private static void OnLocalMonitorSelectedDelegate(IntPtr e, IntPtr localMonitor){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			LocalMonitor csLocalMonitor = null;
			if(localMonitor != IntPtr.Zero) {
				var csLocalMonitorPtr = LocalMonitor.VidyoLocalMonitorGetUserDataNative(localMonitor);
				if (csLocalMonitorPtr == IntPtr.Zero) {
					csLocalMonitor = new LocalMonitor(localMonitor);
					if (csLocalMonitor != null) {
						csE?.objects?.Add(new WeakReference(csLocalMonitor));
					}
				} else {
					csLocalMonitor = (LocalMonitor)GCHandle.FromIntPtr(csLocalMonitorPtr).Target;
				}
			}

			csE?._mIRegisterLocalMonitorEventListener?.OnLocalMonitorSelected(csLocalMonitor);
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnLocalMonitorStateUpdated))]
#endif
		private static void OnLocalMonitorStateUpdatedDelegate(IntPtr e, IntPtr localMonitor, Device.DeviceState state){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			LocalMonitor csLocalMonitor = null;
			if(localMonitor != IntPtr.Zero) {
				var csLocalMonitorPtr = LocalMonitor.VidyoLocalMonitorGetUserDataNative(localMonitor);
				if (csLocalMonitorPtr == IntPtr.Zero) {
					csLocalMonitor = new LocalMonitor(localMonitor);
					if (csLocalMonitor != null) {
						csE?.objects?.Add(new WeakReference(csLocalMonitor));
					}
				} else {
					csLocalMonitor = (LocalMonitor)GCHandle.FromIntPtr(csLocalMonitorPtr).Target;
				}
			}

			csE?._mIRegisterLocalMonitorEventListener?.OnLocalMonitorStateUpdated(csLocalMonitor, state);
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnLocalRendererAdded))]
#endif
		private static void OnLocalRendererAddedDelegate(IntPtr e, IntPtr localRenderer){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			LocalRenderer csLocalRenderer = null;
			if(localRenderer != IntPtr.Zero) {
				var csLocalRendererPtr = LocalRenderer.VidyoLocalRendererGetUserDataNative(localRenderer);
				if (csLocalRendererPtr == IntPtr.Zero) {
					csLocalRenderer = new LocalRenderer(localRenderer);
					if (csLocalRenderer != null) {
						csE?.objects?.Add(new WeakReference(csLocalRenderer));
					}
				} else {
					csLocalRenderer = (LocalRenderer)GCHandle.FromIntPtr(csLocalRendererPtr).Target;
				}
			}

			csE?._mIRegisterLocalRendererEventListener?.OnLocalRendererAdded(csLocalRenderer);
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnLocalRendererRemoved))]
#endif
		private static void OnLocalRendererRemovedDelegate(IntPtr e, IntPtr localRenderer){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			LocalRenderer csLocalRenderer = null;
			if(localRenderer != IntPtr.Zero) {
				var csLocalRendererPtr = LocalRenderer.VidyoLocalRendererGetUserDataNative(localRenderer);
				if (csLocalRendererPtr == IntPtr.Zero) {
					csLocalRenderer = new LocalRenderer(localRenderer);
					if (csLocalRenderer != null) {
						csE?.objects?.Add(new WeakReference(csLocalRenderer));
					}
				} else {
					csLocalRenderer = (LocalRenderer)GCHandle.FromIntPtr(csLocalRendererPtr).Target;
				}
			}

			csE?._mIRegisterLocalRendererEventListener?.OnLocalRendererRemoved(csLocalRenderer);
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnLocalRendererSelected))]
#endif
		private static void OnLocalRendererSelectedDelegate(IntPtr e, IntPtr localRenderer){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			LocalRenderer csLocalRenderer = null;
			if(localRenderer != IntPtr.Zero) {
				var csLocalRendererPtr = LocalRenderer.VidyoLocalRendererGetUserDataNative(localRenderer);
				if (csLocalRendererPtr == IntPtr.Zero) {
					csLocalRenderer = new LocalRenderer(localRenderer);
					if (csLocalRenderer != null) {
						csE?.objects?.Add(new WeakReference(csLocalRenderer));
					}
				} else {
					csLocalRenderer = (LocalRenderer)GCHandle.FromIntPtr(csLocalRendererPtr).Target;
				}
			}

			csE?._mIRegisterLocalRendererEventListener?.OnLocalRendererSelected(csLocalRenderer);
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnLocalRendererStateUpdated))]
#endif
		private static void OnLocalRendererStateUpdatedDelegate(IntPtr e, IntPtr localRenderer, Device.DeviceState state){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			LocalRenderer csLocalRenderer = null;
			if(localRenderer != IntPtr.Zero) {
				var csLocalRendererPtr = LocalRenderer.VidyoLocalRendererGetUserDataNative(localRenderer);
				if (csLocalRendererPtr == IntPtr.Zero) {
					csLocalRenderer = new LocalRenderer(localRenderer);
					if (csLocalRenderer != null) {
						csE?.objects?.Add(new WeakReference(csLocalRenderer));
					}
				} else {
					csLocalRenderer = (LocalRenderer)GCHandle.FromIntPtr(csLocalRendererPtr).Target;
				}
			}

			csE?._mIRegisterLocalRendererEventListener?.OnLocalRendererStateUpdated(csLocalRenderer, state);
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnLocalSpeakerAdded))]
#endif
		private static void OnLocalSpeakerAddedDelegate(IntPtr e, IntPtr localSpeaker){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			LocalSpeaker csLocalSpeaker = null;
			if(localSpeaker != IntPtr.Zero) {
				var csLocalSpeakerPtr = LocalSpeaker.VidyoLocalSpeakerGetUserDataNative(localSpeaker);
				if (csLocalSpeakerPtr == IntPtr.Zero) {
					csLocalSpeaker = new LocalSpeaker(localSpeaker);
					if (csLocalSpeaker != null) {
						csE?.objects?.Add(new WeakReference(csLocalSpeaker));
					}
				} else {
					csLocalSpeaker = (LocalSpeaker)GCHandle.FromIntPtr(csLocalSpeakerPtr).Target;
				}
			}

			csE?._mIRegisterLocalSpeakerEventListener?.OnLocalSpeakerAdded(csLocalSpeaker);
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnLocalSpeakerRemoved))]
#endif
		private static void OnLocalSpeakerRemovedDelegate(IntPtr e, IntPtr localSpeaker){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			LocalSpeaker csLocalSpeaker = null;
			if(localSpeaker != IntPtr.Zero) {
				var csLocalSpeakerPtr = LocalSpeaker.VidyoLocalSpeakerGetUserDataNative(localSpeaker);
				if (csLocalSpeakerPtr == IntPtr.Zero) {
					csLocalSpeaker = new LocalSpeaker(localSpeaker);
					if (csLocalSpeaker != null) {
						csE?.objects?.Add(new WeakReference(csLocalSpeaker));
					}
				} else {
					csLocalSpeaker = (LocalSpeaker)GCHandle.FromIntPtr(csLocalSpeakerPtr).Target;
				}
			}

			csE?._mIRegisterLocalSpeakerEventListener?.OnLocalSpeakerRemoved(csLocalSpeaker);
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnLocalSpeakerSelected))]
#endif
		private static void OnLocalSpeakerSelectedDelegate(IntPtr e, IntPtr localSpeaker){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			LocalSpeaker csLocalSpeaker = null;
			if(localSpeaker != IntPtr.Zero) {
				var csLocalSpeakerPtr = LocalSpeaker.VidyoLocalSpeakerGetUserDataNative(localSpeaker);
				if (csLocalSpeakerPtr == IntPtr.Zero) {
					csLocalSpeaker = new LocalSpeaker(localSpeaker);
					if (csLocalSpeaker != null) {
						csE?.objects?.Add(new WeakReference(csLocalSpeaker));
					}
				} else {
					csLocalSpeaker = (LocalSpeaker)GCHandle.FromIntPtr(csLocalSpeakerPtr).Target;
				}
			}

			csE?._mIRegisterLocalSpeakerEventListener?.OnLocalSpeakerSelected(csLocalSpeaker);
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnLocalSpeakerStateUpdated))]
#endif
		private static void OnLocalSpeakerStateUpdatedDelegate(IntPtr e, IntPtr localSpeaker, Device.DeviceState state){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			LocalSpeaker csLocalSpeaker = null;
			if(localSpeaker != IntPtr.Zero) {
				var csLocalSpeakerPtr = LocalSpeaker.VidyoLocalSpeakerGetUserDataNative(localSpeaker);
				if (csLocalSpeakerPtr == IntPtr.Zero) {
					csLocalSpeaker = new LocalSpeaker(localSpeaker);
					if (csLocalSpeaker != null) {
						csE?.objects?.Add(new WeakReference(csLocalSpeaker));
					}
				} else {
					csLocalSpeaker = (LocalSpeaker)GCHandle.FromIntPtr(csLocalSpeakerPtr).Target;
				}
			}

			csE?._mIRegisterLocalSpeakerEventListener?.OnLocalSpeakerStateUpdated(csLocalSpeaker, state);
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnLocalWindowShareAdded))]
#endif
		private static void OnLocalWindowShareAddedDelegate(IntPtr e, IntPtr localWindowShare){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			LocalWindowShare csLocalWindowShare = null;
			if(localWindowShare != IntPtr.Zero) {
				var csLocalWindowSharePtr = LocalWindowShare.VidyoLocalWindowShareGetUserDataNative(localWindowShare);
				if (csLocalWindowSharePtr == IntPtr.Zero) {
					csLocalWindowShare = new LocalWindowShare(localWindowShare);
					if (csLocalWindowShare != null) {
						csE?.objects?.Add(new WeakReference(csLocalWindowShare));
					}
				} else {
					csLocalWindowShare = (LocalWindowShare)GCHandle.FromIntPtr(csLocalWindowSharePtr).Target;
				}
			}

			csE?._mIRegisterLocalWindowShareEventListener?.OnLocalWindowShareAdded(csLocalWindowShare);
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnLocalWindowShareFrame))]
#endif
		private static void OnLocalWindowShareFrameDelegate(IntPtr e, IntPtr localWindowShare, IntPtr videoFrame){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			LocalWindowShare csLocalWindowShare = null;
			if(localWindowShare != IntPtr.Zero) {
				var csLocalWindowSharePtr = LocalWindowShare.VidyoLocalWindowShareGetUserDataNative(localWindowShare);
				if (csLocalWindowSharePtr == IntPtr.Zero) {
					csLocalWindowShare = new LocalWindowShare(localWindowShare);
					if (csLocalWindowShare != null) {
						csE?.objects?.Add(new WeakReference(csLocalWindowShare));
					}
				} else {
					csLocalWindowShare = (LocalWindowShare)GCHandle.FromIntPtr(csLocalWindowSharePtr).Target;
				}
			}

			VideoFrame csVideoFrame = null;
			if(videoFrame != IntPtr.Zero) {
				var csVideoFramePtr = VideoFrame.VidyoVideoFrameGetUserDataNative(videoFrame);
				csVideoFrame = csVideoFramePtr == IntPtr.Zero ? new VideoFrame(videoFrame) : (VideoFrame)GCHandle.FromIntPtr(csVideoFramePtr).Target;
			}

			csE?._mIRegisterLocalWindowShareFrameListener?.OnLocalWindowShareFrame(csLocalWindowShare, csVideoFrame);
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnLocalWindowShareRemoved))]
#endif
		private static void OnLocalWindowShareRemovedDelegate(IntPtr e, IntPtr localWindowShare){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			LocalWindowShare csLocalWindowShare = null;
			if(localWindowShare != IntPtr.Zero) {
				var csLocalWindowSharePtr = LocalWindowShare.VidyoLocalWindowShareGetUserDataNative(localWindowShare);
				if (csLocalWindowSharePtr == IntPtr.Zero) {
					csLocalWindowShare = new LocalWindowShare(localWindowShare);
					if (csLocalWindowShare != null) {
						csE?.objects?.Add(new WeakReference(csLocalWindowShare));
					}
				} else {
					csLocalWindowShare = (LocalWindowShare)GCHandle.FromIntPtr(csLocalWindowSharePtr).Target;
				}
			}

			csE?._mIRegisterLocalWindowShareEventListener?.OnLocalWindowShareRemoved(csLocalWindowShare);
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnLocalWindowShareSelected))]
#endif
		private static void OnLocalWindowShareSelectedDelegate(IntPtr e, IntPtr localWindowShare){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			LocalWindowShare csLocalWindowShare = null;
			if(localWindowShare != IntPtr.Zero) {
				var csLocalWindowSharePtr = LocalWindowShare.VidyoLocalWindowShareGetUserDataNative(localWindowShare);
				if (csLocalWindowSharePtr == IntPtr.Zero) {
					csLocalWindowShare = new LocalWindowShare(localWindowShare);
					if (csLocalWindowShare != null) {
						csE?.objects?.Add(new WeakReference(csLocalWindowShare));
					}
				} else {
					csLocalWindowShare = (LocalWindowShare)GCHandle.FromIntPtr(csLocalWindowSharePtr).Target;
				}
			}

			csE?._mIRegisterLocalWindowShareEventListener?.OnLocalWindowShareSelected(csLocalWindowShare);
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnLocalWindowShareStateUpdated))]
#endif
		private static void OnLocalWindowShareStateUpdatedDelegate(IntPtr e, IntPtr localWindowShare, Device.DeviceState state){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			LocalWindowShare csLocalWindowShare = null;
			if(localWindowShare != IntPtr.Zero) {
				var csLocalWindowSharePtr = LocalWindowShare.VidyoLocalWindowShareGetUserDataNative(localWindowShare);
				if (csLocalWindowSharePtr == IntPtr.Zero) {
					csLocalWindowShare = new LocalWindowShare(localWindowShare);
					if (csLocalWindowShare != null) {
						csE?.objects?.Add(new WeakReference(csLocalWindowShare));
					}
				} else {
					csLocalWindowShare = (LocalWindowShare)GCHandle.FromIntPtr(csLocalWindowSharePtr).Target;
				}
			}

			csE?._mIRegisterLocalWindowShareEventListener?.OnLocalWindowShareStateUpdated(csLocalWindowShare, state);
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnLog))]
#endif
		private static void OnLogDelegate(IntPtr e, IntPtr logRecord){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			LogRecord csLogRecord = new LogRecord(logRecord);
			csE?._mIRegisterLogEventListener?.OnLog(csLogRecord);
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnLogCompressionComplete))]
#endif
		private static void OnLogCompressionCompleteDelegate(IntPtr e, IntPtr compressedFileName, EndpointLogCompressionResult result){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			var n_compressedFileName = VidyoEndpointOnLogCompressionCompleteGetcompressedFileNameCStr(compressedFileName);

			csE?._mICompressLogs?.OnLogCompressionComplete((string)MarshalPtrToUtf8.GetInstance().MarshalNativeToManaged(n_compressedFileName), result);
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnNGRResult))]
#endif
		private static void OnNGRResultDelegate(IntPtr e, EndpointNGRActionType type, Boolean success, IntPtr error){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			var n_error = VidyoEndpointOnNGRResultGeterrorCStr(error);

			csE?._mIRegisterNGRResultEventListener?.OnNGRResult(type, success, (string)MarshalPtrToUtf8.GetInstance().MarshalNativeToManaged(n_error));
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnNetworkInterfaceAdded))]
#endif
		private static void OnNetworkInterfaceAddedDelegate(IntPtr e, IntPtr networkInterface){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			NetworkInterface csNetworkInterface = null;
			if(networkInterface != IntPtr.Zero) {
				var csNetworkInterfacePtr = NetworkInterface.VidyoNetworkInterfaceGetUserDataNative(networkInterface);
				if (csNetworkInterfacePtr == IntPtr.Zero) {
					csNetworkInterface = new NetworkInterface(networkInterface);
					if (csNetworkInterface != null) {
						csE?.objects?.Add(new WeakReference(csNetworkInterface));
					}
				} else {
					csNetworkInterface = (NetworkInterface)GCHandle.FromIntPtr(csNetworkInterfacePtr).Target;
				}
			}

			csE?._mIRegisterNetworkInterfaceEventListener?.OnNetworkInterfaceAdded(csNetworkInterface);
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnNetworkInterfaceRemoved))]
#endif
		private static void OnNetworkInterfaceRemovedDelegate(IntPtr e, IntPtr networkInterface){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			NetworkInterface csNetworkInterface = null;
			if(networkInterface != IntPtr.Zero) {
				var csNetworkInterfacePtr = NetworkInterface.VidyoNetworkInterfaceGetUserDataNative(networkInterface);
				if (csNetworkInterfacePtr == IntPtr.Zero) {
					csNetworkInterface = new NetworkInterface(networkInterface);
					if (csNetworkInterface != null) {
						csE?.objects?.Add(new WeakReference(csNetworkInterface));
					}
				} else {
					csNetworkInterface = (NetworkInterface)GCHandle.FromIntPtr(csNetworkInterfacePtr).Target;
				}
			}

			csE?._mIRegisterNetworkInterfaceEventListener?.OnNetworkInterfaceRemoved(csNetworkInterface);
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnNetworkInterfaceSelected))]
#endif
		private static void OnNetworkInterfaceSelectedDelegate(IntPtr e, IntPtr networkInterface, NetworkInterface.NetworkInterfaceTransportType transportType){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			NetworkInterface csNetworkInterface = null;
			if(networkInterface != IntPtr.Zero) {
				var csNetworkInterfacePtr = NetworkInterface.VidyoNetworkInterfaceGetUserDataNative(networkInterface);
				if (csNetworkInterfacePtr == IntPtr.Zero) {
					csNetworkInterface = new NetworkInterface(networkInterface);
					if (csNetworkInterface != null) {
						csE?.objects?.Add(new WeakReference(csNetworkInterface));
					}
				} else {
					csNetworkInterface = (NetworkInterface)GCHandle.FromIntPtr(csNetworkInterfacePtr).Target;
				}
			}

			csE?._mIRegisterNetworkInterfaceEventListener?.OnNetworkInterfaceSelected(csNetworkInterface, transportType);
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnNetworkInterfaceStateUpdated))]
#endif
		private static void OnNetworkInterfaceStateUpdatedDelegate(IntPtr e, IntPtr networkInterface, NetworkInterface.NetworkInterfaceState state){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			NetworkInterface csNetworkInterface = null;
			if(networkInterface != IntPtr.Zero) {
				var csNetworkInterfacePtr = NetworkInterface.VidyoNetworkInterfaceGetUserDataNative(networkInterface);
				if (csNetworkInterfacePtr == IntPtr.Zero) {
					csNetworkInterface = new NetworkInterface(networkInterface);
					if (csNetworkInterface != null) {
						csE?.objects?.Add(new WeakReference(csNetworkInterface));
					}
				} else {
					csNetworkInterface = (NetworkInterface)GCHandle.FromIntPtr(csNetworkInterfacePtr).Target;
				}
			}

			csE?._mIRegisterNetworkInterfaceEventListener?.OnNetworkInterfaceStateUpdated(csNetworkInterface, state);
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnReconnected))]
#endif
		private static void OnReconnectedDelegate(IntPtr e){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			csE?._mIRegisterReconnectEventListener?.OnReconnected();
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnReconnecting))]
#endif
		private static void OnReconnectingDelegate(IntPtr e, uint attempt, uint attemptTimeout, EndpointReconnectFailReason reason){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			csE?._mIRegisterReconnectEventListener?.OnReconnecting(attempt, attemptTimeout, reason);
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnRemoteCameraAdded))]
#endif
		private static void OnRemoteCameraAddedDelegate(IntPtr e, IntPtr remoteCamera, IntPtr user, IntPtr call, IntPtr room, IntPtr participant){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			RemoteCamera csRemoteCamera = null;
			if(remoteCamera != IntPtr.Zero) {
				var csRemoteCameraPtr = RemoteCamera.VidyoRemoteCameraGetUserDataNative(remoteCamera);
				if (csRemoteCameraPtr == IntPtr.Zero) {
					csRemoteCamera = new RemoteCamera(remoteCamera);
					if (csRemoteCamera != null) {
						csE?.objects?.Add(new WeakReference(csRemoteCamera));
					}
				} else {
					csRemoteCamera = (RemoteCamera)GCHandle.FromIntPtr(csRemoteCameraPtr).Target;
				}
			}
			if(csE != null && csRemoteCamera != null)
				csE.GetRemoteCamerasMap()[csRemoteCamera.GetId()] = csRemoteCamera;

			User csUser = null;
			if(user != IntPtr.Zero) {
				var csUserPtr = User.VidyoUserGetUserDataNative(user);
				if (csUserPtr == IntPtr.Zero) {
					csUser = new User(user);
					if (csUser != null) {
						csE?.objects?.Add(new WeakReference(csUser));
					}
				} else {
					csUser = (User)GCHandle.FromIntPtr(csUserPtr).Target;
				}
			}

			Call csCall = null;
			if(call != IntPtr.Zero) {
				var csCallPtr = Call.VidyoCallGetUserDataNative(call);
				if (csCallPtr == IntPtr.Zero) {
					csCall = new Call(call);
					if (csCall != null) {
						csE?.objects?.Add(new WeakReference(csCall));
					}
				} else {
					csCall = (Call)GCHandle.FromIntPtr(csCallPtr).Target;
				}
			}

			Room csRoom = null;
			if(room != IntPtr.Zero) {
				var csRoomPtr = Room.VidyoRoomGetUserDataNative(room);
				if (csRoomPtr == IntPtr.Zero) {
					csRoom = new Room(room);
					if (csRoom != null) {
						csE?.objects?.Add(new WeakReference(csRoom));
					}
				} else {
					csRoom = (Room)GCHandle.FromIntPtr(csRoomPtr).Target;
				}
			}

			Participant csParticipant = null;
			if(participant != IntPtr.Zero) {
				var csParticipantPtr = Participant.VidyoParticipantGetUserDataNative(participant);
				if (csParticipantPtr == IntPtr.Zero) {
					csParticipant = new Participant(participant);
					if (csParticipant != null) {
						csE?.objects?.Add(new WeakReference(csParticipant));
					}
				} else {
					csParticipant = (Participant)GCHandle.FromIntPtr(csParticipantPtr).Target;
				}
			}

			csE?._mIRegisterRemoteCameraEventListener?.OnRemoteCameraAdded(csRemoteCamera, csUser, csCall, csRoom, csParticipant);
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnRemoteCameraFirstFrameReceived))]
#endif
		private static void OnRemoteCameraFirstFrameReceivedDelegate(IntPtr e, IntPtr remoteCamera){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			RemoteCamera csRemoteCamera = null;
			if(remoteCamera != IntPtr.Zero) {
				var csRemoteCameraPtr = RemoteCamera.VidyoRemoteCameraGetUserDataNative(remoteCamera);
				if (csRemoteCameraPtr == IntPtr.Zero) {
					csRemoteCamera = new RemoteCamera(remoteCamera);
					if (csRemoteCamera != null) {
						csE?.objects?.Add(new WeakReference(csRemoteCamera));
					}
				} else {
					csRemoteCamera = (RemoteCamera)GCHandle.FromIntPtr(csRemoteCameraPtr).Target;
				}
			}

			IRequestVideoForRemoteCamera cb = csE?.GetOnRemoteCameraFirstFrameReceivedCallbacksMap()?[csRemoteCamera?.GetId() ?? string.Empty];
			csE?.GetOnRemoteCameraFirstFrameReceivedCallbacksMap()?.Remove(csRemoteCamera?.GetId() ?? string.Empty);
			cb?.OnRemoteCameraFirstFrameReceived(csRemoteCamera);
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnRemoteCameraFrame))]
#endif
		private static void OnRemoteCameraFrameDelegate(IntPtr e, IntPtr remoteCamera, IntPtr participant, IntPtr videoFrame){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			RemoteCamera csRemoteCamera = null;
			if(remoteCamera != IntPtr.Zero) {
				var csRemoteCameraPtr = RemoteCamera.VidyoRemoteCameraGetUserDataNative(remoteCamera);
				if (csRemoteCameraPtr == IntPtr.Zero) {
					csRemoteCamera = new RemoteCamera(remoteCamera);
					if (csRemoteCamera != null) {
						csE?.objects?.Add(new WeakReference(csRemoteCamera));
					}
				} else {
					csRemoteCamera = (RemoteCamera)GCHandle.FromIntPtr(csRemoteCameraPtr).Target;
				}
			}

			Participant csParticipant = null;
			if(participant != IntPtr.Zero) {
				var csParticipantPtr = Participant.VidyoParticipantGetUserDataNative(participant);
				if (csParticipantPtr == IntPtr.Zero) {
					csParticipant = new Participant(participant);
					if (csParticipant != null) {
						csE?.objects?.Add(new WeakReference(csParticipant));
					}
				} else {
					csParticipant = (Participant)GCHandle.FromIntPtr(csParticipantPtr).Target;
				}
			}

			VideoFrame csVideoFrame = null;
			if(videoFrame != IntPtr.Zero) {
				var csVideoFramePtr = VideoFrame.VidyoVideoFrameGetUserDataNative(videoFrame);
				csVideoFrame = csVideoFramePtr == IntPtr.Zero ? new VideoFrame(videoFrame) : (VideoFrame)GCHandle.FromIntPtr(csVideoFramePtr).Target;
			}

			csE?._mIRegisterRemoteCameraFrameListener?.OnRemoteCameraFrame(csRemoteCamera, csParticipant, csVideoFrame);
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnRemoteCameraRemoved))]
#endif
		private static void OnRemoteCameraRemovedDelegate(IntPtr e, IntPtr remoteCamera, IntPtr user, IntPtr call, IntPtr room, IntPtr participant){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			RemoteCamera csRemoteCamera = null;
			if(remoteCamera != IntPtr.Zero) {
				var csRemoteCameraPtr = RemoteCamera.VidyoRemoteCameraGetUserDataNative(remoteCamera);
				if (csRemoteCameraPtr == IntPtr.Zero) {
					csRemoteCamera = new RemoteCamera(remoteCamera);
					if (csRemoteCamera != null) {
						csE?.objects?.Add(new WeakReference(csRemoteCamera));
					}
				} else {
					csRemoteCamera = (RemoteCamera)GCHandle.FromIntPtr(csRemoteCameraPtr).Target;
				}
			}
			csE?.GetRemoteCamerasMap()?.Remove(csRemoteCamera?.GetId() ?? string.Empty);

			User csUser = null;
			if(user != IntPtr.Zero) {
				var csUserPtr = User.VidyoUserGetUserDataNative(user);
				if (csUserPtr == IntPtr.Zero) {
					csUser = new User(user);
					if (csUser != null) {
						csE?.objects?.Add(new WeakReference(csUser));
					}
				} else {
					csUser = (User)GCHandle.FromIntPtr(csUserPtr).Target;
				}
			}

			Call csCall = null;
			if(call != IntPtr.Zero) {
				var csCallPtr = Call.VidyoCallGetUserDataNative(call);
				if (csCallPtr == IntPtr.Zero) {
					csCall = new Call(call);
					if (csCall != null) {
						csE?.objects?.Add(new WeakReference(csCall));
					}
				} else {
					csCall = (Call)GCHandle.FromIntPtr(csCallPtr).Target;
				}
			}

			Room csRoom = null;
			if(room != IntPtr.Zero) {
				var csRoomPtr = Room.VidyoRoomGetUserDataNative(room);
				if (csRoomPtr == IntPtr.Zero) {
					csRoom = new Room(room);
					if (csRoom != null) {
						csE?.objects?.Add(new WeakReference(csRoom));
					}
				} else {
					csRoom = (Room)GCHandle.FromIntPtr(csRoomPtr).Target;
				}
			}

			Participant csParticipant = null;
			if(participant != IntPtr.Zero) {
				var csParticipantPtr = Participant.VidyoParticipantGetUserDataNative(participant);
				if (csParticipantPtr == IntPtr.Zero) {
					csParticipant = new Participant(participant);
					if (csParticipant != null) {
						csE?.objects?.Add(new WeakReference(csParticipant));
					}
				} else {
					csParticipant = (Participant)GCHandle.FromIntPtr(csParticipantPtr).Target;
				}
			}

			csE?._mIRegisterRemoteCameraEventListener?.OnRemoteCameraRemoved(csRemoteCamera, csUser, csCall, csRoom, csParticipant);
			if(csE?._mIRegisterRemoteCameraEventListener == null) csRemoteCamera?.Dispose();
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnRemoteCameraStateUpdated))]
#endif
		private static void OnRemoteCameraStateUpdatedDelegate(IntPtr e, IntPtr remoteCamera, IntPtr user, IntPtr call, IntPtr room, IntPtr participant, Device.DeviceState state){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			RemoteCamera csRemoteCamera = null;
			if(remoteCamera != IntPtr.Zero) {
				var csRemoteCameraPtr = RemoteCamera.VidyoRemoteCameraGetUserDataNative(remoteCamera);
				if (csRemoteCameraPtr == IntPtr.Zero) {
					csRemoteCamera = new RemoteCamera(remoteCamera);
					if (csRemoteCamera != null) {
						csE?.objects?.Add(new WeakReference(csRemoteCamera));
					}
				} else {
					csRemoteCamera = (RemoteCamera)GCHandle.FromIntPtr(csRemoteCameraPtr).Target;
				}
			}

			User csUser = null;
			if(user != IntPtr.Zero) {
				var csUserPtr = User.VidyoUserGetUserDataNative(user);
				if (csUserPtr == IntPtr.Zero) {
					csUser = new User(user);
					if (csUser != null) {
						csE?.objects?.Add(new WeakReference(csUser));
					}
				} else {
					csUser = (User)GCHandle.FromIntPtr(csUserPtr).Target;
				}
			}

			Call csCall = null;
			if(call != IntPtr.Zero) {
				var csCallPtr = Call.VidyoCallGetUserDataNative(call);
				if (csCallPtr == IntPtr.Zero) {
					csCall = new Call(call);
					if (csCall != null) {
						csE?.objects?.Add(new WeakReference(csCall));
					}
				} else {
					csCall = (Call)GCHandle.FromIntPtr(csCallPtr).Target;
				}
			}

			Room csRoom = null;
			if(room != IntPtr.Zero) {
				var csRoomPtr = Room.VidyoRoomGetUserDataNative(room);
				if (csRoomPtr == IntPtr.Zero) {
					csRoom = new Room(room);
					if (csRoom != null) {
						csE?.objects?.Add(new WeakReference(csRoom));
					}
				} else {
					csRoom = (Room)GCHandle.FromIntPtr(csRoomPtr).Target;
				}
			}

			Participant csParticipant = null;
			if(participant != IntPtr.Zero) {
				var csParticipantPtr = Participant.VidyoParticipantGetUserDataNative(participant);
				if (csParticipantPtr == IntPtr.Zero) {
					csParticipant = new Participant(participant);
					if (csParticipant != null) {
						csE?.objects?.Add(new WeakReference(csParticipant));
					}
				} else {
					csParticipant = (Participant)GCHandle.FromIntPtr(csParticipantPtr).Target;
				}
			}

			csE?._mIRegisterRemoteCameraEventListener?.OnRemoteCameraStateUpdated(csRemoteCamera, csUser, csCall, csRoom, csParticipant, state);
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnRemoteMicrophoneAdded))]
#endif
		private static void OnRemoteMicrophoneAddedDelegate(IntPtr e, IntPtr remoteMicrophone, IntPtr user, IntPtr call, IntPtr room, IntPtr participant){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			RemoteMicrophone csRemoteMicrophone = null;
			if(remoteMicrophone != IntPtr.Zero) {
				var csRemoteMicrophonePtr = RemoteMicrophone.VidyoRemoteMicrophoneGetUserDataNative(remoteMicrophone);
				if (csRemoteMicrophonePtr == IntPtr.Zero) {
					csRemoteMicrophone = new RemoteMicrophone(remoteMicrophone);
					if (csRemoteMicrophone != null) {
						csE?.objects?.Add(new WeakReference(csRemoteMicrophone));
					}
				} else {
					csRemoteMicrophone = (RemoteMicrophone)GCHandle.FromIntPtr(csRemoteMicrophonePtr).Target;
				}
			}
			if(csE != null && csRemoteMicrophone != null)
				csE.GetRemoteMicrophonesMap()[csRemoteMicrophone.GetId()] = csRemoteMicrophone;

			User csUser = null;
			if(user != IntPtr.Zero) {
				var csUserPtr = User.VidyoUserGetUserDataNative(user);
				if (csUserPtr == IntPtr.Zero) {
					csUser = new User(user);
					if (csUser != null) {
						csE?.objects?.Add(new WeakReference(csUser));
					}
				} else {
					csUser = (User)GCHandle.FromIntPtr(csUserPtr).Target;
				}
			}

			Call csCall = null;
			if(call != IntPtr.Zero) {
				var csCallPtr = Call.VidyoCallGetUserDataNative(call);
				if (csCallPtr == IntPtr.Zero) {
					csCall = new Call(call);
					if (csCall != null) {
						csE?.objects?.Add(new WeakReference(csCall));
					}
				} else {
					csCall = (Call)GCHandle.FromIntPtr(csCallPtr).Target;
				}
			}

			Room csRoom = null;
			if(room != IntPtr.Zero) {
				var csRoomPtr = Room.VidyoRoomGetUserDataNative(room);
				if (csRoomPtr == IntPtr.Zero) {
					csRoom = new Room(room);
					if (csRoom != null) {
						csE?.objects?.Add(new WeakReference(csRoom));
					}
				} else {
					csRoom = (Room)GCHandle.FromIntPtr(csRoomPtr).Target;
				}
			}

			Participant csParticipant = null;
			if(participant != IntPtr.Zero) {
				var csParticipantPtr = Participant.VidyoParticipantGetUserDataNative(participant);
				if (csParticipantPtr == IntPtr.Zero) {
					csParticipant = new Participant(participant);
					if (csParticipant != null) {
						csE?.objects?.Add(new WeakReference(csParticipant));
					}
				} else {
					csParticipant = (Participant)GCHandle.FromIntPtr(csParticipantPtr).Target;
				}
			}

			csE?._mIRegisterRemoteMicrophoneEventListener?.OnRemoteMicrophoneAdded(csRemoteMicrophone, csUser, csCall, csRoom, csParticipant);
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnRemoteMicrophoneEnergy))]
#endif
		private static void OnRemoteMicrophoneEnergyDelegate(IntPtr e, IntPtr remoteMicrophone, IntPtr participant, int audioEnergy){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			RemoteMicrophone csRemoteMicrophone = null;
			if(remoteMicrophone != IntPtr.Zero) {
				var csRemoteMicrophonePtr = RemoteMicrophone.VidyoRemoteMicrophoneGetUserDataNative(remoteMicrophone);
				if (csRemoteMicrophonePtr == IntPtr.Zero) {
					csRemoteMicrophone = new RemoteMicrophone(remoteMicrophone);
					if (csRemoteMicrophone != null) {
						csE?.objects?.Add(new WeakReference(csRemoteMicrophone));
					}
				} else {
					csRemoteMicrophone = (RemoteMicrophone)GCHandle.FromIntPtr(csRemoteMicrophonePtr).Target;
				}
			}

			Participant csParticipant = null;
			if(participant != IntPtr.Zero) {
				var csParticipantPtr = Participant.VidyoParticipantGetUserDataNative(participant);
				if (csParticipantPtr == IntPtr.Zero) {
					csParticipant = new Participant(participant);
					if (csParticipant != null) {
						csE?.objects?.Add(new WeakReference(csParticipant));
					}
				} else {
					csParticipant = (Participant)GCHandle.FromIntPtr(csParticipantPtr).Target;
				}
			}

			csE?._mIRegisterRemoteMicrophoneEnergyListener?.OnRemoteMicrophoneEnergy(csRemoteMicrophone, csParticipant, audioEnergy);
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnRemoteMicrophoneFrame))]
#endif
		private static void OnRemoteMicrophoneFrameDelegate(IntPtr e, IntPtr remoteMicrophone, IntPtr participant, IntPtr audioFrame){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			RemoteMicrophone csRemoteMicrophone = null;
			if(remoteMicrophone != IntPtr.Zero) {
				var csRemoteMicrophonePtr = RemoteMicrophone.VidyoRemoteMicrophoneGetUserDataNative(remoteMicrophone);
				if (csRemoteMicrophonePtr == IntPtr.Zero) {
					csRemoteMicrophone = new RemoteMicrophone(remoteMicrophone);
					if (csRemoteMicrophone != null) {
						csE?.objects?.Add(new WeakReference(csRemoteMicrophone));
					}
				} else {
					csRemoteMicrophone = (RemoteMicrophone)GCHandle.FromIntPtr(csRemoteMicrophonePtr).Target;
				}
			}

			Participant csParticipant = null;
			if(participant != IntPtr.Zero) {
				var csParticipantPtr = Participant.VidyoParticipantGetUserDataNative(participant);
				if (csParticipantPtr == IntPtr.Zero) {
					csParticipant = new Participant(participant);
					if (csParticipant != null) {
						csE?.objects?.Add(new WeakReference(csParticipant));
					}
				} else {
					csParticipant = (Participant)GCHandle.FromIntPtr(csParticipantPtr).Target;
				}
			}

			AudioFrame csAudioFrame = null;
			if(audioFrame != IntPtr.Zero) {
				var csAudioFramePtr = AudioFrame.VidyoAudioFrameGetUserDataNative(audioFrame);
				csAudioFrame = csAudioFramePtr == IntPtr.Zero ? new AudioFrame(audioFrame) : (AudioFrame)GCHandle.FromIntPtr(csAudioFramePtr).Target;
			}

			csE?._mIRegisterRemoteMicrophoneFrameListener?.OnRemoteMicrophoneFrame(csRemoteMicrophone, csParticipant, csAudioFrame);
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnRemoteMicrophoneRemoved))]
#endif
		private static void OnRemoteMicrophoneRemovedDelegate(IntPtr e, IntPtr remoteMicrophone, IntPtr user, IntPtr call, IntPtr room, IntPtr participant){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			RemoteMicrophone csRemoteMicrophone = null;
			if(remoteMicrophone != IntPtr.Zero) {
				var csRemoteMicrophonePtr = RemoteMicrophone.VidyoRemoteMicrophoneGetUserDataNative(remoteMicrophone);
				if (csRemoteMicrophonePtr == IntPtr.Zero) {
					csRemoteMicrophone = new RemoteMicrophone(remoteMicrophone);
					if (csRemoteMicrophone != null) {
						csE?.objects?.Add(new WeakReference(csRemoteMicrophone));
					}
				} else {
					csRemoteMicrophone = (RemoteMicrophone)GCHandle.FromIntPtr(csRemoteMicrophonePtr).Target;
				}
			}
			csE?.GetRemoteMicrophonesMap()?.Remove(csRemoteMicrophone?.GetId() ?? string.Empty);

			User csUser = null;
			if(user != IntPtr.Zero) {
				var csUserPtr = User.VidyoUserGetUserDataNative(user);
				if (csUserPtr == IntPtr.Zero) {
					csUser = new User(user);
					if (csUser != null) {
						csE?.objects?.Add(new WeakReference(csUser));
					}
				} else {
					csUser = (User)GCHandle.FromIntPtr(csUserPtr).Target;
				}
			}

			Call csCall = null;
			if(call != IntPtr.Zero) {
				var csCallPtr = Call.VidyoCallGetUserDataNative(call);
				if (csCallPtr == IntPtr.Zero) {
					csCall = new Call(call);
					if (csCall != null) {
						csE?.objects?.Add(new WeakReference(csCall));
					}
				} else {
					csCall = (Call)GCHandle.FromIntPtr(csCallPtr).Target;
				}
			}

			Room csRoom = null;
			if(room != IntPtr.Zero) {
				var csRoomPtr = Room.VidyoRoomGetUserDataNative(room);
				if (csRoomPtr == IntPtr.Zero) {
					csRoom = new Room(room);
					if (csRoom != null) {
						csE?.objects?.Add(new WeakReference(csRoom));
					}
				} else {
					csRoom = (Room)GCHandle.FromIntPtr(csRoomPtr).Target;
				}
			}

			Participant csParticipant = null;
			if(participant != IntPtr.Zero) {
				var csParticipantPtr = Participant.VidyoParticipantGetUserDataNative(participant);
				if (csParticipantPtr == IntPtr.Zero) {
					csParticipant = new Participant(participant);
					if (csParticipant != null) {
						csE?.objects?.Add(new WeakReference(csParticipant));
					}
				} else {
					csParticipant = (Participant)GCHandle.FromIntPtr(csParticipantPtr).Target;
				}
			}

			csE?._mIRegisterRemoteMicrophoneEventListener?.OnRemoteMicrophoneRemoved(csRemoteMicrophone, csUser, csCall, csRoom, csParticipant);
			if(csE?._mIRegisterRemoteMicrophoneEventListener == null) csRemoteMicrophone?.Dispose();
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnRemoteMicrophoneStateUpdated))]
#endif
		private static void OnRemoteMicrophoneStateUpdatedDelegate(IntPtr e, IntPtr remoteMicrophone, IntPtr user, IntPtr call, IntPtr room, IntPtr participant, Device.DeviceState state){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			RemoteMicrophone csRemoteMicrophone = null;
			if(remoteMicrophone != IntPtr.Zero) {
				var csRemoteMicrophonePtr = RemoteMicrophone.VidyoRemoteMicrophoneGetUserDataNative(remoteMicrophone);
				if (csRemoteMicrophonePtr == IntPtr.Zero) {
					csRemoteMicrophone = new RemoteMicrophone(remoteMicrophone);
					if (csRemoteMicrophone != null) {
						csE?.objects?.Add(new WeakReference(csRemoteMicrophone));
					}
				} else {
					csRemoteMicrophone = (RemoteMicrophone)GCHandle.FromIntPtr(csRemoteMicrophonePtr).Target;
				}
			}

			User csUser = null;
			if(user != IntPtr.Zero) {
				var csUserPtr = User.VidyoUserGetUserDataNative(user);
				if (csUserPtr == IntPtr.Zero) {
					csUser = new User(user);
					if (csUser != null) {
						csE?.objects?.Add(new WeakReference(csUser));
					}
				} else {
					csUser = (User)GCHandle.FromIntPtr(csUserPtr).Target;
				}
			}

			Call csCall = null;
			if(call != IntPtr.Zero) {
				var csCallPtr = Call.VidyoCallGetUserDataNative(call);
				if (csCallPtr == IntPtr.Zero) {
					csCall = new Call(call);
					if (csCall != null) {
						csE?.objects?.Add(new WeakReference(csCall));
					}
				} else {
					csCall = (Call)GCHandle.FromIntPtr(csCallPtr).Target;
				}
			}

			Room csRoom = null;
			if(room != IntPtr.Zero) {
				var csRoomPtr = Room.VidyoRoomGetUserDataNative(room);
				if (csRoomPtr == IntPtr.Zero) {
					csRoom = new Room(room);
					if (csRoom != null) {
						csE?.objects?.Add(new WeakReference(csRoom));
					}
				} else {
					csRoom = (Room)GCHandle.FromIntPtr(csRoomPtr).Target;
				}
			}

			Participant csParticipant = null;
			if(participant != IntPtr.Zero) {
				var csParticipantPtr = Participant.VidyoParticipantGetUserDataNative(participant);
				if (csParticipantPtr == IntPtr.Zero) {
					csParticipant = new Participant(participant);
					if (csParticipant != null) {
						csE?.objects?.Add(new WeakReference(csParticipant));
					}
				} else {
					csParticipant = (Participant)GCHandle.FromIntPtr(csParticipantPtr).Target;
				}
			}

			csE?._mIRegisterRemoteMicrophoneEventListener?.OnRemoteMicrophoneStateUpdated(csRemoteMicrophone, csUser, csCall, csRoom, csParticipant, state);
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnRemoteRendererAdded))]
#endif
		private static void OnRemoteRendererAddedDelegate(IntPtr e, IntPtr remoteRenderer, IntPtr user, IntPtr call, IntPtr room){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			RemoteRenderer csRemoteRenderer = null;
			if(remoteRenderer != IntPtr.Zero) {
				var csRemoteRendererPtr = RemoteRenderer.VidyoRemoteRendererGetUserDataNative(remoteRenderer);
				if (csRemoteRendererPtr == IntPtr.Zero) {
					csRemoteRenderer = new RemoteRenderer(remoteRenderer);
					if (csRemoteRenderer != null) {
						csE?.objects?.Add(new WeakReference(csRemoteRenderer));
					}
				} else {
					csRemoteRenderer = (RemoteRenderer)GCHandle.FromIntPtr(csRemoteRendererPtr).Target;
				}
			}

			User csUser = null;
			if(user != IntPtr.Zero) {
				var csUserPtr = User.VidyoUserGetUserDataNative(user);
				if (csUserPtr == IntPtr.Zero) {
					csUser = new User(user);
					if (csUser != null) {
						csE?.objects?.Add(new WeakReference(csUser));
					}
				} else {
					csUser = (User)GCHandle.FromIntPtr(csUserPtr).Target;
				}
			}

			Call csCall = null;
			if(call != IntPtr.Zero) {
				var csCallPtr = Call.VidyoCallGetUserDataNative(call);
				if (csCallPtr == IntPtr.Zero) {
					csCall = new Call(call);
					if (csCall != null) {
						csE?.objects?.Add(new WeakReference(csCall));
					}
				} else {
					csCall = (Call)GCHandle.FromIntPtr(csCallPtr).Target;
				}
			}

			Room csRoom = null;
			if(room != IntPtr.Zero) {
				var csRoomPtr = Room.VidyoRoomGetUserDataNative(room);
				if (csRoomPtr == IntPtr.Zero) {
					csRoom = new Room(room);
					if (csRoom != null) {
						csE?.objects?.Add(new WeakReference(csRoom));
					}
				} else {
					csRoom = (Room)GCHandle.FromIntPtr(csRoomPtr).Target;
				}
			}

			csE?._mIRegisterRemoteRendererEventListener?.OnRemoteRendererAdded(csRemoteRenderer, csUser, csCall, csRoom);
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnRemoteRendererRemoved))]
#endif
		private static void OnRemoteRendererRemovedDelegate(IntPtr e, IntPtr remoteRenderer, IntPtr user, IntPtr call, IntPtr room){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			RemoteRenderer csRemoteRenderer = null;
			if(remoteRenderer != IntPtr.Zero) {
				var csRemoteRendererPtr = RemoteRenderer.VidyoRemoteRendererGetUserDataNative(remoteRenderer);
				if (csRemoteRendererPtr == IntPtr.Zero) {
					csRemoteRenderer = new RemoteRenderer(remoteRenderer);
					if (csRemoteRenderer != null) {
						csE?.objects?.Add(new WeakReference(csRemoteRenderer));
					}
				} else {
					csRemoteRenderer = (RemoteRenderer)GCHandle.FromIntPtr(csRemoteRendererPtr).Target;
				}
			}

			User csUser = null;
			if(user != IntPtr.Zero) {
				var csUserPtr = User.VidyoUserGetUserDataNative(user);
				if (csUserPtr == IntPtr.Zero) {
					csUser = new User(user);
					if (csUser != null) {
						csE?.objects?.Add(new WeakReference(csUser));
					}
				} else {
					csUser = (User)GCHandle.FromIntPtr(csUserPtr).Target;
				}
			}

			Call csCall = null;
			if(call != IntPtr.Zero) {
				var csCallPtr = Call.VidyoCallGetUserDataNative(call);
				if (csCallPtr == IntPtr.Zero) {
					csCall = new Call(call);
					if (csCall != null) {
						csE?.objects?.Add(new WeakReference(csCall));
					}
				} else {
					csCall = (Call)GCHandle.FromIntPtr(csCallPtr).Target;
				}
			}

			Room csRoom = null;
			if(room != IntPtr.Zero) {
				var csRoomPtr = Room.VidyoRoomGetUserDataNative(room);
				if (csRoomPtr == IntPtr.Zero) {
					csRoom = new Room(room);
					if (csRoom != null) {
						csE?.objects?.Add(new WeakReference(csRoom));
					}
				} else {
					csRoom = (Room)GCHandle.FromIntPtr(csRoomPtr).Target;
				}
			}

			csE?._mIRegisterRemoteRendererEventListener?.OnRemoteRendererRemoved(csRemoteRenderer, csUser, csCall, csRoom);
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnRemoteRendererStateUpdated))]
#endif
		private static void OnRemoteRendererStateUpdatedDelegate(IntPtr e, IntPtr remoteRenderer, IntPtr user, IntPtr call, IntPtr room, Device.DeviceState state){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			RemoteRenderer csRemoteRenderer = null;
			if(remoteRenderer != IntPtr.Zero) {
				var csRemoteRendererPtr = RemoteRenderer.VidyoRemoteRendererGetUserDataNative(remoteRenderer);
				if (csRemoteRendererPtr == IntPtr.Zero) {
					csRemoteRenderer = new RemoteRenderer(remoteRenderer);
					if (csRemoteRenderer != null) {
						csE?.objects?.Add(new WeakReference(csRemoteRenderer));
					}
				} else {
					csRemoteRenderer = (RemoteRenderer)GCHandle.FromIntPtr(csRemoteRendererPtr).Target;
				}
			}

			User csUser = null;
			if(user != IntPtr.Zero) {
				var csUserPtr = User.VidyoUserGetUserDataNative(user);
				if (csUserPtr == IntPtr.Zero) {
					csUser = new User(user);
					if (csUser != null) {
						csE?.objects?.Add(new WeakReference(csUser));
					}
				} else {
					csUser = (User)GCHandle.FromIntPtr(csUserPtr).Target;
				}
			}

			Call csCall = null;
			if(call != IntPtr.Zero) {
				var csCallPtr = Call.VidyoCallGetUserDataNative(call);
				if (csCallPtr == IntPtr.Zero) {
					csCall = new Call(call);
					if (csCall != null) {
						csE?.objects?.Add(new WeakReference(csCall));
					}
				} else {
					csCall = (Call)GCHandle.FromIntPtr(csCallPtr).Target;
				}
			}

			Room csRoom = null;
			if(room != IntPtr.Zero) {
				var csRoomPtr = Room.VidyoRoomGetUserDataNative(room);
				if (csRoomPtr == IntPtr.Zero) {
					csRoom = new Room(room);
					if (csRoom != null) {
						csE?.objects?.Add(new WeakReference(csRoom));
					}
				} else {
					csRoom = (Room)GCHandle.FromIntPtr(csRoomPtr).Target;
				}
			}

			csE?._mIRegisterRemoteRendererEventListener?.OnRemoteRendererStateUpdated(csRemoteRenderer, csUser, csCall, csRoom, state);
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnRemoteSpeakerAdded))]
#endif
		private static void OnRemoteSpeakerAddedDelegate(IntPtr e, IntPtr remoteSpeaker, IntPtr user, IntPtr call, IntPtr room){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			RemoteSpeaker csRemoteSpeaker = null;
			if(remoteSpeaker != IntPtr.Zero) {
				var csRemoteSpeakerPtr = RemoteSpeaker.VidyoRemoteSpeakerGetUserDataNative(remoteSpeaker);
				if (csRemoteSpeakerPtr == IntPtr.Zero) {
					csRemoteSpeaker = new RemoteSpeaker(remoteSpeaker);
					if (csRemoteSpeaker != null) {
						csE?.objects?.Add(new WeakReference(csRemoteSpeaker));
					}
				} else {
					csRemoteSpeaker = (RemoteSpeaker)GCHandle.FromIntPtr(csRemoteSpeakerPtr).Target;
				}
			}

			User csUser = null;
			if(user != IntPtr.Zero) {
				var csUserPtr = User.VidyoUserGetUserDataNative(user);
				if (csUserPtr == IntPtr.Zero) {
					csUser = new User(user);
					if (csUser != null) {
						csE?.objects?.Add(new WeakReference(csUser));
					}
				} else {
					csUser = (User)GCHandle.FromIntPtr(csUserPtr).Target;
				}
			}

			Call csCall = null;
			if(call != IntPtr.Zero) {
				var csCallPtr = Call.VidyoCallGetUserDataNative(call);
				if (csCallPtr == IntPtr.Zero) {
					csCall = new Call(call);
					if (csCall != null) {
						csE?.objects?.Add(new WeakReference(csCall));
					}
				} else {
					csCall = (Call)GCHandle.FromIntPtr(csCallPtr).Target;
				}
			}

			Room csRoom = null;
			if(room != IntPtr.Zero) {
				var csRoomPtr = Room.VidyoRoomGetUserDataNative(room);
				if (csRoomPtr == IntPtr.Zero) {
					csRoom = new Room(room);
					if (csRoom != null) {
						csE?.objects?.Add(new WeakReference(csRoom));
					}
				} else {
					csRoom = (Room)GCHandle.FromIntPtr(csRoomPtr).Target;
				}
			}

			csE?._mIRegisterRemoteSpeakerEventListener?.OnRemoteSpeakerAdded(csRemoteSpeaker, csUser, csCall, csRoom);
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnRemoteSpeakerRemoved))]
#endif
		private static void OnRemoteSpeakerRemovedDelegate(IntPtr e, IntPtr remoteSpeaker, IntPtr user, IntPtr call, IntPtr room){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			RemoteSpeaker csRemoteSpeaker = null;
			if(remoteSpeaker != IntPtr.Zero) {
				var csRemoteSpeakerPtr = RemoteSpeaker.VidyoRemoteSpeakerGetUserDataNative(remoteSpeaker);
				if (csRemoteSpeakerPtr == IntPtr.Zero) {
					csRemoteSpeaker = new RemoteSpeaker(remoteSpeaker);
					if (csRemoteSpeaker != null) {
						csE?.objects?.Add(new WeakReference(csRemoteSpeaker));
					}
				} else {
					csRemoteSpeaker = (RemoteSpeaker)GCHandle.FromIntPtr(csRemoteSpeakerPtr).Target;
				}
			}

			User csUser = null;
			if(user != IntPtr.Zero) {
				var csUserPtr = User.VidyoUserGetUserDataNative(user);
				if (csUserPtr == IntPtr.Zero) {
					csUser = new User(user);
					if (csUser != null) {
						csE?.objects?.Add(new WeakReference(csUser));
					}
				} else {
					csUser = (User)GCHandle.FromIntPtr(csUserPtr).Target;
				}
			}

			Call csCall = null;
			if(call != IntPtr.Zero) {
				var csCallPtr = Call.VidyoCallGetUserDataNative(call);
				if (csCallPtr == IntPtr.Zero) {
					csCall = new Call(call);
					if (csCall != null) {
						csE?.objects?.Add(new WeakReference(csCall));
					}
				} else {
					csCall = (Call)GCHandle.FromIntPtr(csCallPtr).Target;
				}
			}

			Room csRoom = null;
			if(room != IntPtr.Zero) {
				var csRoomPtr = Room.VidyoRoomGetUserDataNative(room);
				if (csRoomPtr == IntPtr.Zero) {
					csRoom = new Room(room);
					if (csRoom != null) {
						csE?.objects?.Add(new WeakReference(csRoom));
					}
				} else {
					csRoom = (Room)GCHandle.FromIntPtr(csRoomPtr).Target;
				}
			}

			csE?._mIRegisterRemoteSpeakerEventListener?.OnRemoteSpeakerRemoved(csRemoteSpeaker, csUser, csCall, csRoom);
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnRemoteSpeakerStateUpdated))]
#endif
		private static void OnRemoteSpeakerStateUpdatedDelegate(IntPtr e, IntPtr remoteSpeaker, IntPtr user, IntPtr call, IntPtr room, Device.DeviceState state){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			RemoteSpeaker csRemoteSpeaker = null;
			if(remoteSpeaker != IntPtr.Zero) {
				var csRemoteSpeakerPtr = RemoteSpeaker.VidyoRemoteSpeakerGetUserDataNative(remoteSpeaker);
				if (csRemoteSpeakerPtr == IntPtr.Zero) {
					csRemoteSpeaker = new RemoteSpeaker(remoteSpeaker);
					if (csRemoteSpeaker != null) {
						csE?.objects?.Add(new WeakReference(csRemoteSpeaker));
					}
				} else {
					csRemoteSpeaker = (RemoteSpeaker)GCHandle.FromIntPtr(csRemoteSpeakerPtr).Target;
				}
			}

			User csUser = null;
			if(user != IntPtr.Zero) {
				var csUserPtr = User.VidyoUserGetUserDataNative(user);
				if (csUserPtr == IntPtr.Zero) {
					csUser = new User(user);
					if (csUser != null) {
						csE?.objects?.Add(new WeakReference(csUser));
					}
				} else {
					csUser = (User)GCHandle.FromIntPtr(csUserPtr).Target;
				}
			}

			Call csCall = null;
			if(call != IntPtr.Zero) {
				var csCallPtr = Call.VidyoCallGetUserDataNative(call);
				if (csCallPtr == IntPtr.Zero) {
					csCall = new Call(call);
					if (csCall != null) {
						csE?.objects?.Add(new WeakReference(csCall));
					}
				} else {
					csCall = (Call)GCHandle.FromIntPtr(csCallPtr).Target;
				}
			}

			Room csRoom = null;
			if(room != IntPtr.Zero) {
				var csRoomPtr = Room.VidyoRoomGetUserDataNative(room);
				if (csRoomPtr == IntPtr.Zero) {
					csRoom = new Room(room);
					if (csRoom != null) {
						csE?.objects?.Add(new WeakReference(csRoom));
					}
				} else {
					csRoom = (Room)GCHandle.FromIntPtr(csRoomPtr).Target;
				}
			}

			csE?._mIRegisterRemoteSpeakerEventListener?.OnRemoteSpeakerStateUpdated(csRemoteSpeaker, csUser, csCall, csRoom, state);
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnRemoteWindowShareAdded))]
#endif
		private static void OnRemoteWindowShareAddedDelegate(IntPtr e, IntPtr remoteWindowShare, IntPtr user, IntPtr call, IntPtr room, IntPtr participant){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			RemoteWindowShare csRemoteWindowShare = null;
			if(remoteWindowShare != IntPtr.Zero) {
				var csRemoteWindowSharePtr = RemoteWindowShare.VidyoRemoteWindowShareGetUserDataNative(remoteWindowShare);
				if (csRemoteWindowSharePtr == IntPtr.Zero) {
					csRemoteWindowShare = new RemoteWindowShare(remoteWindowShare);
					if (csRemoteWindowShare != null) {
						csE?.objects?.Add(new WeakReference(csRemoteWindowShare));
					}
				} else {
					csRemoteWindowShare = (RemoteWindowShare)GCHandle.FromIntPtr(csRemoteWindowSharePtr).Target;
				}
			}
			if(csE != null && csRemoteWindowShare != null)
				csE.GetRemoteWindowSharesMap()[csRemoteWindowShare.GetId()] = csRemoteWindowShare;

			User csUser = null;
			if(user != IntPtr.Zero) {
				var csUserPtr = User.VidyoUserGetUserDataNative(user);
				if (csUserPtr == IntPtr.Zero) {
					csUser = new User(user);
					if (csUser != null) {
						csE?.objects?.Add(new WeakReference(csUser));
					}
				} else {
					csUser = (User)GCHandle.FromIntPtr(csUserPtr).Target;
				}
			}

			Call csCall = null;
			if(call != IntPtr.Zero) {
				var csCallPtr = Call.VidyoCallGetUserDataNative(call);
				if (csCallPtr == IntPtr.Zero) {
					csCall = new Call(call);
					if (csCall != null) {
						csE?.objects?.Add(new WeakReference(csCall));
					}
				} else {
					csCall = (Call)GCHandle.FromIntPtr(csCallPtr).Target;
				}
			}

			Room csRoom = null;
			if(room != IntPtr.Zero) {
				var csRoomPtr = Room.VidyoRoomGetUserDataNative(room);
				if (csRoomPtr == IntPtr.Zero) {
					csRoom = new Room(room);
					if (csRoom != null) {
						csE?.objects?.Add(new WeakReference(csRoom));
					}
				} else {
					csRoom = (Room)GCHandle.FromIntPtr(csRoomPtr).Target;
				}
			}

			Participant csParticipant = null;
			if(participant != IntPtr.Zero) {
				var csParticipantPtr = Participant.VidyoParticipantGetUserDataNative(participant);
				if (csParticipantPtr == IntPtr.Zero) {
					csParticipant = new Participant(participant);
					if (csParticipant != null) {
						csE?.objects?.Add(new WeakReference(csParticipant));
					}
				} else {
					csParticipant = (Participant)GCHandle.FromIntPtr(csParticipantPtr).Target;
				}
			}

			csE?._mIRegisterRemoteWindowShareEventListener?.OnRemoteWindowShareAdded(csRemoteWindowShare, csUser, csCall, csRoom, csParticipant);
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnRemoteWindowShareFirstFrameReceived))]
#endif
		private static void OnRemoteWindowShareFirstFrameReceivedDelegate(IntPtr e, IntPtr remoteWindowShare){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			RemoteWindowShare csRemoteWindowShare = null;
			if(remoteWindowShare != IntPtr.Zero) {
				var csRemoteWindowSharePtr = RemoteWindowShare.VidyoRemoteWindowShareGetUserDataNative(remoteWindowShare);
				if (csRemoteWindowSharePtr == IntPtr.Zero) {
					csRemoteWindowShare = new RemoteWindowShare(remoteWindowShare);
					if (csRemoteWindowShare != null) {
						csE?.objects?.Add(new WeakReference(csRemoteWindowShare));
					}
				} else {
					csRemoteWindowShare = (RemoteWindowShare)GCHandle.FromIntPtr(csRemoteWindowSharePtr).Target;
				}
			}

			IRequestVideoForRemoteWindowShare cb = csE?.GetOnRemoteWindowShareFirstFrameReceivedCallbacksMap()?[csRemoteWindowShare?.GetId() ?? string.Empty];
			csE?.GetOnRemoteWindowShareFirstFrameReceivedCallbacksMap()?.Remove(csRemoteWindowShare?.GetId() ?? string.Empty);
			cb?.OnRemoteWindowShareFirstFrameReceived(csRemoteWindowShare);
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnRemoteWindowShareFrame))]
#endif
		private static void OnRemoteWindowShareFrameDelegate(IntPtr e, IntPtr remoteWindowShare, IntPtr participant, IntPtr videoFrame){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			RemoteWindowShare csRemoteWindowShare = null;
			if(remoteWindowShare != IntPtr.Zero) {
				var csRemoteWindowSharePtr = RemoteWindowShare.VidyoRemoteWindowShareGetUserDataNative(remoteWindowShare);
				if (csRemoteWindowSharePtr == IntPtr.Zero) {
					csRemoteWindowShare = new RemoteWindowShare(remoteWindowShare);
					if (csRemoteWindowShare != null) {
						csE?.objects?.Add(new WeakReference(csRemoteWindowShare));
					}
				} else {
					csRemoteWindowShare = (RemoteWindowShare)GCHandle.FromIntPtr(csRemoteWindowSharePtr).Target;
				}
			}

			Participant csParticipant = null;
			if(participant != IntPtr.Zero) {
				var csParticipantPtr = Participant.VidyoParticipantGetUserDataNative(participant);
				if (csParticipantPtr == IntPtr.Zero) {
					csParticipant = new Participant(participant);
					if (csParticipant != null) {
						csE?.objects?.Add(new WeakReference(csParticipant));
					}
				} else {
					csParticipant = (Participant)GCHandle.FromIntPtr(csParticipantPtr).Target;
				}
			}

			VideoFrame csVideoFrame = null;
			if(videoFrame != IntPtr.Zero) {
				var csVideoFramePtr = VideoFrame.VidyoVideoFrameGetUserDataNative(videoFrame);
				csVideoFrame = csVideoFramePtr == IntPtr.Zero ? new VideoFrame(videoFrame) : (VideoFrame)GCHandle.FromIntPtr(csVideoFramePtr).Target;
			}

			csE?._mIRegisterRemoteWindowShareFrameListener?.OnRemoteWindowShareFrame(csRemoteWindowShare, csParticipant, csVideoFrame);
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnRemoteWindowShareRemoved))]
#endif
		private static void OnRemoteWindowShareRemovedDelegate(IntPtr e, IntPtr remoteWindowShare, IntPtr user, IntPtr call, IntPtr room, IntPtr participant){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			RemoteWindowShare csRemoteWindowShare = null;
			if(remoteWindowShare != IntPtr.Zero) {
				var csRemoteWindowSharePtr = RemoteWindowShare.VidyoRemoteWindowShareGetUserDataNative(remoteWindowShare);
				if (csRemoteWindowSharePtr == IntPtr.Zero) {
					csRemoteWindowShare = new RemoteWindowShare(remoteWindowShare);
					if (csRemoteWindowShare != null) {
						csE?.objects?.Add(new WeakReference(csRemoteWindowShare));
					}
				} else {
					csRemoteWindowShare = (RemoteWindowShare)GCHandle.FromIntPtr(csRemoteWindowSharePtr).Target;
				}
			}
			csE?.GetRemoteWindowSharesMap()?.Remove(csRemoteWindowShare?.GetId() ?? string.Empty);

			User csUser = null;
			if(user != IntPtr.Zero) {
				var csUserPtr = User.VidyoUserGetUserDataNative(user);
				if (csUserPtr == IntPtr.Zero) {
					csUser = new User(user);
					if (csUser != null) {
						csE?.objects?.Add(new WeakReference(csUser));
					}
				} else {
					csUser = (User)GCHandle.FromIntPtr(csUserPtr).Target;
				}
			}

			Call csCall = null;
			if(call != IntPtr.Zero) {
				var csCallPtr = Call.VidyoCallGetUserDataNative(call);
				if (csCallPtr == IntPtr.Zero) {
					csCall = new Call(call);
					if (csCall != null) {
						csE?.objects?.Add(new WeakReference(csCall));
					}
				} else {
					csCall = (Call)GCHandle.FromIntPtr(csCallPtr).Target;
				}
			}

			Room csRoom = null;
			if(room != IntPtr.Zero) {
				var csRoomPtr = Room.VidyoRoomGetUserDataNative(room);
				if (csRoomPtr == IntPtr.Zero) {
					csRoom = new Room(room);
					if (csRoom != null) {
						csE?.objects?.Add(new WeakReference(csRoom));
					}
				} else {
					csRoom = (Room)GCHandle.FromIntPtr(csRoomPtr).Target;
				}
			}

			Participant csParticipant = null;
			if(participant != IntPtr.Zero) {
				var csParticipantPtr = Participant.VidyoParticipantGetUserDataNative(participant);
				if (csParticipantPtr == IntPtr.Zero) {
					csParticipant = new Participant(participant);
					if (csParticipant != null) {
						csE?.objects?.Add(new WeakReference(csParticipant));
					}
				} else {
					csParticipant = (Participant)GCHandle.FromIntPtr(csParticipantPtr).Target;
				}
			}

			csE?._mIRegisterRemoteWindowShareEventListener?.OnRemoteWindowShareRemoved(csRemoteWindowShare, csUser, csCall, csRoom, csParticipant);
			if(csE?._mIRegisterRemoteWindowShareEventListener == null) csRemoteWindowShare?.Dispose();
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnRemoteWindowShareStateUpdated))]
#endif
		private static void OnRemoteWindowShareStateUpdatedDelegate(IntPtr e, IntPtr remoteWindowShare, IntPtr user, IntPtr call, IntPtr room, IntPtr participant, Device.DeviceState state){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			RemoteWindowShare csRemoteWindowShare = null;
			if(remoteWindowShare != IntPtr.Zero) {
				var csRemoteWindowSharePtr = RemoteWindowShare.VidyoRemoteWindowShareGetUserDataNative(remoteWindowShare);
				if (csRemoteWindowSharePtr == IntPtr.Zero) {
					csRemoteWindowShare = new RemoteWindowShare(remoteWindowShare);
					if (csRemoteWindowShare != null) {
						csE?.objects?.Add(new WeakReference(csRemoteWindowShare));
					}
				} else {
					csRemoteWindowShare = (RemoteWindowShare)GCHandle.FromIntPtr(csRemoteWindowSharePtr).Target;
				}
			}

			User csUser = null;
			if(user != IntPtr.Zero) {
				var csUserPtr = User.VidyoUserGetUserDataNative(user);
				if (csUserPtr == IntPtr.Zero) {
					csUser = new User(user);
					if (csUser != null) {
						csE?.objects?.Add(new WeakReference(csUser));
					}
				} else {
					csUser = (User)GCHandle.FromIntPtr(csUserPtr).Target;
				}
			}

			Call csCall = null;
			if(call != IntPtr.Zero) {
				var csCallPtr = Call.VidyoCallGetUserDataNative(call);
				if (csCallPtr == IntPtr.Zero) {
					csCall = new Call(call);
					if (csCall != null) {
						csE?.objects?.Add(new WeakReference(csCall));
					}
				} else {
					csCall = (Call)GCHandle.FromIntPtr(csCallPtr).Target;
				}
			}

			Room csRoom = null;
			if(room != IntPtr.Zero) {
				var csRoomPtr = Room.VidyoRoomGetUserDataNative(room);
				if (csRoomPtr == IntPtr.Zero) {
					csRoom = new Room(room);
					if (csRoom != null) {
						csE?.objects?.Add(new WeakReference(csRoom));
					}
				} else {
					csRoom = (Room)GCHandle.FromIntPtr(csRoomPtr).Target;
				}
			}

			Participant csParticipant = null;
			if(participant != IntPtr.Zero) {
				var csParticipantPtr = Participant.VidyoParticipantGetUserDataNative(participant);
				if (csParticipantPtr == IntPtr.Zero) {
					csParticipant = new Participant(participant);
					if (csParticipant != null) {
						csE?.objects?.Add(new WeakReference(csParticipant));
					}
				} else {
					csParticipant = (Participant)GCHandle.FromIntPtr(csParticipantPtr).Target;
				}
			}

			csE?._mIRegisterRemoteWindowShareEventListener?.OnRemoteWindowShareStateUpdated(csRemoteWindowShare, csUser, csCall, csRoom, csParticipant, state);
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnVirtualAudioSourceAdded))]
#endif
		private static void OnVirtualAudioSourceAddedDelegate(IntPtr e, IntPtr virtualAudioSource){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			VirtualAudioSource csVirtualAudioSource = null;
			if(virtualAudioSource != IntPtr.Zero) {
				var csVirtualAudioSourcePtr = VirtualAudioSource.VidyoVirtualAudioSourceGetUserDataNative(virtualAudioSource);
				if (csVirtualAudioSourcePtr == IntPtr.Zero) {
					csVirtualAudioSource = new VirtualAudioSource(virtualAudioSource);
					if (csVirtualAudioSource != null) {
						csE?.objects?.Add(new WeakReference(csVirtualAudioSource));
					}
				} else {
					csVirtualAudioSource = (VirtualAudioSource)GCHandle.FromIntPtr(csVirtualAudioSourcePtr).Target;
				}
			}

			csE?._mIRegisterVirtualAudioSourceEventListener?.OnVirtualAudioSourceAdded(csVirtualAudioSource);
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnVirtualAudioSourceExternalMediaBufferReleased))]
#endif
		private static void OnVirtualAudioSourceExternalMediaBufferReleasedDelegate(IntPtr e, IntPtr virtualAudioSource, IntPtr buffer, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(SizeTMarshaler))]SizeT size){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			VirtualAudioSource csVirtualAudioSource = null;
			if(virtualAudioSource != IntPtr.Zero) {
				var csVirtualAudioSourcePtr = VirtualAudioSource.VidyoVirtualAudioSourceGetUserDataNative(virtualAudioSource);
				if (csVirtualAudioSourcePtr == IntPtr.Zero) {
					csVirtualAudioSource = new VirtualAudioSource(virtualAudioSource);
					if (csVirtualAudioSource != null) {
						csE?.objects?.Add(new WeakReference(csVirtualAudioSource));
					}
				} else {
					csVirtualAudioSource = (VirtualAudioSource)GCHandle.FromIntPtr(csVirtualAudioSourcePtr).Target;
				}
			}

			var pointer = ByteArrayHelperSingleton.RawPointerToByteArray(buffer);
			csE?._mIRegisterVirtualAudioSourceEventListener?.OnVirtualAudioSourceExternalMediaBufferReleased(csVirtualAudioSource, pointer, size);
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnVirtualAudioSourceRemoved))]
#endif
		private static void OnVirtualAudioSourceRemovedDelegate(IntPtr e, IntPtr virtualAudioSource){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			VirtualAudioSource csVirtualAudioSource = null;
			if(virtualAudioSource != IntPtr.Zero) {
				var csVirtualAudioSourcePtr = VirtualAudioSource.VidyoVirtualAudioSourceGetUserDataNative(virtualAudioSource);
				if (csVirtualAudioSourcePtr == IntPtr.Zero) {
					csVirtualAudioSource = new VirtualAudioSource(virtualAudioSource);
					if (csVirtualAudioSource != null) {
						csE?.objects?.Add(new WeakReference(csVirtualAudioSource));
					}
				} else {
					csVirtualAudioSource = (VirtualAudioSource)GCHandle.FromIntPtr(csVirtualAudioSourcePtr).Target;
				}
			}

			csE?._mIRegisterVirtualAudioSourceEventListener?.OnVirtualAudioSourceRemoved(csVirtualAudioSource);
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnVirtualAudioSourceSelected))]
#endif
		private static void OnVirtualAudioSourceSelectedDelegate(IntPtr e, IntPtr virtualAudioSource){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			VirtualAudioSource csVirtualAudioSource = null;
			if(virtualAudioSource != IntPtr.Zero) {
				var csVirtualAudioSourcePtr = VirtualAudioSource.VidyoVirtualAudioSourceGetUserDataNative(virtualAudioSource);
				if (csVirtualAudioSourcePtr == IntPtr.Zero) {
					csVirtualAudioSource = new VirtualAudioSource(virtualAudioSource);
					if (csVirtualAudioSource != null) {
						csE?.objects?.Add(new WeakReference(csVirtualAudioSource));
					}
				} else {
					csVirtualAudioSource = (VirtualAudioSource)GCHandle.FromIntPtr(csVirtualAudioSourcePtr).Target;
				}
			}

			csE?._mIRegisterVirtualAudioSourceEventListener?.OnVirtualAudioSourceSelected(csVirtualAudioSource);
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnVirtualAudioSourceStateUpdated))]
#endif
		private static void OnVirtualAudioSourceStateUpdatedDelegate(IntPtr e, IntPtr virtualAudioSource, Device.DeviceState state){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			VirtualAudioSource csVirtualAudioSource = null;
			if(virtualAudioSource != IntPtr.Zero) {
				var csVirtualAudioSourcePtr = VirtualAudioSource.VidyoVirtualAudioSourceGetUserDataNative(virtualAudioSource);
				if (csVirtualAudioSourcePtr == IntPtr.Zero) {
					csVirtualAudioSource = new VirtualAudioSource(virtualAudioSource);
					if (csVirtualAudioSource != null) {
						csE?.objects?.Add(new WeakReference(csVirtualAudioSource));
					}
				} else {
					csVirtualAudioSource = (VirtualAudioSource)GCHandle.FromIntPtr(csVirtualAudioSourcePtr).Target;
				}
			}

			csE?._mIRegisterVirtualAudioSourceEventListener?.OnVirtualAudioSourceStateUpdated(csVirtualAudioSource, state);
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnVirtualVideoSourceAdded))]
#endif
		private static void OnVirtualVideoSourceAddedDelegate(IntPtr e, IntPtr virtualVideoSource){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			VirtualVideoSource csVirtualVideoSource = null;
			if(virtualVideoSource != IntPtr.Zero) {
				var csVirtualVideoSourcePtr = VirtualVideoSource.VidyoVirtualVideoSourceGetUserDataNative(virtualVideoSource);
				if (csVirtualVideoSourcePtr == IntPtr.Zero) {
					csVirtualVideoSource = new VirtualVideoSource(virtualVideoSource);
					if (csVirtualVideoSource != null) {
						csE?.objects?.Add(new WeakReference(csVirtualVideoSource));
					}
				} else {
					csVirtualVideoSource = (VirtualVideoSource)GCHandle.FromIntPtr(csVirtualVideoSourcePtr).Target;
				}
			}

			csE?._mIRegisterVirtualVideoSourceEventListener?.OnVirtualVideoSourceAdded(csVirtualVideoSource);
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnVirtualVideoSourceExternalMediaBufferReleased))]
#endif
		private static void OnVirtualVideoSourceExternalMediaBufferReleasedDelegate(IntPtr e, IntPtr virtualVideoSource, IntPtr buffer, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(SizeTMarshaler))]SizeT size){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			VirtualVideoSource csVirtualVideoSource = null;
			if(virtualVideoSource != IntPtr.Zero) {
				var csVirtualVideoSourcePtr = VirtualVideoSource.VidyoVirtualVideoSourceGetUserDataNative(virtualVideoSource);
				if (csVirtualVideoSourcePtr == IntPtr.Zero) {
					csVirtualVideoSource = new VirtualVideoSource(virtualVideoSource);
					if (csVirtualVideoSource != null) {
						csE?.objects?.Add(new WeakReference(csVirtualVideoSource));
					}
				} else {
					csVirtualVideoSource = (VirtualVideoSource)GCHandle.FromIntPtr(csVirtualVideoSourcePtr).Target;
				}
			}

			var pointer = ByteArrayHelperSingleton.RawPointerToByteArray(buffer);
			csE?._mIRegisterVirtualVideoSourceEventListener?.OnVirtualVideoSourceExternalMediaBufferReleased(csVirtualVideoSource, pointer, size);
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnVirtualVideoSourceRemoved))]
#endif
		private static void OnVirtualVideoSourceRemovedDelegate(IntPtr e, IntPtr virtualVideoSource){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			VirtualVideoSource csVirtualVideoSource = null;
			if(virtualVideoSource != IntPtr.Zero) {
				var csVirtualVideoSourcePtr = VirtualVideoSource.VidyoVirtualVideoSourceGetUserDataNative(virtualVideoSource);
				if (csVirtualVideoSourcePtr == IntPtr.Zero) {
					csVirtualVideoSource = new VirtualVideoSource(virtualVideoSource);
					if (csVirtualVideoSource != null) {
						csE?.objects?.Add(new WeakReference(csVirtualVideoSource));
					}
				} else {
					csVirtualVideoSource = (VirtualVideoSource)GCHandle.FromIntPtr(csVirtualVideoSourcePtr).Target;
				}
			}

			csE?._mIRegisterVirtualVideoSourceEventListener?.OnVirtualVideoSourceRemoved(csVirtualVideoSource);
		}
#if __IOS__
[ObjCRuntime.MonoPInvokeCallback(typeof(OnVirtualVideoSourceStateUpdated))]
#endif
		private static void OnVirtualVideoSourceStateUpdatedDelegate(IntPtr e, IntPtr virtualVideoSource, Device.DeviceState state){
			var csEPtr = e != IntPtr.Zero ? VidyoEndpointGetUserDataNative(e) : IntPtr.Zero;
			if(csEPtr == IntPtr.Zero) return;
			var csE = (Endpoint)GCHandle.FromIntPtr(csEPtr).Target;

			VirtualVideoSource csVirtualVideoSource = null;
			if(virtualVideoSource != IntPtr.Zero) {
				var csVirtualVideoSourcePtr = VirtualVideoSource.VidyoVirtualVideoSourceGetUserDataNative(virtualVideoSource);
				if (csVirtualVideoSourcePtr == IntPtr.Zero) {
					csVirtualVideoSource = new VirtualVideoSource(virtualVideoSource);
					if (csVirtualVideoSource != null) {
						csE?.objects?.Add(new WeakReference(csVirtualVideoSource));
					}
				} else {
					csVirtualVideoSource = (VirtualVideoSource)GCHandle.FromIntPtr(csVirtualVideoSourcePtr).Target;
				}
			}

			csE?._mIRegisterVirtualVideoSourceEventListener?.OnVirtualVideoSourceStateUpdated(csVirtualVideoSource, state);
		}
	};
}
