/// <summary>
        /// Maps the users.
        /// </summary>
        /// <param name="tableData">The table data.</param>
        private void MapUsers( IQueryable<Row> tableData )
        {
            var lookupContext = new RockContext();
            var personService = new PersonService( lookupContext );

            int rockAuthenticatedTypeId = EntityTypeCache.Read( "Rock.Security.Authentication.Database" ).Id;

            int secondaryEmailAttributeId = new AttributeService( lookupContext ).GetByEntityTypeId( PersonEntityTypeId )
                .Where( a => a.Key == "SecondaryEmail" ).Select( a => a.Id ).FirstOrDefault();
            var secondaryEmailAttribute = AttributeCache.Read( SecondaryEmailAttributeId );

            int staffGroupId = new GroupService( lookupContext ).GetByGuid( new Guid( Rock.SystemGuid.Group.GROUP_STAFF_MEMBERS ) ).Id;
            int memberGroupRoleId = new GroupTypeRoleService( lookupContext ).Queryable().Where( r => r.Guid.Equals( new Guid( "00F3AC1C-71B9-4EE5-A30E-4C48C8A0BF1F" ) ) )
                .Select( r => r.Id ).FirstOrDefault();

            var importedUsers = new UserLoginService( lookupContext ).Queryable()
                 .Where( u => u.ForeignId != null )
                 .Select( u => new { UserId = u.ForeignId, PersonId = u.PersonId } ).ToList()
                 .ToDictionary( t => t.UserId.AsType<int>(), t => t.PersonId );

            var newUserLogins = new List<UserLogin>();
            var newStaffMembers = new List<GroupMember>();
            var updatedPersonList = new List<Person>();

            int completed = 0;
            int totalRows = tableData.Count();
            int percentage = ( totalRows - 1 ) / 100 + 1;
            ReportProgress( 0, string.Format( "Verifying user import ({0:N0} found, {1:N0} already exist).", totalRows, importedUsers.Count() ) );

            foreach ( var row in tableData )
            {
                int? individualId = row["LinkedIndividualID"] as int?;
                string userName = row["UserLogin"] as string;
                int? userId = row["UserID"] as int?;
                if ( userId != null && individualId != null && !string.IsNullOrWhiteSpace( userName ) && !importedUsers.ContainsKey( (int)userId ) )
                {
                    int? personId = GetPersonAliasId( individualId, null );
                    if ( personId != null )
                    {
                        DateTime? createdDate = row["UserCreatedDate"] as DateTime?;
                        string userPhone = row["UserPhone"] as string;
                        string userEmail = row["UserEmail"] as string;
                        string userTitle = row["UserTitle"] as string;
                        bool? isEnabled = row["IsUserEnabled"] as bool?;
                        bool? isStaff = row["IsStaff"] as bool?;
                        bool isActive = isEnabled ?? false;

                        var user = new UserLogin();
                        user.CreatedDateTime = createdDate;
                        user.CreatedByPersonAliasId = ImportPersonAlias.Id;
                        user.EntityTypeId = rockAuthenticatedTypeId;
                        user.IsConfirmed = isEnabled;
                        user.UserName = userName;
                        user.PersonId = personId;
                        user.ForeignId = userId.ToString();

                        if ( isStaff == true )
                        {
                            // add this user to the staff group
                            var staffMember = new GroupMember();
                            staffMember.GroupId = staffGroupId;
                            staffMember.PersonId = (int)personId;
                            staffMember.GroupRoleId = memberGroupRoleId;
                            staffMember.CreatedDateTime = createdDate;
                            staffMember.CreatedByPersonAliasId = ImportPersonAlias.Id;
                            staffMember.GroupMemberStatus = isActive ? GroupMemberStatus.Active : GroupMemberStatus.Inactive;

                            newStaffMembers.Add( staffMember );
                        }

                        // set user login email to primary email
                        if ( !string.IsNullOrWhiteSpace( userEmail ) && userEmail.IsValidEmail() )
                        {
                            var person = personService.Queryable( includeDeceased: true ).FirstOrDefault( p => p.Id == personId );
                            string secondaryEmail = string.Empty;
                            userEmail = userEmail.Trim();
                            if ( string.IsNullOrWhiteSpace( person.Email ) )
                            {
                                secondaryEmail = person.Email;
                                person.Email = userEmail.Left( 75 );
                                person.IsEmailActive = isEnabled;
                                person.EmailNote = userTitle;
                                lookupContext.SaveChanges( true );
                            }
                            else if ( !person.Email.Equals( userEmail ) )
                            {
                                secondaryEmail = userEmail;
                            }

                            if ( !string.IsNullOrWhiteSpace( secondaryEmail ) )
                            {
                                person.Attributes = new Dictionary<string, AttributeCache>();
                                person.AttributeValues = new Dictionary<string, AttributeValue>();
                                AddPersonAttribute( secondaryEmailAttribute, person, secondaryEmail );
                            }

                            updatedPersonList.Add( person );
                        }

                        // other Attributes to save
                        // UserBio
                        // DepartmentName
                        // IsPastor

                        newUserLogins.Add( user );
                        completed++;

                        if ( completed % percentage < 1 )
                        {
                            int percentComplete = completed / percentage;
                            ReportProgress( percentComplete, string.Format( "{0:N0} users imported ({1}% complete).", completed, percentComplete ) );
                        }
                        else if ( completed % ReportingNumber < 1 )
                        {
                            SaveNewUserLogins( newUserLogins, newStaffMembers, updatedPersonList );

                            updatedPersonList.Clear();
                            newUserLogins.Clear();
                            newStaffMembers.Clear();
                            ReportPartialProgress();
                        }
                    }
                }
            }

            if ( newUserLogins.Any() )
            {
                SaveNewUserLogins( newUserLogins, newStaffMembers, updatedPersonList );
            }

            ReportProgress( 100, string.Format( "Finished user import: {0:N0} users imported.", completed ) );
        }