bool FOnlineLeaderboardsNull::WriteLeaderboards(const FName& SessionName, const FUniqueNetId& Player, FOnlineLeaderboardWrite& WriteObject)
{
    bool bWasSuccessful = true;

    int32 NumLeaderboards = WriteObject.LeaderboardNames.Num();
    for (int32 LeaderboardIdx = 0; LeaderboardIdx < NumLeaderboards; ++LeaderboardIdx)
    {
        // Will create or retrieve the leaderboards, triggering async calls as appropriate
        FLeaderboardNull* Leaderboard = FindOrCreateLeaderboard(WriteObject.LeaderboardNames[LeaderboardIdx], WriteObject.SortMethod, WriteObject.DisplayFormat);
        check(Leaderboard);

        FOnlineStatsRow* PlayerRow = Leaderboard->FindOrCreatePlayerRecord(Player);
        check(PlayerRow);

        for (FStatPropertyArray::TConstIterator It(WriteObject.Properties); It; ++It)
        {
            const FName& StatName = It.Key();
            const FVariantData& Stat = It.Value();
            FVariantData* ExistingStat = PlayerRow->Columns.Find(StatName);
            if (ExistingStat)
            {
                //@TODO: Add support for other types (variant doesn't define an ordering operator)
                bool bJustAssign = true;

                if ((ExistingStat->GetType() == Stat.GetType()) && (Stat.GetType() == EOnlineKeyValuePairDataType::Int32))
                {
                    int32 NewValue;
                    int32 OldValue;
                    Stat.GetValue(NewValue);
                    ExistingStat->GetValue(OldValue);

                    switch (WriteObject.SortMethod)
                    {
                    case ELeaderboardSort::Ascending:
                        bJustAssign = NewValue < OldValue;
                        break;
                    case ELeaderboardSort::Descending:
                        bJustAssign = NewValue > OldValue;
                        break;
                    default:
                        bJustAssign = true;
                    }
                }

                if (bJustAssign)
                {
                    *ExistingStat = Stat;
                }
            }
            else
            {
                PlayerRow->Columns.Add(StatName, Stat);
            }
        }
    }

    // Write has no delegates as of now
    return bWasSuccessful;
}
/**
 * Increments a stat of type int32 by the value specified. Does nothing
 * if the stat is not of the right type.
 *
 * @param StatName the stat to increment
 * @param IncBy the value to increment by
 */
void FOnlineStats::IncrementIntStat(const FName& StatName, int32 IncBy)
{
	FVariantData* Stat = FindStatByName(StatName);
	if (Stat != NULL && Stat->GetType() == EOnlineKeyValuePairDataType::Int32)
	{
		// Set the value
		Stat->Increment<int32, EOnlineKeyValuePairDataType::Int32>(IncBy);
	}
	else
	{
		FVariantData NewValue(IncBy);
		Properties.Add(StatName, NewValue);
	}
}
/**
 * Decrements a stat of type float by the value specified. Does nothing
 * if the stat is not of the right type.
 *
 * @param StatName the stat to decrement
 * @param DecBy the value to decrement by
 */
void FOnlineStats::DecrementFloatStat(const FName& StatName, float DecBy)
{
	FVariantData* Stat = FindStatByName(StatName);
	if (Stat != NULL && Stat->GetType() == EOnlineKeyValuePairDataType::Float)
	{
		// Set the value
		Stat->Decrement<float, EOnlineKeyValuePairDataType::Float>(DecBy);
	}
	else
	{
		FVariantData NewValue(-DecBy);
		Properties.Add(StatName, NewValue);
	}
}
/**
 * Sets a stat of type float to the value specified. Does nothing
 * if the stat is not of the right type.
 *
 * @param StatName the stat to change the value of
 * @param Value the new value to assign to the stat
 */
void FOnlineStats::SetFloatStat(const FName& StatName, float Value)
{
	FVariantData* Stat = FindStatByName(StatName);
	if (Stat != NULL)
	{
		if (Stat->GetType() == EOnlineKeyValuePairDataType::Float)
		{
			// Set the value
			Stat->SetValue(Value);
		}
	}
	else
	{
		FVariantData NewValue(Value);
		Properties.Add(StatName, NewValue);
	}
}
bool UFindSessionsCallbackProxyAdvanced::CompareVariants(const FVariantData &A, const FVariantData &B, EOnlineComparisonOpRedux::Type Comparator)
{
	if (A.GetType() != B.GetType())
		return false;

	switch (A.GetType())
	{
	case EOnlineKeyValuePairDataType::Bool:
	{
		bool bA, bB;
		A.GetValue(bA);
		B.GetValue(bB);
		switch (Comparator)
		{
		case EOnlineComparisonOpRedux::Equals:
			return bA == bB; break;
		case EOnlineComparisonOpRedux::NotEquals:
			return bA != bB; break;
		default:
			return false;break;
		}
	}
	case EOnlineKeyValuePairDataType::Double:
	{
		double bA, bB;
		A.GetValue(bA);
		B.GetValue(bB);
		switch (Comparator)
		{
		case EOnlineComparisonOpRedux::Equals:
			return bA == bB; break;
		case EOnlineComparisonOpRedux::NotEquals:
			return bA != bB; break;
		case EOnlineComparisonOpRedux::GreaterThanEquals:
			return (bA == bB || bA > bB); break;
		case EOnlineComparisonOpRedux::LessThanEquals:
			return (bA == bB || bA < bB); break;
		case EOnlineComparisonOpRedux::GreaterThan:
			return bA > bB; break;
		case EOnlineComparisonOpRedux::LessThan:
			return bA < bB; break;
		default:
			return false; break;
		}
	}
	case EOnlineKeyValuePairDataType::Float:
	{
		float tbA, tbB;
		double bA, bB;
		A.GetValue(tbA);
		B.GetValue(tbB);
		bA = (double)tbA;
		bB = (double)tbB;
		switch (Comparator)
		{
		case EOnlineComparisonOpRedux::Equals:
			return bA == bB; break;
		case EOnlineComparisonOpRedux::NotEquals:
			return bA != bB; break;
		case EOnlineComparisonOpRedux::GreaterThanEquals:
			return (bA == bB || bA > bB); break;
		case EOnlineComparisonOpRedux::LessThanEquals:
			return (bA == bB || bA < bB); break;
		case EOnlineComparisonOpRedux::GreaterThan:
			return bA > bB; break;
		case EOnlineComparisonOpRedux::LessThan:
			return bA < bB; break;
		default:
			return false; break;
		}
	}
	case EOnlineKeyValuePairDataType::Int32:
	{
		int32 bA, bB;
		A.GetValue(bA);
		B.GetValue(bB);
		switch (Comparator)
		{
		case EOnlineComparisonOpRedux::Equals:
			return bA == bB; break;
		case EOnlineComparisonOpRedux::NotEquals:
			return bA != bB; break;
		case EOnlineComparisonOpRedux::GreaterThanEquals:
			return (bA == bB || bA > bB); break;
		case EOnlineComparisonOpRedux::LessThanEquals:
			return (bA == bB || bA < bB); break;
		case EOnlineComparisonOpRedux::GreaterThan:
			return bA > bB; break;
		case EOnlineComparisonOpRedux::LessThan:
			return bA < bB; break;
		default:
			return false; break;
		}
	}
	case EOnlineKeyValuePairDataType::Int64:
	{
		uint64 bA, bB;
		A.GetValue(bA);
		B.GetValue(bB);
		switch (Comparator)
		{
		case EOnlineComparisonOpRedux::Equals:
			return bA == bB; break;
		case EOnlineComparisonOpRedux::NotEquals:
			return bA != bB; break;
		case EOnlineComparisonOpRedux::GreaterThanEquals:
			return (bA == bB || bA > bB); break;
		case EOnlineComparisonOpRedux::LessThanEquals:
			return (bA == bB || bA < bB); break;
		case EOnlineComparisonOpRedux::GreaterThan:
			return bA > bB; break;
		case EOnlineComparisonOpRedux::LessThan:
			return bA < bB; break;
		default:
			return false; break;
		}
	}

	case EOnlineKeyValuePairDataType::String:
	{
		FString bA, bB;
		A.GetValue(bA);
		B.GetValue(bB);
		switch (Comparator)
		{
		case EOnlineComparisonOpRedux::Equals:
			return bA == bB; break;
		case EOnlineComparisonOpRedux::NotEquals:
			return bA != bB; break;
		default:
			return false; break;
		}
	}

	case EOnlineKeyValuePairDataType::Empty:
	case EOnlineKeyValuePairDataType::Blob:
	default:
		return false; break;
	}



}