/// <summary>
    /// Identifies the users on the image.
    /// </summary>
    /// <returns><c>true</c>, if identification completed successfully, <c>false</c> otherwise.</returns>
    /// <param name="imageBytes">Image bytes.</param>
    /// <param name="faces">Array of faces.</param>
    /// <param name="results">Array of identification results.</param>
    public bool IdentifyUsers(byte[] imageBytes, ref Face[] faces, ref IdentifyResult[] results)
    {
        // create the user-group if needed
        if (userGroupId != initedGroupId)
        {
            GetOrGreateUserGroup();
        }
        if (userGroupId != initedGroupId)
        {
            return(false);
        }

        // detect and identify user faces
        faces   = null;
        results = null;

        if (faceManager != null)
        {
            faces = faceManager.DetectFaces(imageBytes);

            // get the training status
            TrainingStatus training    = faceManager.GetPersonGroupTrainingStatus(userGroupId);
            bool           bEmptyGroup = false;

            if (training != null)
            {
                if (training.status == Status.Failed)
                {
                    // check if there are persons in this group
                    List <Person> listPersons = GetUsersList();

                    if (listPersons.Count > 0)
                    {
                        // retrain the group
                        faceManager.TrainPersonGroup(userGroupId);
                    }
                    else
                    {
                        // empty group - always returns 'training failed'
                        training.status = Status.Succeeded;
                        bEmptyGroup     = true;
                    }
                }
                else if (training.status == Status.Succeeded && training.message.StartsWith("There is no person"))
                {
                    // the group exists but it's empty
                    bEmptyGroup = true;
                }
            }

            DateTime waitTill = DateTime.Now.AddSeconds(5);
            while ((training == null || training.status != Status.Succeeded) && (DateTime.Now < waitTill))
            {
                // wait for training to succeed
                System.Threading.Thread.Sleep(1000);
                training = faceManager.GetPersonGroupTrainingStatus(userGroupId);
            }

            if (bEmptyGroup)
            {
                // nothing to check
                return(true);
            }

            if (faces != null && faces.Length > 0)
            {
                results = faceManager.IdentifyFaces(userGroupId, ref faces, 1);
                faceManager.MatchCandidatesToFaces(ref faces, ref results, userGroupId);
                return(true);
            }
        }

        return(false);
    }