//---------------------------------------------------------------
        //---------------------------------------------------------------
        void GooglePlayIAPJavaInterface::StartListeningForTransactionUpdates(const CSNetworking::IAPSystem::TransactionStatusDelegate& in_delegate)
        {
        	CS_ASSERT(in_delegate != nullptr, "Cannot have null transaction delegate");

        	m_transactionStatusDelegate = in_delegate;

        	JNIEnv* env = JavaInterfaceManager::GetSingletonPtr()->GetJNIEnvironmentPtr();
        	env->CallVoidMethod(GetJavaObject(), GetMethodID("RestorePendingUnmanagedTransactions"));

        	Json::Value jData;
        	if(CSCore::JsonUtils::ReadJson(CSCore::StorageLocation::k_cache, k_pendingCacheFile, jData))
        	{
        		const Json::Value::Members& members = jData.getMemberNames();
        		jobjectArray transactionIDs = env->NewObjectArray(members.size(), env->FindClass("java/lang/String"), env->NewStringUTF(""));

        		u32 index = 0;
        		for(Json::Value::Members::const_iterator it = members.begin(); it != members.end(); ++it, ++index)
        		{
    				jstring jtransactionId = JavaInterfaceUtils::CreateJStringFromSTDString(*it);
    				env->SetObjectArrayElement(transactionIDs, index, jtransactionId);
    				env->DeleteLocalRef(jtransactionId);
        		}

            	env->CallVoidMethod(GetJavaObject(), GetMethodID("RestorePendingManagedTransactions"), transactionIDs);
            	env->DeleteLocalRef(transactionIDs);
        	}
        }
        //-----------------------------------------------------------------------------------------------------
        //-----------------------------------------------------------------------------------------------------
        TimeIntervalMs CoreJavaInterface::GetSystemTimeInMilliseconds()
        {
        	TimeIntervalMs output = 0;
			JNIEnv* env = JavaInterfaceManager::GetSingletonPtr()->GetJNIEnvironmentPtr();
			output = (TimeIntervalMs)env->CallLongMethod(GetJavaObject(), GetMethodID("getSystemTimeInMilliseconds"));
			return output;
        }
		//-------------------------------------------------------
		//-------------------------------------------------------
		void TextEntryJavaInterface::SetTextBuffer(const std::string& in_text)
		{
        	JNIEnv* env = JavaInterfaceManager::GetSingletonPtr()->GetJNIEnvironmentPtr();
        	jstring text = JavaInterfaceUtils::CreateJStringFromSTDString(in_text);
        	env->CallVoidMethod(GetJavaObject(), GetMethodID("setTextBuffer"), text);
        	env->DeleteLocalRef(text);
		}
        //---------------------------------------------------------------
        //---------------------------------------------------------------
        void AmazonIAPJavaInterface::RequestProductPurchase(const std::string& in_productId)
        {
			JNIEnv* env = JavaInterfaceManager::GetSingletonPtr()->GetJNIEnvironmentPtr();
			jstring productID = JavaUtils::CreateJStringFromSTDString(in_productId);
			env->CallVoidMethod(GetJavaObject(), GetMethodID("RequestProductPurchase"), productID);
			env->DeleteLocalRef(productID);
        }
		//--------------------------------------------------------------
		/// Present
		//--------------------------------------------------------------
		void EmailComposerJavaInterface::Present(const std::vector<std::string>& inastrRecipientAddresses, const std::string& instrSubject, const std::string& instrContents,
				bool inbFormatAsHtml, const std::string& instrAttachmentFilename, const ResultDelegate& inDelegate)
		{
			mDelegate = inDelegate;

			JNIEnv* pEnv = JavaInterfaceManager::GetSingletonPtr()->GetJNIEnvironmentPtr();

			//build the recipient list
			u32 udwCount = 0;
			jobjectArray ajstrRecipients = pEnv->NewObjectArray(inastrRecipientAddresses.size(), pEnv->FindClass("java/lang/String"), pEnv->NewStringUTF(""));
			for(auto it = inastrRecipientAddresses.begin(); it != inastrRecipientAddresses.end(); ++it)
			{
				jstring jstrRecipient = JavaUtils::CreateJStringFromSTDString(*it);
				pEnv->SetObjectArrayElement(ajstrRecipients,udwCount++, jstrRecipient);
				pEnv->DeleteLocalRef(jstrRecipient);
			}

			jstring jstrSubject = JavaUtils::CreateJStringFromSTDString(instrSubject);
			jstring jstrContents = JavaUtils::CreateJStringFromSTDString(instrContents);
			jstring jstrAttachmentFilename = JavaUtils::CreateJStringFromSTDString(instrAttachmentFilename);

			//call method
			pEnv->CallVoidMethod(GetJavaObject(), GetMethodID("Present"), ajstrRecipients, jstrSubject, jstrContents, inbFormatAsHtml, jstrAttachmentFilename);

			//clean up
			pEnv->DeleteLocalRef(ajstrRecipients);
			pEnv->DeleteLocalRef(jstrSubject);
			pEnv->DeleteLocalRef(jstrContents);
			pEnv->DeleteLocalRef(jstrAttachmentFilename);
		}
        //---------------------------------------------------------------
        //---------------------------------------------------------------
        void AmazonIAPJavaInterface::RequestProductDescriptions(const std::vector<std::string>& in_productIds, const CSNetworking::IAPSystem::ProductDescDelegate& in_delegate)
        {
            CS_ASSERT(in_productIds.empty() == false, "Cannot request no product descriptions");
            CS_ASSERT(in_delegate != nullptr, "Cannot have null product description delegate");
            CS_ASSERT(m_productsRequestDelegate == nullptr, "Only 1 product description request can be active at a time");

        	m_productsRequestDelegate = in_delegate;

        	JNIEnv* env = JavaInterfaceManager::GetSingletonPtr()->GetJNIEnvironmentPtr();

			jstring jstrEmptyString = env->NewStringUTF("");
			jclass jStringClass = env->FindClass("java/lang/String");

        	jobjectArray productIDs = env->NewObjectArray(in_productIds.size(), jStringClass, jstrEmptyString);
        	u32 productIDIndex = 0;
        	for(std::vector<std::string>::const_iterator it = in_productIds.begin(); it != in_productIds.end(); ++it)
        	{
        		jstring productID = JavaUtils::CreateJStringFromSTDString(*it);
        		env->SetObjectArrayElement(productIDs, productIDIndex, productID);
        		env->DeleteLocalRef(productID);
        		productIDIndex++;
        	}

        	env->CallVoidMethod(GetJavaObject(), GetMethodID("RequestProductDescriptions"), productIDs);
        	env->DeleteLocalRef(productIDs);
			env->DeleteLocalRef(jstrEmptyString);
			env->DeleteLocalRef(jStringClass);
        }
        //------------------------------------------------------
        //------------------------------------------------------
        void DialogueBoxJavaInterface::MakeToast(const std::string& in_text)
        {
			JNIEnv* env = JavaInterfaceManager::GetSingletonPtr()->GetJNIEnvironmentPtr();
			jstring message = JavaInterfaceUtils::CreateJStringFromSTDString(in_text);
			env->CallVoidMethod(GetJavaObject(), GetMethodID("makeToast"), message);
			env->DeleteLocalRef(message);
        }
        //---------------------------------------------------------------
        //---------------------------------------------------------------
        void AmazonIAPJavaInterface::StopListeningForTransactionUpdates()
        {
        	m_transactionStatusDelegate = nullptr;

        	JNIEnv* env = JavaInterfaceManager::GetSingletonPtr()->GetJNIEnvironmentPtr();
        	env->CallVoidMethod(GetJavaObject(), GetMethodID("StopListeningForTransactionUpdates"));
        }
		//--------------------------------------------------------------------------------------
		//--------------------------------------------------------------------------------------
		std::string CoreJavaInterface::GetExternalStorageDirectory()
		{
			std::string sdCardRootPath = "";
			JNIEnv* env = JavaInterfaceManager::GetSingletonPtr()->GetJNIEnvironmentPtr();
			jstring externalStorageDir = static_cast<jstring>(env->CallObjectMethod(GetJavaObject(), GetMethodID("getExternalStorageDirectory")));
			sdCardRootPath = JavaUtils::CreateSTDStringFromJString(externalStorageDir);
			env->DeleteLocalRef(externalStorageDir);
			return sdCardRootPath;
		}
		//--------------------------------------------------------------------------------------
		//--------------------------------------------------------------------------------------
		std::string CoreJavaInterface::GetPackageName()
		{
			std::string packageName = "";
			JNIEnv* env = JavaInterfaceManager::GetSingletonPtr()->GetJNIEnvironmentPtr();
			jstring jstrName = static_cast<jstring>(env->CallObjectMethod(GetJavaObject(), GetMethodID("getPackageName")));
			packageName = JavaUtils::CreateSTDStringFromJString(jstrName);
			env->DeleteLocalRef(jstrName);
			return packageName;
		}
        //---------------------------------------------------------------
        //---------------------------------------------------------------
        void AmazonIAPJavaInterface::StartListeningForTransactionUpdates(const CSNetworking::IAPSystem::TransactionStatusDelegate& in_delegate)
        {
        	CS_ASSERT(in_delegate != nullptr, "Cannot have null transaction delegate");

        	m_transactionStatusDelegate = in_delegate;

        	JNIEnv* env = JavaInterfaceManager::GetSingletonPtr()->GetJNIEnvironmentPtr();
        	env->CallVoidMethod(GetJavaObject(), GetMethodID("StartListeningForTransactionUpdates"));
        }
		//--------------------------------------------------------------------------------------
		//--------------------------------------------------------------------------------------
		std::string CoreJavaInterface::GetAPKDirectory()
		{
			std::string apkRootPath = " ";
			JNIEnv* env = JavaInterfaceManager::GetSingletonPtr()->GetJNIEnvironmentPtr();
			jstring jstrAkpPath = static_cast<jstring>(env->CallObjectMethod(GetJavaObject(), GetMethodID("getAPKDirectory")));
			apkRootPath = JavaUtils::CreateSTDStringFromJString(jstrAkpPath);
			env->DeleteLocalRef(jstrAkpPath);
			return apkRootPath;
		}
		//--------------------------------------------------------------------------------------
		//--------------------------------------------------------------------------------------
		s32 CoreJavaInterface::GetScreenHeight()
		{
			if (m_screenHeight == 0)
			{
				JNIEnv* env = JavaInterfaceManager::GetSingletonPtr()->GetJNIEnvironmentPtr();
				m_screenHeight = env->CallIntMethod(GetJavaObject(), GetMethodID("getScreenHeight"));
			}
			return m_screenHeight;
		}
		//--------------------------------------------------------------------------------------
		//--------------------------------------------------------------------------------------
		f32 CoreJavaInterface::GetScreenDensity()
		{
			if (m_screenDensity < 0.0f)
			{
				JNIEnv* env = JavaInterfaceManager::GetSingletonPtr()->GetJNIEnvironmentPtr();
				m_screenDensity = env->CallFloatMethod(GetJavaObject(), GetMethodID("getScreenDensity"));
			}
			return m_screenDensity;
		}
		//------------------------------------------------
		/// Stop Listening
		//------------------------------------------------
		void AccelerometerJavaInterface::StopListening()
		{
			if (true == mbListening)
			{
				mAccelerationChangedDelegate = nullptr;
				JNIEnv* pEnv = JavaInterfaceManager::GetSingletonPtr()->GetJNIEnvironmentPtr();
				pEnv->CallVoidMethod(GetJavaObject(), GetMethodID("StopListening"));
				mbListening = false;
			}
		}
        //-----------------------------------------------------
        //-----------------------------------------------------
        void DialogueBoxJavaInterface::ShowSystemDialogue(s32 in_dialogID, const std::string& in_title, const std::string& in_message, const std::string& in_confirm)
        {
			JNIEnv* env = JavaInterfaceManager::GetSingletonPtr()->GetJNIEnvironmentPtr();
			jstring title = JavaInterfaceUtils::CreateJStringFromSTDString(in_title);
			jstring message = JavaInterfaceUtils::CreateJStringFromSTDString(in_message);
			jstring confirm = JavaInterfaceUtils::CreateJStringFromSTDString(in_confirm);
			env->CallVoidMethod(GetJavaObject(), GetMethodID("showSystemDialogue"), in_dialogID, title, message, confirm);
			env->DeleteLocalRef(title);
			env->DeleteLocalRef(message);
			env->DeleteLocalRef(confirm);
        }
		//------------------------------------------------
		/// Start Listening
		//------------------------------------------------
		void AccelerometerJavaInterface::StartListening(const AccelerationChangedDelegate& inAccelerationChangedDelegate)
		{
			if (true == IsAvailable() && false == mbListening)
			{
				JNIEnv* pEnv = JavaInterfaceManager::GetSingletonPtr()->GetJNIEnvironmentPtr();
				pEnv->CallVoidMethod(GetJavaObject(), GetMethodID("StartListening"));

				mAccelerationChangedDelegate = inAccelerationChangedDelegate;
				mbListening = true;
			}
		}
        //---------------------------------------------------------------
        //---------------------------------------------------------------
        void AmazonIAPJavaInterface::CloseTransaction(const std::string& in_productId, const std::string& in_transactionId, const CSNetworking::IAPSystem::TransactionCloseDelegate& in_delegate)
        {
        	CS_ASSERT(in_delegate != nullptr, "Cannot have null transaction close delegate");
        	CS_ASSERT(m_transactionCloseDelegate == nullptr, "Only 1 transaction can be closed at a time");

        	m_transactionCloseDelegate = in_delegate;

			JNIEnv* env = JavaInterfaceManager::GetSingletonPtr()->GetJNIEnvironmentPtr();
			jstring productId = JavaUtils::CreateJStringFromSTDString(in_productId);
			jstring transactionId = JavaUtils::CreateJStringFromSTDString(in_transactionId);
			env->CallVoidMethod(GetJavaObject(), GetMethodID("CloseTransaction"), productId, transactionId);
			env->DeleteLocalRef(productId);
			env->DeleteLocalRef(transactionId);
        }
		//--------------------------------------------------------------
		//--------------------------------------------------------------
		GooglePlayIAPJavaInterface::GooglePlayIAPJavaInterface(const std::string& in_publicKey)
		{
			CreateNativeInterface("com/chilliworks/chillisource/googleplay/networking/GooglePlayIAPNativeInterface");
			CreateMethodReference("Init", "(Ljava/lang/String;)V");
			CreateMethodReference("IsPurchasingEnabled", "()Z");
			CreateMethodReference("RequestProductDescriptions", "([Ljava/lang/String;)V");
			CreateMethodReference("CancelProductDescriptionsRequest", "()V");
			CreateMethodReference("RequestProductPurchase", "(Ljava/lang/String;I)V");
			CreateMethodReference("CloseTransaction", "(Ljava/lang/String;Ljava/lang/String;)V");
			CreateMethodReference("RestoreManagedPurchases", "()V");
			CreateMethodReference("RestorePendingUnmanagedTransactions", "()V");
			CreateMethodReference("RestorePendingManagedTransactions", "([Ljava/lang/String;)V");

			//initialise the system
			JNIEnv* env = JavaInterfaceManager::GetSingletonPtr()->GetJNIEnvironmentPtr();
			jstring publicKey = JavaInterfaceUtils::CreateJStringFromSTDString(in_publicKey);
			env->CallVoidMethod(GetJavaObject(), GetMethodID("Init"), publicKey);
			env->DeleteLocalRef(publicKey);
		}
		//--------------------------------------------------------------
		//--------------------------------------------------------------
		AmazonIAPJavaInterface::AmazonIAPJavaInterface(const std::string& in_privateKey, const std::string& in_udid)
		{
			CreateNativeInterface("com/chilliworks/chillisource/networking/AmazonIAPNativeInterface");
			CreateMethodReference("Init", "(Ljava/lang/String;Ljava/lang/String;)V");
			CreateMethodReference("IsPurchasingEnabled", "()Z");
			CreateMethodReference("RequestProductDescriptions", "([Ljava/lang/String;)V");
			CreateMethodReference("CancelProductDescriptionsRequest", "()V");
			CreateMethodReference("RequestProductPurchase", "(Ljava/lang/String;)V");
			CreateMethodReference("CloseTransaction", "(Ljava/lang/String;Ljava/lang/String;)V");
			CreateMethodReference("RestoreManagedPurchases", "()V");
			CreateMethodReference("StartListeningForTransactionUpdates", "()V");
			CreateMethodReference("StopListeningForTransactionUpdates", "()V");

			//initialise the system
			JNIEnv* env = JavaInterfaceManager::GetSingletonPtr()->GetJNIEnvironmentPtr();
			jstring privateKey = JavaUtils::CreateJStringFromSTDString(in_privateKey);
			jstring udid = JavaUtils::CreateJStringFromSTDString(in_udid);
			env->CallVoidMethod(GetJavaObject(), GetMethodID("Init"), privateKey, udid);
			env->DeleteLocalRef(privateKey);
			env->DeleteLocalRef(udid);
		}
        //---------------------------------------------------------------
        //---------------------------------------------------------------
        void GooglePlayIAPJavaInterface::RequestProductPurchase(const std::string& in_productId, CSNetworking::IAPSystem::ProductRegInfo::Type in_type)
        {
        	const u32 k_managedType = 0;
        	const u32 k_unManagedType = 1;
        	u32 type = k_unManagedType;

        	switch(in_type)
        	{
        		case CSNetworking::IAPSystem::ProductRegInfo::Type::k_managed:
        			type = k_managedType;
        			break;
        		case CSNetworking::IAPSystem::ProductRegInfo::Type::k_unmanaged:
        			type = k_unManagedType;
        			break;
        	}

			JNIEnv* env = JavaInterfaceManager::GetSingletonPtr()->GetJNIEnvironmentPtr();
			jstring jproductId = JavaInterfaceUtils::CreateJStringFromSTDString(in_productId);
			env->CallVoidMethod(GetJavaObject(), GetMethodID("RequestProductPurchase"), jproductId, type);
			env->DeleteLocalRef(jproductId);
        }
 //---------------------------------------------------------------
 //---------------------------------------------------------------
 void AmazonIAPJavaInterface::RestoreManagedPurchases()
 {
 	JNIEnv* env = JavaInterfaceManager::GetSingletonPtr()->GetJNIEnvironmentPtr();
 	env->CallVoidMethod(GetJavaObject(), GetMethodID("RestoreManagedPurchases"));
 }
        //-----------------------------------------------------------------------------------------------------
        //-----------------------------------------------------------------------------------------------------
        void CoreJavaInterface::ForceQuit()
        {
			JNIEnv* env = JavaInterfaceManager::GetSingletonPtr()->GetJNIEnvironmentPtr();
			env->CallVoidMethod(GetJavaObject(), GetMethodID("forceQuit"));
        }
		//------------------------------------------------
		/// Is Available
		//------------------------------------------------
		bool AccelerometerJavaInterface::IsAvailable()
		{
			JNIEnv* pEnv = JavaInterfaceManager::GetSingletonPtr()->GetJNIEnvironmentPtr();
			return pEnv->CallBooleanMethod(GetJavaObject(), GetMethodID("IsAvailable"));
		}
        //---------------------------------------------------------------
        //---------------------------------------------------------------
        bool AmazonIAPJavaInterface::IsPurchasingEnabled()
        {
			JNIEnv* env = JavaInterfaceManager::GetSingletonPtr()->GetJNIEnvironmentPtr();
			return env->CallBooleanMethod(GetJavaObject(), GetMethodID("IsPurchasingEnabled"));
        }
        //---------------------------------------------------------------
        //---------------------------------------------------------------
        void AmazonIAPJavaInterface::CancelProductDescriptionsRequest()
        {
			JNIEnv* env = JavaInterfaceManager::GetSingletonPtr()->GetJNIEnvironmentPtr();
			env->CallVoidMethod(GetJavaObject(), GetMethodID("CancelProductDescriptionsRequest"));
        }
		//--------------------------------------------------------------------------------------
		//--------------------------------------------------------------------------------------
		u32 CoreJavaInterface::GetApplicationVersionCode()
		{
			JNIEnv* env = JavaInterfaceManager::GetSingletonPtr()->GetJNIEnvironmentPtr();
			return env->CallIntMethod(GetJavaObject(), GetMethodID("getApplicationVersionCode"));
		}
		//-------------------------------------------
		//-------------------------------------------
        void TextEntryJavaInterface::SetCapitalisationMethod(CSInput::TextEntry::Capitalisation ineKeyboardCapitalisation)
        {
        	JNIEnv* pEnv = JavaInterfaceManager::GetSingletonPtr()->GetJNIEnvironmentPtr();
        	s32 dwKeyboardCapitalisation = KeyboardCapitalisationToInteger(ineKeyboardCapitalisation);
        	pEnv->CallVoidMethod(GetJavaObject(), GetMethodID("setCapitalisationMethod"), dwKeyboardCapitalisation);
        }
		//-----------------------------------------
		//-----------------------------------------
		void CoreJavaInterface::SetPreferredFPS(u32 in_maxFPS)
		{
			JNIEnv* env = JavaInterfaceManager::GetSingletonPtr()->GetJNIEnvironmentPtr();
			env->CallVoidMethod(GetJavaObject(), GetMethodID("setPreferredFPS"), in_maxFPS);
		}
		//------------------------------------------------------------------------------
		//------------------------------------------------------------------------------
		jobject CoreJavaInterface::GetActivity() const
		{
			JNIEnv* pEnv = CSBackend::Android::JavaInterfaceManager::GetSingletonPtr()->GetJNIEnvironmentPtr();
			return pEnv->CallObjectMethod(GetJavaObject(), GetMethodID("getActivity"));
		}