public bool ReportAchievementProgressAsync(double record, string achievementKey, Action <bool> onResultsReceived = null)
        {
            bool returnIsAttemptingReport = false;
            ServiceSpecificIds requestedAchievementIds = null;

            // Clamp record
            if (record < 0)
            {
                record = 0;
            }
            else if (record > 100)
            {
                record = 100;
            }

            // Grab an achievement
            if (string.IsNullOrEmpty(achievementKey) == false)
            {
                requestedAchievementIds = GetAchievementIds(achievementKey);
            }

            // Make sure all the parameters are correct
            if (IsArgumentValid <double>("Achievement", requestedAchievementIds, achievementKey, record, onResultsReceived) == true)
            {
                // Grab the action to report to
                if (onResultsReceived == null)
                {
                    if (onAchievementReported == null)
                    {
                        onAchievementReported = new Action <bool>(OnAchievementReported);
                    }
                    onResultsReceived = onAchievementReported;
                }

                // Report score
                Social.ReportProgress(requestedAchievementIds.Id, record, onResultsReceived);

                // Indicate attempt succeeded
                returnIsAttemptingReport = true;

                // Show debugging messages
                if (Debug.isDebugBuild == true)
                {
                    lock (warningBuilder)
                    {
                        warningBuilder.Length = 0;
                        warningBuilder.Append("Reporting Achievement with key ");
                        warningBuilder.Append(achievementKey);
                        warningBuilder.Append(" and progress ");
                        warningBuilder.Append(record);
                        Utility.Log(warningBuilder.ToString());
                    }
                }
            }
            return(returnIsAttemptingReport);
        }
        bool IsArgumentValid <T>(string type, ServiceSpecificIds ids, string achievementKey, T record, Action <bool> debug)
        {
            bool returnFlag = true;

#if UNITY_EDITOR
            // Return false
            returnFlag = false;

            // Pretend to run the results, anyway
            StartCoroutine(DebugUnsupportedPlatforms <T>(achievementKey, record, debug));
#else
            if (ids == null)
            {
                // Return false
                returnFlag = false;

                // Generate warning
                lock (warningBuilder)
                {
                    warningBuilder.Length = 0;
                    warningBuilder.Append("No ");
                    warningBuilder.Append(type);
                    warningBuilder.Append(" with key ");
                    warningBuilder.Append(achievementKey);
                    warningBuilder.Append("found!");
                    Debug.LogWarning(warningBuilder.ToString());
                }
            }
            else if (string.IsNullOrEmpty(ids.Id) == true)
            {
                // Return false
                returnFlag = false;

                // Generate warning
                lock (warningBuilder)
                {
                    warningBuilder.Length = 0;
                    warningBuilder.Append("No ");
                    warningBuilder.Append(type);
                    warningBuilder.Append(" ID provided");
                    Debug.LogWarning(warningBuilder.ToString());
                }
            }
            else if (CurrentLogInState != LogInState.AuthenticationSuccess)
            {
                // Return false
                returnFlag = false;

                // Generate warning
                Debug.LogWarning("User is not authenticated yet");
            }
#endif
            return(returnFlag);
        }
        public ILeaderboardWrapper GetLeaderboard(string leaderboardKey = null,
                                                  UserScope userScope   = UserScope.Global, TimeScope timeScope = TimeScope.AllTime,
                                                  ushort startingRank   = 0, ushort numberOfRanks = 0, bool retrieveScore = true)
        {
            ILeaderboardWrapper returnWrapper  = null;
            ServiceSpecificIds  leaderboardIds = DefaultLeaderboardIds;

            if (string.IsNullOrEmpty(leaderboardKey) == false)
            {
                leaderboardIds = GetLeaderboardIds(leaderboardKey);
            }

            // Check if the ID is provided
            if (leaderboardIds == null)
            {
                if (Debug.isDebugBuild == true)
                {
                    Debug.LogWarning("No Leaderboard with key " + leaderboardKey + " found");
                }
            }
            else if (string.IsNullOrEmpty(leaderboardIds.Id) == true)
            {
                if (Debug.isDebugBuild == true)
                {
                    Debug.LogWarning("No Leaderboard ID provided");
                }
            }
            else
            {
                // Find a LeaderboardWrapper from the dictionary
                LeaderboardKey key = new LeaderboardKey(leaderboardIds.Id, userScope, timeScope, startingRank, numberOfRanks);
                if (allLeaderboards.TryGetValue(key, out returnWrapper) == false)
                {
                    // Create a new wrapper, and add it to the dictionary
                    returnWrapper = new LeaderboardWrapper(key);
                    allLeaderboards.Add(key, returnWrapper);

                    // Check if we should retrive scores for this leaderboard
                    if ((retrieveScore == true) && (CurrentLogInState == LogInState.AuthenticationSuccess))
                    {
                        returnWrapper.LoadLeaderboardAsync();
                    }
                }
            }
            return(returnWrapper);
        }
        public bool ReportLeaderboardRecordAsync(long record, string leaderboardKey = null, Action <bool> onResultsReceived = null)
        {
            bool returnIsAttemptingReport = false;
            ServiceSpecificIds requestedLeaderboardIds = DefaultLeaderboardIds;

            if (string.IsNullOrEmpty(leaderboardKey) == false)
            {
                requestedLeaderboardIds = GetLeaderboardIds(leaderboardKey);
            }

            // Make sure all the parameters are correct
            if (IsArgumentValid <long>("Leaderboard", requestedLeaderboardIds, leaderboardKey, record, onResultsReceived) == true)
            {
                // Grab the action to report to
                if (onResultsReceived == null)
                {
                    if (onLeaderboardReported == null)
                    {
                        onLeaderboardReported = new Action <bool>(OnLeaderboardReported);
                    }
                    onResultsReceived = onLeaderboardReported;
                }

                // Report score
                Social.ReportScore(record, requestedLeaderboardIds.Id, onResultsReceived);

                // Indicate attempt succeeded
                returnIsAttemptingReport = true;

                // Show debugging messages
                if (Debug.isDebugBuild == true)
                {
                    lock (warningBuilder)
                    {
                        warningBuilder.Length = 0;
                        warningBuilder.Append("Reporting Leaderboard with key ");
                        warningBuilder.Append(leaderboardKey);
                        warningBuilder.Append(" and score ");
                        warningBuilder.Append(record);
                        Utility.Log(warningBuilder.ToString());
                    }
                }
            }
            return(returnIsAttemptingReport);
        }
        ServiceSpecificIds GetIds(string key, Dictionary <string, ServiceSpecificIds> dictionary, ServiceSpecificIds[] list)
        {
            ServiceSpecificIds returnId = null;

            // First, check if the leaderboard dictionary needs to be populated
            if (dictionary.Count != list.Length)
            {
                dictionary.Clear();
                for (int index = 0; index < list.Length; ++index)
                {
                    dictionary.Add(list[index].Key, list[index]);
                }
            }

            // Next, see if we can grab a leaderboard
            if (dictionary.TryGetValue(key, out returnId) == false)
            {
                returnId = null;
            }
            return(returnId);
        }