code: func (c *Client) processPublish(publish *packet.Publish) error {
  	// call callback for unacknowledged and directly acknowledged messages
  	if publish.Message.QOS <= 1 {
  		if c.Callback != nil {
  			err := c.Callback(&publish.Message, nil)
  			if err != nil {
  				return c.die(err, true, true)
  			}
  		}
  	}
  
  	// handle qos 1 flow
  	if publish.Message.QOS == 1 {
  		// prepare puback packet
  		puback := packet.NewPuback()
  		puback.ID = publish.ID
  
  		// acknowledge qos 1 publish
  		err := c.send(puback, true)
  		if err != nil {
  			return c.die(err, false, false)
  		}
  	}
  
  	// handle qos 2 flow
  	if publish.Message.QOS == 2 {
  		// store packet
  		err := c.Session.SavePacket(session.Incoming, publish)
  		if err != nil {
  			return c.die(err, true, false)
  		}
  
  		// prepare pubrec packet
  		pubrec := packet.NewPubrec()
  		pubrec.ID = publish.ID
  
  		// acknowledge qos 2 publish
  		err = c.send(pubrec, true)
  		if err != nil {
  			return c.die(err, false, false)
  		}
  	}
  
  	return nil
  }
docs: // handle an incoming Publish packet