func selectMember(partition []Change, address string) (Change, bool) {
	for _, m := range partition {
		if m.Address == address {
			return m, true
		}
	}
	return Change{}, false
}
selectMember selects the member with the specified address from the partition.
package swim
import "time"
func AttemptHeal(node *Node, target string) ([]string, error) {
	node.EmitEvent(AttemptHealEvent{})
	node.logger.WithField("target", target).Info("attempt heal")
	joinRes, err := sendJoinRequest(node, target, time.Second)
	if err != nil {
		return nil, err
	}
	MA := node.disseminator.MembershipAsChanges()
	MB := joinRes.Membership
	changesForA, changesForB := nodesThatNeedToReincarnate(MA, MB)
	if len(changesForA) != 0 || len(changesForB) != 0 {
		err = reincarnateNodes(node, target, changesForA, changesForB)
		return pingableHosts(MB), err
	}
	err = mergePartitions(node, target, MB)
	return pingableHosts(MB), err
}
func nodesThatNeedToReincarnate(MA, MB []Change) (changesForA, changesForB []Change) {
	for _, b := range MB {
		a, ok := selectMember(MA, b.Address)
		if !ok {
			continue
		}
		if b.isPingable() && a.overrides(b) && !a.isPingable() {
			var change Change
			change = a
			change.scrubSource()
			change.Status = Suspect
			changesForB = append(changesForB, change)
		}
		if a.isPingable() && b.overrides(a) && !b.isPingable() {
			var change Change
			change = b
			change.scrubSource()
			change.Status = Suspect
			changesForA = append(changesForA, change)
		}
	}
	return changesForA, changesForB
}
func reincarnateNodes(node *Node, target string, changesForA, changesForB []Change) error {
	node.healer.logger.WithField("target", target).Info("reincarnate nodes before we can merge the partitions")
	node.memberlist.Update(changesForA)
	var err error
	if len(changesForB) != 0 {
		_, err = sendPingWithChanges(node, target, changesForB, time.Second)
	}
	return err
}
func mergePartitions(node *Node, target string, MB []Change) error {
	node.healer.logger.WithField("target", target).Info("merge two partitions")
	node.memberlist.Update(MB)
	MA := node.disseminator.MembershipAsChanges()
	_, err := sendPingWithChanges(node, target, MA, time.Second)
	return err
}
func pingableHosts(changes []Change) (ret []string) {
	for _, b := range changes {
		if b.isPingable() {
			ret = append(ret, b.Address)
		}
	}
	return
}