text: import time
  import asyncio
  import typing
  import collections
  import logging
  
  log = logging.getLogger(__name__)
  
  
  CONNECTED_EVENT = "connected"
  DISCONNECTED_EVENT = "disconnected"
  TRANSFERRED_EVENT = "transferred"
  
  
  class ConnectionManager:
      def __init__(self, loop: asyncio.AbstractEventLoop):
          self.loop = loop
          self.incoming_connected: typing.Set[str] = set()
          self.incoming: typing.DefaultDict[str, int] = collections.defaultdict(int)
          self.outgoing_connected: typing.Set[str] = set()
          self.outgoing: typing.DefaultDict[str, int] = collections.defaultdict(int)
          self._max_incoming_mbs = 0.0
          self._max_outgoing_mbs = 0.0
          self._status = {}
          self._running = False
          self._task: typing.Optional[asyncio.Task] = None
  
      @property
      def status(self):
          return self._status
  
      def sent_data(self, host_and_port: str, size: int):
          if self._running:
              self.outgoing[host_and_port] += size
  
      def received_data(self, host_and_port: str, size: int):
          if self._running:
              self.incoming[host_and_port] += size
  
      def connection_made(self, host_and_port: str):
          if self._running:
              self.outgoing_connected.add(host_and_port)
  
      def connection_received(self, host_and_port: str):
          # self.incoming_connected.add(host_and_port)
          pass
  
      def outgoing_connection_lost(self, host_and_port: str):
          if self._running and host_and_port in self.outgoing_connected:
              self.outgoing_connected.remove(host_and_port)
  
      def incoming_connection_lost(self, host_and_port: str):
          if self._running and host_and_port in self.incoming_connected:
              self.incoming_connected.remove(host_and_port)
  
      async def _update(self):
          self._status = {
              'incoming_bps': {},
              'outgoing_bps': {},
              'total_incoming_mbs': 0.0,
              'total_outgoing_mbs': 0.0,
              'total_sent': 0,
              'total_received': 0,
              'max_incoming_mbs': 0.0,
              'max_outgoing_mbs': 0.0
          }
  
          while True:
              last = time.perf_counter()
              await asyncio.sleep(0.1, loop=self.loop)
              self._status['incoming_bps'].clear()
              self._status['outgoing_bps'].clear()
              now = time.perf_counter()
              while self.outgoing:
                  k, sent = self.outgoing.popitem()
                  self._status['total_sent'] += sent
                  self._status['outgoing_bps'][k] = sent / (now - last)
              while self.incoming:
                  k, received = self.incoming.popitem()
                  self._status['total_received'] += received
                  self._status['incoming_bps'][k] = received / (now - last)
              self._status['total_outgoing_mbs'] = int(sum(list(self._status['outgoing_bps'].values())
                                                           )) / 1000000.0
              self._status['total_incoming_mbs'] = int(sum(list(self._status['incoming_bps'].values())
                                                           )) / 1000000.0
              self._max_incoming_mbs = max(self._max_incoming_mbs, self._status['total_incoming_mbs'])
              self._max_outgoing_mbs = max(self._max_outgoing_mbs, self._status['total_outgoing_mbs'])
              self._status['max_incoming_mbs'] = self._max_incoming_mbs
              self._status['max_outgoing_mbs'] = self._max_outgoing_mbs
  
      def stop(self):
          if self._task:
              self._task.cancel()
              self._task = None
          self.outgoing.clear()
          self.outgoing_connected.clear()
          self.incoming.clear()
          self.incoming_connected.clear()
          self._status.clear()
          self._running = False
  
      def start(self):
          self.stop()
          self._running = True
          self._task = self.loop.create_task(self._update())
  