func updateTeam(w http.ResponseWriter, r *http.Request, t auth.Token) error {
	name := r.URL.Query().Get(":name")
	type teamChange struct {
		NewName string
		Tags    []string
	}
	changeRequest := teamChange{}
	if err := ParseInput(r, &changeRequest); err != nil {
		return err
	}
	tags, _ := InputValues(r, "tag")
	changeRequest.Tags = append(changeRequest.Tags, tags...) // for compatibility
	allowed := permission.Check(t, permission.PermTeamUpdate,
		permission.Context(permTypes.CtxTeam, name),
	)
	if !allowed {
		return permission.ErrUnauthorized
	}
	_, err := servicemanager.Team.FindByName(name)
	if err != nil {
		if err == authTypes.ErrTeamNotFound {
			return &errors.HTTP{Code: http.StatusNotFound, Message: err.Error()}
		}
		return err
	}
	evt, err := event.New(&event.Opts{
		Target:     teamTarget(name),
		Kind:       permission.PermTeamUpdate,
		Owner:      t,
		CustomData: event.FormToCustomData(InputFields(r)),
		Allowed:    event.Allowed(permission.PermTeamReadEvents, permission.Context(permTypes.CtxTeam, name)),
	})
	if err != nil {
		return err
	}
	defer func() { evt.Done(err) }()
	if changeRequest.NewName == "" {
		return servicemanager.Team.Update(name, changeRequest.Tags)
	}
	u, err := t.User()
	if err != nil {
		return err
	}
	err = servicemanager.Team.Create(changeRequest.NewName, changeRequest.Tags, u)
	if err != nil {
		return err
	}
	var toRollback []func(oldName, newName string) error
	defer func() {
		if err == nil {
			return
		}
		rollbackErr := servicemanager.Team.Remove(changeRequest.NewName)
		if rollbackErr != nil {
			log.Errorf("error rolling back team creation from %v to %v", name, changeRequest.NewName)
		}
		for _, rollbackFn := range toRollback {
			rollbackErr := rollbackFn(changeRequest.NewName, name)
			if rollbackErr != nil {
				fnName := runtime.FuncForPC(reflect.ValueOf(rollbackFn).Pointer()).Name()
				log.Errorf("error rolling back team name change in %v from %q to %q", fnName, name, changeRequest.NewName)
			}
		}
	}()
	for _, fn := range teamRenameFns {
		err = fn(name, changeRequest.NewName)
		if err != nil {
			return err
		}
		toRollback = append(toRollback, fn)
	}
	return servicemanager.Team.Remove(name)
}
func updateTeam(w http.ResponseWriter, r *http.Request, t auth.Token) error {
	name := r.URL.Query().Get(":name")
	type teamChange struct {
		NewName string
		Tags    []string
	}
	changeRequest := teamChange{}
	if err := ParseInput(r, &changeRequest); err != nil {
		return err
	}
	tags, _ := InputValues(r, "tag")
	changeRequest.Tags = append(changeRequest.Tags, tags...) // for compatibility
	allowed := permission.Check(t, permission.PermTeamUpdate,
		permission.Context(permTypes.CtxTeam, name),
	)
	if !allowed {
		return permission.ErrUnauthorized
	}
	_, err := servicemanager.Team.FindByName(name)
	if err != nil {
		if err == authTypes.ErrTeamNotFound {
			return &errors.HTTP{Code: http.StatusNotFound, Message: err.Error()}
		}
		return err
	}
	evt, err := event.New(&event.Opts{
		Target:     teamTarget(name),
		Kind:       permission.PermTeamUpdate,
		Owner:      t,
		CustomData: event.FormToCustomData(InputFields(r)),
		Allowed:    event.Allowed(permission.PermTeamReadEvents, permission.Context(permTypes.CtxTeam, name)),
	})
	if err != nil {
		return err
	}
	defer func() { evt.Done(err) }()
	if changeRequest.NewName == "" {
		return servicemanager.Team.Update(name, changeRequest.Tags)
	}
	u, err := t.User()
	if err != nil {
		return err
	}
	err = servicemanager.Team.Create(changeRequest.NewName, changeRequest.Tags, u)
	if err != nil {
		return err
	}
	var toRollback []func(oldName, newName string) error
	defer func() {
		if err == nil {
			return
		}
		rollbackErr := servicemanager.Team.Remove(changeRequest.NewName)
		if rollbackErr != nil {
			log.Errorf("error rolling back team creation from %v to %v", name, changeRequest.NewName)
		}
		for _, rollbackFn := range toRollback {
			rollbackErr := rollbackFn(changeRequest.NewName, name)
			if rollbackErr != nil {
				fnName := runtime.FuncForPC(reflect.ValueOf(rollbackFn).Pointer()).Name()
				log.Errorf("error rolling back team name change in %v from %q to %q", fnName, name, changeRequest.NewName)
			}
		}
	}()
	for _, fn := range teamRenameFns {
		err = fn(name, changeRequest.NewName)
		if err != nil {
			return err
		}
		toRollback = append(toRollback, fn)
	}
	return servicemanager.Team.Remove(name)
}
// title: team update
// path: /teams/{name}
// method: PUT
// consume: application/x-www-form-urlencoded
// responses:
//   200: Team updated
//   400: Invalid data
//   401: Unauthorized
//   404: Team not found