public AndroidBillingTransaction(IDictionary _transactionInfo)
        {
            IDictionary _originalJSON = _transactionInfo[kOriginalJSON] as IDictionary;

            // Set raw response
            RawPurchaseData			= _originalJSON.ToJSON();

            // Assign values
            ProductIdentifier		= _originalJSON.GetIfAvailable<string>(kProductID);

            // Transaction time
            long _purchaseTimeInMillis		= _originalJSON.GetIfAvailable<long>(kPurchaseTime);
            System.DateTime _purchaseDate 	= _purchaseTimeInMillis.ToDateTimeFromJavaTime();
            TransactionDateUTC				= _purchaseDate.ToUniversalTime();
            TransactionDateLocal			= _purchaseDate.ToLocalTime();

            TransactionIdentifier			= GetPurchaseIdentifier(_originalJSON);
            int _purchaseState 				= _originalJSON.GetIfAvailable<int>(kPurchaseState);
            TransactionState				= GetConvertedPurchaseState(_purchaseState);

            // Data from _transactionInfo
            TransactionReceipt				= _transactionInfo.GetIfAvailable<string>(kSignature);

            //First find out if the transaction is valid
            string _validationState 		= _transactionInfo.GetIfAvailable<string>(kPurchaseValidationState);
            VerificationState 				= GetValidationState(_validationState);

            // Error
            Error							= _transactionInfo.GetIfAvailable<string>(kError);
        }
			internal iOSSpecificProperties (IDictionary _jsonDict)
			{
				AlertAction	= _jsonDict.GetIfAvailable<string>(kAlertActionKey);
				HasAction	= _jsonDict.GetIfAvailable<bool>(kHasActionKey);
				BadgeCount	= _jsonDict.GetIfAvailable<int>(kBadgeCountKey);
				LaunchImage	= _jsonDict.GetIfAvailable<string>(kLaunchImageKey);
			}
		protected override void RequestForImageFinished (IDictionary _dataDict)
		{
			string		_error	= _dataDict.GetIfAvailable<string>(EditorGameCenter.kErrorKey);
			Texture2D	_image	= _dataDict.GetIfAvailable<Texture2D>(EditorGameCenter.kImageKey);

			DownloadImageFinished(_image, _error);
		}
		public AndroidAddressBookContact (IDictionary _contactInfoJsontDict)
		{
			//If Given Name is available set it. Else pick from Display Name
			string _displayName = _contactInfoJsontDict.GetIfAvailable<string>(kDisplayName);
			string _givenName 	= _contactInfoJsontDict.GetIfAvailable<string>(kGivenName);
			string _familyName 	= _contactInfoJsontDict.GetIfAvailable<string>(kFamilyName);
		
			if(string.IsNullOrEmpty(_displayName))
			{
				_displayName = "";
			}

			FirstName 		= _givenName;
			LastName 		= _familyName;
			ImagePath		= _contactInfoJsontDict[kImagePath] as string;
			PhoneNumberList	= new List<string>();
			EmailIDList		= new List<string>();
			
			// Add phone numbers
			IList _phoneNumJsonList	= _contactInfoJsontDict[kPhoneNumList] as IList;
			foreach (string _phoneNo in _phoneNumJsonList)
				PhoneNumberList.Add(_phoneNo);
			
			// Add email id's
			IList _emailIDJsonList	= _contactInfoJsontDict[kEmailList] as IList;
			foreach (string _emailID in _emailIDJsonList)
				EmailIDList.Add(_emailID);
		}
		public iOSTwitterSession (IDictionary _sessionJsonDict)
		{
			AuthToken		= _sessionJsonDict.GetIfAvailable<string>(kAuthToken);
			AuthTokenSecret	= _sessionJsonDict.GetIfAvailable<string>(kAuthTokenSecret);
			UserName		= _sessionJsonDict.GetIfAvailable<string>(kUserName);
			UserID			= _sessionJsonDict.GetIfAvailable<string>(kUserID);
		}
		public iOSBillingTransaction (IDictionary _transactionJsonDict)
		{
			ProductIdentifier		= _transactionJsonDict.GetIfAvailable<string>(kProductID);

			// Transaction date can be NULL/Empty
			string 	_tDateStr		= _transactionJsonDict.GetIfAvailable<string>(kTransactionDate);

			if (!string.IsNullOrEmpty(_tDateStr))
			{
				TransactionDateUTC		= _tDateStr.ToZuluFormatDateTimeUTC();
				TransactionDateLocal	= TransactionDateUTC.ToLocalTime();
			}

			// Transaction identifier
			TransactionIdentifier	= _transactionJsonDict.GetIfAvailable<string>(kTransactionID);

			// Transaction receipt can be NULL/Empty
			TransactionReceipt		= _transactionJsonDict.GetIfAvailable<string>(kTransactionReceipt);

			// Transactions state
			SKPaymentTransactionState _skTransactionState	= (SKPaymentTransactionState)int.Parse(_transactionJsonDict[kTransactionState].ToString());
			TransactionState		= ConvertToBillingTransactionState(_skTransactionState);

			// Verifications state
			VerificationState		= (eBillingTransactionVerificationState)int.Parse(_transactionJsonDict[kVerificationState].ToString());

			// Error can be NULL/Empty
			Error					= _transactionJsonDict.GetIfAvailable<string>(kError);		

			// Set response which is sent from Native side
			RawPurchaseData			= _transactionJsonDict.ToJSON();
		}
		public AndroidBillingProduct (IDictionary _productJsonDict)
		{
			ProductIdentifier	= _productJsonDict[kProductID] as string;
			Name				= _productJsonDict[kTitle] as string;
			Description			= _productJsonDict[kDescription] as string;
			Price				= _productJsonDict.GetIfAvailable<long>(kPriceAmount)/1000000.0f;//As the value is in microns
			LocalizedPrice		= _productJsonDict.GetIfAvailable<string>(kLocalizedPrice);
		}
		public iOSBillingProduct (IDictionary _productJsonDict)
		{
			Name				= _productJsonDict.GetIfAvailable<string>(kTitle);
			ProductIdentifier	= _productJsonDict.GetIfAvailable<string>(kProductID);
			Description			= _productJsonDict.GetIfAvailable<string>(kDescription);
			Price				= _productJsonDict.GetIfAvailable<float>(kPrice);
			LocalizedPrice		= _productJsonDict.GetIfAvailable<string>(kLocalizedPrice);
		}
		public AndroidTwitterUser (IDictionary _userJsonDict)
		{
			UserID					= _userJsonDict[kUserID] as string;
			Name					= _userJsonDict[kName] as string;
			IsVerified				= _userJsonDict.GetIfAvailable<bool>(kIsVerified);
			IsProtected				= _userJsonDict.GetIfAvailable<bool>(kIsProtected);
			ProfileImageURL			= _userJsonDict[kProfileImageURL] as string;
		}
		public iOSTwitterUser (IDictionary _userJsonDict)
		{
			UserID					= _userJsonDict.GetIfAvailable<string>(kUserID);
			Name					= _userJsonDict.GetIfAvailable<string>(kName);
			IsVerified				= _userJsonDict.GetIfAvailable<bool>(kIsVerified);
			IsProtected				= _userJsonDict.GetIfAvailable<bool>(kIsProtected);
			ProfileImageURL			= _userJsonDict.GetIfAvailable<string>(kProfileImageURL);
		}
		public iOSNotificationPayload (IDictionary _payloadDict)
		{
			IDictionary _apsDict			= _payloadDict[kAPS] as IDictionary;
			string 		_userInfoKey		= NPSettings.Notification.iOS.UserInfoKey;
			iOSProperties					= new iOSSpecificProperties();

			// Read alert info
			if (_apsDict.Contains(kAlert))
			{
				object 	_alertUnknownType	= _apsDict[kAlert] as object;
			
				if (_alertUnknownType != null)
				{
					// String format
					if ((_alertUnknownType as string) != null)
					{
						AlertBody						= _alertUnknownType as string;
					}
					// Dictionary format
					else
					{
						IDictionary _alertDict			= _alertUnknownType as IDictionary;
						AlertBody						= _alertDict.GetIfAvailable<string>(kBody);
						string 		_alertAction		= _alertDict.GetIfAvailable<string>(kAction);

						if (string.IsNullOrEmpty(_alertAction))
						{
							iOSProperties.AlertAction	= null;
							iOSProperties.HasAction		= false;
						}
						else
						{
							iOSProperties.AlertAction	= _alertAction;
							iOSProperties.HasAction		= true;
						}

						// Launch image
						iOSProperties.LaunchImage		= _alertDict.GetIfAvailable<string>(kLaunchImage);
					}
				}
			}

			// Read sound, badge info
			iOSProperties.SoundName		=  _apsDict.GetIfAvailable<string>(kSound);
			iOSProperties.BadgeCount	=  _apsDict.GetIfAvailable<int>(kBadge);

			// Read user info
			if (_apsDict.Contains(_userInfoKey))
				UserInfo				= _payloadDict[_userInfoKey] as IDictionary;
			
			// Read fire date, repeat interval
			string 	_fireDateStr		= _payloadDict.GetIfAvailable<string>(kFireDate);

			if (!string.IsNullOrEmpty(_fireDateStr))
				FireDate				= _fireDateStr.ToDateTimeLocalUsingZuluFormat();

			RepeatInterval				= ConvertToRepeatInterval(_payloadDict.GetIfAvailable<CalendarUnit>(kRepeatIntervalKey));
		}
		internal AndroidUser (IDictionary _userProfileData)
		{
			if(_userProfileData != null)
			{
				m_identifier		= _userProfileData.GetIfAvailable<string>(kIdentifier);
				m_name				= _userProfileData.GetIfAvailable<string>(kName);
				m_imagePath			= _userProfileData.GetIfAvailable<string>(kHighResImageURL);
			}
		}
		protected override void LoadUsersFinished (IDictionary _dataDict)
		{
			EGCUser[]			_gcUsers			= _dataDict.GetIfAvailable<EGCUser[]>(EditorGameCenter.kUsersListKey);
			string 				_error				= _dataDict.GetIfAvailable<string>(EditorGameCenter.kErrorKey);
			User[]				_newUsers			= EditorUser.ConvertUsersList(_gcUsers);
			
			// Invoke handler
			LoadUsersFinished(_newUsers, _error);
		}
		protected override void LoadAchievementsFinished (IDictionary _dataDict)
		{
			EGCAchievement[]			_gcAchievements			= _dataDict.GetIfAvailable<EGCAchievement[]>(EditorGameCenter.kAchievementsListKey);
			string 						_error					= _dataDict.GetIfAvailable<string>(EditorGameCenter.kErrorKey);
			Achievement[]				_newAchievements		= EditorAchievement.ConvertAchievementsList(_gcAchievements);
			
			// Invoke handler
			LoadAchievementsFinished(_newAchievements, _error);
		}
		protected override void LoadAchievementsFinished (IDictionary _dataDict)
		{
			IList			_achievementsJSONList	= _dataDict.GetIfAvailable<IList>(kAchievementsListKey);
			string 			_error					= _dataDict.GetIfAvailable<string>(GameServicesIOS.kNativeMessageErrorKey);
			Achievement[]	_newAchievements		= iOSAchievement.ConvertAchievementsList(_achievementsJSONList);
			
			// Invoke handler
			LoadAchievementsFinished(_newAchievements, _error);
		}
		public iOSNotificationPayload (IDictionary _payloadDict)
		{
			iOSProperties					= new iOSSpecificProperties();
			string 		_userInfoKey		= NPSettings.Notification.iOS.UserInfoKey;
			IDictionary _apsDict			= _payloadDict[kAPS] as IDictionary;

			// Read alert info from aps dictionary
			if (_apsDict.Contains(kAlert))
			{
				object 	_alertUnknownType	= _apsDict[kAlert] as object;
			
				if (_alertUnknownType != null)
				{
					// String format
					if ((_alertUnknownType as string) != null)
					{
						AlertBody						= _alertUnknownType as string;
					}
					// Dictionary format
					else
					{
						IDictionary _alertDict			= _alertUnknownType as IDictionary;
						string		_alertAction		= _alertDict.GetIfAvailable<string>(kAction);
						bool		_hasAction			= false;

						if (_alertDict.Contains(kHasAction))
							_hasAction					= System.Convert.ToBoolean(_alertDict[kHasAction]);
						else
							_hasAction					= (_alertAction != null);

						// Set properties
						AlertBody						= _alertDict.GetIfAvailable<string>(kBody);
						iOSProperties.AlertAction		= _alertAction;
						iOSProperties.HasAction			= _hasAction;
						iOSProperties.LaunchImage		= _alertDict.GetIfAvailable<string>(kLaunchImage);
					}
				}
			}

			// Read sound, badge info from aps dictionary
			SoundName					=  _apsDict.GetIfAvailable<string>(kSound);
			iOSProperties.BadgeCount	=  _apsDict.GetIfAvailable<int>(kBadge);

			// Read user info from payload dictionary
			UserInfo					= _payloadDict.GetIfAvailable<IDictionary>(_userInfoKey);

			// Read fire date, repeat interval from payload dictionary
			string 	_fireDateStr		= _payloadDict.GetIfAvailable<string>(kFireDate);
			
			if (_fireDateStr != null)
				FireDate				= _fireDateStr.ToZuluFormatDateTimeLocal();
			
			RepeatInterval				= ConvertToRepeatInterval(_payloadDict.GetIfAvailable<CalendarUnit>(kRepeatIntervalKey));
		}
		protected override void ParsePickImageFinishedData (IDictionary _infoDict, out string _selectedImagePath, out ePickImageFinishReason _finishReason)
		{
			_selectedImagePath	= _infoDict.GetIfAvailable<string>(kImagePath);
			_finishReason		=  kPickImageParseMap[_infoDict.GetIfAvailable<string>(kFinishReason)];
			
			// Selected image path is invalid
			if (string.IsNullOrEmpty(_selectedImagePath))
			{
				_selectedImagePath	= null;
				_finishReason		= ePickImageFinishReason.FAILED;
			}
		}
		internal AndroidScore (IDictionary _scoreData)
		{
			LeaderboardID			= _scoreData.GetIfAvailable<string>(kIdentifier);	
			LeaderboardGlobalID		= GameServicesIDHandler.GetLeaderboardGID(LeaderboardID);
			
			User					= new AndroidUser(_scoreData.GetIfAvailable<Dictionary<string, object>>(kUser));
			Value					= _scoreData.GetIfAvailable<long>(kValue);

			long _timeInMillis		= _scoreData.GetIfAvailable<long>(kDate);
			Date 					= _timeInMillis.ToDateTimeFromJavaTime();

			Rank					= _scoreData.GetIfAvailable<int>(kRank);
		}
		internal ProductUpdateInfo (string _currentVersion, IDictionary _dataDict) : this ()
		{
			string _availableVersion	= _dataDict.GetIfAvailable<string>(kVersionNumberKey);
			string _downloadLink		= _dataDict.GetIfAvailable<string>(kDownloadLinkKey);
			string _assetStoreLink		= _dataDict.GetIfAvailable<string>(kAssetStoreLink);
			string _releaseNote			= _dataDict.GetIfAvailable<string>(kReleaseNoteKey);
			
			// Update class properties
			NewUpdateAvailable			= (_availableVersion.CompareTo(_currentVersion) > 0);
			VersionNumber				= _availableVersion;
			DownloadLink				= _downloadLink;
			AssetStoreLink				= _assetStoreLink;
			ReleaseNote					= _releaseNote;
		}
		protected override void LoadAchievementsFinished (IDictionary _dataDict)
		{
			IList			_achievementsJSONList	= _dataDict.GetIfAvailable<IList>(kAchievementsList);
			string 			_error					= _dataDict.GetIfAvailable<string>(kNativeMessageError);
			Achievement[]	_newAchievements		= null;
			

			if (_achievementsJSONList != null)
			{
				_newAchievements	=	AndroidAchievement.ConvertAchievementList(_achievementsJSONList);
			}
			
			LoadAchievementsFinished(_newAchievements, _error);
		}
		protected override void ReportScoreFinished (IDictionary _dataDict)
		{
			string		_error			= _dataDict.GetIfAvailable<string>(EditorGameCenter.kErrorKey);
			EGCScore	_gcScoreInfo	= _dataDict.GetIfAvailable<EGCScore>(EditorGameCenter.kScoreInfoKey);
			
			if (_gcScoreInfo != null)
			{
				// Update properties
				Value	= _gcScoreInfo.Value;
				Date	= _gcScoreInfo.Date;
				Rank	= _gcScoreInfo.Rank;
			}
			
			ReportScoreFinished(_error == null, _error);
		}
		public iOSScore (IDictionary _dataDict) : base ()
		{
			// Parse data dictionary values
			string		_leaderboardID	= _dataDict.GetIfAvailable<string>(kLeaderboardIdentifierKey);
			IDictionary _userDataDict	= _dataDict.GetIfAvailable<IDictionary>(kPlayerKey);

			LeaderboardGlobalID		= GameServicesIDHandler.GetLeaderboardGID(_leaderboardID);
			LeaderboardID			= _leaderboardID;
			Value					= _dataDict.GetIfAvailable<long>(kValueKey);
			Date					= _dataDict.GetIfAvailable<string>(kDateKey).ToZuluFormatDateTimeLocal();
			Rank					= _dataDict.GetIfAvailable<int>(kRankKey);

			if (_userDataDict != null)
				User				= new iOSUser(_userDataDict);
		}
		protected override void LoadAchievementDescriptionsFinished (IDictionary _dataDict)
		{
			IList			_descriptionsJSONList	= _dataDict.GetIfAvailable<List<object>>(kAchievementsList);//On Android desc's are also in Achievement details.
			string 			_error					= _dataDict.GetIfAvailable<string>(kNativeMessageError);
			AchievementDescription[]	_newDescriptions	= null;

			Debug.Log("LoadAchievementDescriptionsFinished [IDictionary] " + _descriptionsJSONList.ToJSON());
			
			if (_descriptionsJSONList != null)
			{
				_newDescriptions = AndroidAchievementDescription.ConvertAchievementDescriptionList(_descriptionsJSONList);
			}
			
			LoadAchievementDescriptionsFinished(_newDescriptions, _error);
		}
		protected override void RequestForAchievementImageFinished (IDictionary _dataDict)
		{
			string			_instanceID				= _dataDict.GetIfAvailable<string>(kObjectInstanceIDKey);

			// Invoke handler
			RequestForAchievementImageFinished(_instanceID, _dataDict);
		}
		protected override void ReportProgressFinished (IDictionary _dataDict)
		{
			string			_instanceID				= _dataDict.GetIfAvailable<string>(kObjectInstanceIDKey);

			// Invoke handler
			ReportProgressFinished(_instanceID, _dataDict);
		}
		public iOSWebViewMessage (IDictionary _schemeDataJsonDict)
		{
			string _schemeName	= _schemeDataJsonDict.GetIfAvailable<string>(kURLScheme);
			string _host		= _schemeDataJsonDict.GetIfAvailable<string>(kHost);
			IDictionary _args	= _schemeDataJsonDict[kArguments] as IDictionary;

			// Assign value
			SchemeName			= _schemeName;
			Host				= _host;
			Arguments			= new Dictionary<string, string>();

			foreach (object _key in _args.Keys)
			{
				string _keyStr		= _key.ToString();
				string _valueStr	= _args[_key].ToString();

				// Add key and value
				Arguments[_keyStr]	= _valueStr;
			}
		}
		public iOSBillingProduct (IDictionary _productJsonDict)
		{
			Name				= _productJsonDict.GetIfAvailable<string>(kTitle);
			IOSProductID		= _productJsonDict.GetIfAvailable<string>(kProductID);
			Description			= _productJsonDict.GetIfAvailable<string>(kDescription);
			Price				= _productJsonDict.GetIfAvailable<float>(kPrice);
			LocalizedPrice		= _productJsonDict.GetIfAvailable<string>(kLocalizedPrice);
			CurrencyCode		= _productJsonDict.GetIfAvailable<string>(kCurrencyCode);
			CurrencySymbol		= _productJsonDict.GetIfAvailable<string>(kCurrencySymbol);
		}
        public AndroidNotificationPayload(IDictionary _payloadDict)
        {
            AndroidProperties		= new AndroidSpecificProperties();

            // Alert
            if (_payloadDict.Contains(NPSettings.Notification.Android.ContentTextKey))
            {
                //Check here which key is being received.
                Console.Log(Constants.kDebugTag, "[BillingTransaction] " + _payloadDict.ToJSON());//TODO
                object _alertUnknownType	= _payloadDict[ContentTextKey] as object;

                // String type
                if ((_alertUnknownType as string) != null)
                {
                    AlertBody	= _alertUnknownType as string;
                }
            }

            if (_payloadDict.Contains(UserInfoKey))
                UserInfo		= _payloadDict[UserInfoKey] as IDictionary;

            // Fire date
            long _secsFromNow	= _payloadDict.GetIfAvailable<long>(kFireDate);

            FireDate			= _secsFromNow.ToDateTimeFromJavaTime();

            // Sound, Badge
            AndroidProperties.ContentTitle		=  	_payloadDict.GetIfAvailable<string>(ContentTitleKey);
            AndroidProperties.TickerText		=  	_payloadDict.GetIfAvailable<string>(TickerTextKey);
            AndroidProperties.Tag				=  	_payloadDict.GetIfAvailable<string>(TagKey);

            //Added in 1.03
            AndroidProperties.CustomSound		= 	_payloadDict.GetIfAvailable<string>(kCustomSound);
            AndroidProperties.LargeIcon			= 	_payloadDict.GetIfAvailable<string>(kLargeIcon);
        }
		public AndroidAddressBookContact (IDictionary _contactInfoJsontDict)
		{
			string _givenName 	= _contactInfoJsontDict.GetIfAvailable<string>(kGivenName);
			string _familyName 	= _contactInfoJsontDict.GetIfAvailable<string>(kFamilyName);
		
			// Set first name and last name
			FirstName 		= _givenName;
			LastName 		= _familyName;
			ImagePath		= _contactInfoJsontDict.GetIfAvailable<string>(kImagePath);

			// Set phone numbers
			IList 		_phoneNumJSONList	= _contactInfoJsontDict.GetIfAvailable<IList>(kPhoneNumList);
			string[] 	_newPhoneNumList	= null;
			
			if (_phoneNumJSONList != null)
			{
				int		_totalCount			= _phoneNumJSONList.Count;
				_newPhoneNumList			= new string[_totalCount];
				
				for (int _iter = 0; _iter < _totalCount; _iter++)
					_newPhoneNumList[_iter]	= (string)_phoneNumJSONList[_iter];
			}
			
			PhoneNumberList		= _newPhoneNumList;
			
			// Set email id list
			IList 		_emailIDJsonList	= _contactInfoJsontDict.GetIfAvailable<IList>(kEmailList);
			string[] 	_newEmailIDList		= null;
			
			if (_emailIDJsonList != null)
			{
				int		_totalCount			= _emailIDJsonList.Count;
				_newEmailIDList				= new string[_totalCount];
				
				for (int _iter = 0; _iter < _totalCount; _iter++)
					_newEmailIDList[_iter]	= (string)_emailIDJsonList[_iter];
			}
			
			EmailIDList			= _newEmailIDList;
		}
        internal CrossPlatformNotification(IDictionary _jsonDict)
        {
            // Get alert body
            AlertBody			= _jsonDict.GetIfAvailable<string>(kAlertBodyKey);

            // Get fire date
            string _fireDateStr	= _jsonDict.GetIfAvailable<string>(kFireDateKey);

            if (!string.IsNullOrEmpty(_fireDateStr))
                FireDate		= _fireDateStr.ToDateTimeLocalUsingZuluFormat();

            // Get user info
            UserInfo			= _jsonDict[kUserInfoKey] as IDictionary;

            // Get iOS specific properties, if included
            if (_jsonDict.Contains(kiOSPropertiesKey))
                iOSProperties		= new iOSSpecificProperties(_jsonDict[kiOSPropertiesKey] as IDictionary);

            // Get Android specific properties, if included
            if (_jsonDict.Contains(kAndroidPropertiesKey))
                AndroidProperties	= new AndroidSpecificProperties(_jsonDict[kAndroidPropertiesKey] as IDictionary);
        }