<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def _do_report(self, report, in_port, msg):
 """the process when the snooper received a REPORT message."""

        datapath = msg.datapath
        dpid = datapath.id
        ofproto = datapath.ofproto
        parser = datapath.ofproto_parser

        if ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION:
            size = 65535
        else:
            size = ofproto.OFPCML_MAX

        # check whether the querier port has been specified.
        outport = None
        value = self._to_querier.get(dpid)
        if value:
            outport = value['port']

        # send a event when the multicast group address is new.
        self._to_hosts.setdefault(dpid, {})
        if not self._to_hosts[dpid].get(report.address):
            self._send_event(
                EventMulticastGroupStateChanged(
                    MG_GROUP_ADDED, report.address, outport, []))
            self._to_hosts[dpid].setdefault(
                report.address,
                {'replied': False, 'leave': None, 'ports': {}})

        # set a flow entry from a host to the controller when
        # a host sent a REPORT message.
        if not self._to_hosts[dpid][report.address]['ports'].get(
                in_port):
            self._to_hosts[dpid][report.address]['ports'][
                in_port] = {'out': False, 'in': False}
            self._set_flow_entry(
                datapath,
                [parser.OFPActionOutput(ofproto.OFPP_CONTROLLER, size)],
                in_port, report.address)

        if not self._to_hosts[dpid][report.address]['ports'][
                in_port]['out']:
            self._to_hosts[dpid][report.address]['ports'][
                in_port]['out'] = True

        if not outport:
            self.logger.info("no querier exists.")
            return

        # set a flow entry from a multicast server to hosts.
        if not self._to_hosts[dpid][report.address]['ports'][
                in_port]['in']:
            actions = []
            ports = []
            for port in self._to_hosts[dpid][report.address]['ports']:
                actions.append(parser.OFPActionOutput(port))
                ports.append(port)
            self._send_event(
                EventMulticastGroupStateChanged(
                    MG_MEMBER_CHANGED, report.address, outport, ports))
            self._set_flow_entry(
                datapath, actions, outport, report.address)
            self._to_hosts[dpid][report.address]['ports'][
                in_port]['in'] = True

        # send a REPORT message to the querier if this message arrived
        # first after a QUERY message was sent.
        if not self._to_hosts[dpid][report.address]['replied']:
            actions = [parser.OFPActionOutput(outport, size)]
            self._do_packet_out(datapath, msg.data, in_port, actions)
            self._to_hosts[dpid][report.address]['replied'] = True