protected function getSettableGroupIdsFrom(Form $form, Member $member = null)
    {
        // first off check to see if groups were selected by the user. If so, we want
        // to remove that control from the form list (just in case someone's sent through an
        // ID for a group like, say, the admin's group...). It means we have to handle the setting
        // ourselves, but that's okay
        $groupField = $form->Fields()->dataFieldByName('Groups');
        // The list of selectable groups
        $groupIds = $allowedIds = $this->SelectableGroups()->map('ID', 'ID')->toArray();

        // we need to track the selected groups against the existing user's groups - this is
        // so that we don't accidentally remove them from the list of groups
        // a user might have been placed in via other means
        $existingIds = array();
        if ($member) {
            $existing = $member->Groups();
            if ($existing && $existing->count() > 0) {
                $existingIds = $existing->map('ID', 'ID')->toArray();
                // remove any that are in the selectable groups map - we only want to
                // worry about those that aren't managed by this form
                foreach ($groupIds as $gid) {
                    unset($existingIds[$gid]);
                }
            }
        }

        if ($groupField) {
            $givenIds = $groupField->Value();
            $groupIds = array();
            if ($givenIds) {
                foreach ($givenIds as $givenId) {
                    if (isset($allowedIds[$givenId])) {
                        $groupIds[] = $givenId;
                    }
                }
            }
            $form->Fields()->removeByName('Groups');
        }

        foreach ($this->Groups()->column('ID') as $mustId) {
            $groupIds[] = $mustId;
        }

        foreach ($existingIds as $existingId) {
            if (!in_array($existingId, $groupIds)) {
                $groupIds[] = $existingId;
            }
        }

        return $groupIds;
    }