code: func (s *session) addParty(p *party) error {
  	if s.login != p.login {
  		return trace.AccessDenied(
  			"can't switch users from %v to %v for session %v",
  			s.login, p.login, s.id)
  	}
  
  	// Adds participant to in-memory map of party members.
  	s.addPartyMember(p)
  
  	// Write last chunk (so the newly joined parties won't stare at a blank
  	// screen).
  	getRecentWrite := func() []byte {
  		s.writer.Lock()
  		defer s.writer.Unlock()
  		data := make([]byte, 0, 1024)
  		for i := range s.writer.recentWrites {
  			data = append(data, s.writer.recentWrites[i]...)
  		}
  		return data
  	}
  	p.Write(getRecentWrite())
  
  	// Register this party as one of the session writers (output will go to it).
  	s.writer.addWriter(string(p.id), p, true)
  	p.ctx.AddCloser(p)
  	s.term.AddParty(1)
  
  	s.log.Infof("New party %v joined session: %v", p.String(), s.id)
  
  	// This goroutine keeps pumping party's input into the session.
  	go func() {
  		defer s.term.AddParty(-1)
  		_, err := io.Copy(s.term.PTY(), p)
  		if err != nil {
  			s.log.Errorf("Party member %v left session %v due an error: %v", p.id, s.id, err)
  		}
  		s.log.Infof("Party member %v left session %v.", p.id, s.id)
  	}()
  	return nil
  }
docs: // addParty is called when a new party joins the session.