<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def bind_protocol(self, proto):
 """Tries to bind given protocol to this peer. Should only be called by `proto` trying to bind. Once bound this protocol instance will be used to communicate with peer. If another protocol is already bound, connection collision resolution takes place. """

        LOG.debug('Trying to bind protocol %s to peer %s', proto, self)
        # Validate input.
        if not isinstance(proto, BgpProtocol):
            raise ValueError('Currently only supports valid instances of'
                             ' `BgpProtocol`')

        if proto.state != const.BGP_FSM_OPEN_CONFIRM:
            raise ValueError('Only protocols in OpenConfirm state can be'
                             ' bound')

        # If we are not bound to any protocol
        is_bound = False
        if not self._protocol:
            self._set_protocol(proto)
            is_bound = True
        else:
            # If existing protocol is already established, we raise exception.
            if self.state.bgp_state != const.BGP_FSM_IDLE:
                LOG.debug('Currently in %s state, hence will send collision'
                          ' Notification to close this protocol.',
                          self.state.bgp_state)
                self._send_collision_err_and_stop(proto)
                return

            # If we have a collision that need to be resolved
            assert proto.is_colliding(self._protocol), \
                ('Tried to bind second protocol that is not colliding with '
                 'first/bound protocol')
            LOG.debug('Currently have one protocol in %s state and '
                      'another protocol in %s state',
                      self._protocol.state, proto.state)
            # Protocol that is already bound
            first_protocol = self._protocol
            assert ((first_protocol.is_reactive and not proto.is_reactive) or
                    (proto.is_reactive and not first_protocol.is_reactive))
            # Connection initiated by peer.
            reactive_proto = None
            # Connection initiated locally.
            proactive_proto = None
            # Identify which protocol was initiated by which peer.
            if proto.is_reactive:
                reactive_proto = proto
                proactive_proto = self._protocol
            else:
                reactive_proto = self._protocol
                proactive_proto = proto

            LOG.debug('Pro-active/Active protocol %s', proactive_proto)
            # We compare bgp local and remote router id and keep the protocol
            # that was initiated by peer with highest id.
            if proto.is_local_router_id_greater():
                self._set_protocol(proactive_proto)
            else:
                self._set_protocol(reactive_proto)

            if self._protocol is not proto:
                # If new proto did not win collision we return False to
                # indicate this.
                is_bound = False
            else:
                # If first protocol did not win collision resolution we
                # we send notification to peer and stop it
                self._send_collision_err_and_stop(first_protocol)
                is_bound = True

        return is_bound