private bool CanRegister(NodeConnection connection)
 {
     if (cancellationToken.IsCancellationRequested)
     {
         return false;
     }
     if (connection.Direction == NodeConnectionDirection.Incoming)
     {
         if (incomingConnectionsCount >= maxIncomingConnectionsCount)
         {
             return false;
         }
         //todo: should IsConnected be checked for incoming connections?
     }
     else if (connection.Direction == NodeConnectionDirection.Outgoing)
     {
         if (outgoingConnectionsCount >= maxOutgoingConnectionsCount)
         {
             return false;
         }
         if (IsConnected(connection.Endpoint.PeerInfo.IpEndpoint.Address))
         {
             return false;
         }
     }
     else
     {
         throw new InvalidOperationException($"Unexpected connection direction: {connection.Direction}.");
     }
     return true;
 }
 private void Remove(NodeConnection connection)
 {
     lock (lockObject)
     {
         if (!connections.Remove(connection))
         {
             return;
         }
         if (connection.Direction == NodeConnectionDirection.Incoming)
         {
             incomingConnectionsCount--;
         }
         else if (connection.Direction == NodeConnectionDirection.Outgoing)
         {
             outgoingConnectionsCount--;
         }
         else
         {
             throw new InvalidOperationException($"Unexpected connection direction: {connection.Direction}.");
         }
     }
     Changed?.Invoke();
 }
        /// <summary>
        /// Adds a connection to the collection.
        /// <para/>
        /// Can reject the connection if the cancellation token was cancelled or the maximum number of connections is reached.
        /// </summary>
        /// <param name="direction">The direction of the connection.</param>
        /// <param name="endpoint">The connection to a Bitcoin node.</param>
        /// <returns>true if the connection was accepted; otherwise false.</returns>
        public bool Add(NodeConnectionDirection direction, BitcoinEndpoint endpoint)
        {
            NodeConnection connection = new NodeConnection(direction, endpoint);

            lock (lockObject)
            {
                if (!CanRegister(connection))
                {
                    return false;
                }

                if (direction == NodeConnectionDirection.Incoming)
                {
                    incomingConnectionsCount++;
                }
                else if (direction == NodeConnectionDirection.Outgoing)
                {
                    outgoingConnectionsCount++;
                }
                else
                {
                    throw new InvalidOperationException($"Unexpected connection direction: {direction}.");
                }

                connections.Add(connection);
            }

            endpoint.CallWhenDisconnected(() => Remove(connection));

            Changed?.Invoke();

            return true;
        }