protected void registerClient( KernelAdapter ka, Endpoint p, ClientRegistrationMessage m )
    {
        Connection addedConnection = null;

        // Generally this will only be called by one thread, but it's
        // so important that I won't take chances.
        synchronized( this ) {       
            // Grab the random ID that the client created when creating
            // its two registration messages
            long tempId = m.getId();
 
            // See if we already have one
            Connection c = connecting.remove(tempId);
            if( c == null ) {
                c = new Connection(channels.size());
                log.log( Level.FINE, "Registering client for endpoint, pass 1:{0}.", p );
            } else {
                log.log( Level.FINE, "Refining client registration for endpoint:{0}.", p );
            } 
          
            // Fill in what we now know
            int channel = getChannel(ka); 
            c.setChannel(channel, p);            
            log.log( Level.FINE, "Setting up channel:{0}", channel );
 
            // If it's channel 0, then this is the initial connection,
            // and we will send the connection information.
            if( channel == CH_RELIABLE ) {
                // Validate the name and version which is only sent
                // over the reliable connection at this point.
                if( !getGameName().equals(m.getGameName()) 
                    || getVersion() != m.getVersion() ) {
 
                    log.log( Level.FINE, "Kicking client due to name/version mismatch:{0}.", c );
            
                    // Need to kick them off... I may regret doing this from within
                    // the sync block but the alternative is more code
                    c.close( "Server client mismatch, server:" + getGameName() + " v" + getVersion()
                             + "  client:" + m.getGameName() + " v" + m.getVersion() );
                    return;                        
                }
                
                // Else send the extra channel information to the client
                if( !alternatePorts.isEmpty() ) {
                    ChannelInfoMessage cim = new ChannelInfoMessage( m.getId(), alternatePorts );
                    c.send(cim);
                }
            }

            if( c.isComplete() ) {             
                // Then we are fully connected
                if( connections.put( c.getId(), c ) == null ) {
                
                    for( Endpoint cp : c.channels ) {
                        if( cp == null )
                            continue;
                        endpointConnections.put( cp, c );
                    } 
 
                    addedConnection = c;               
                }
            } else {
                // Need to keep getting channels, so we'll keep it in
                // the map.
                connecting.put(tempId, c);
            } 
        }
 
        // Best to do this outside of the synch block to avoid
        // over synchronizing which is the path to deadlocks
        if( addedConnection != null ) {       
            log.log( Level.FINE, "Client registered:{0}.", addedConnection );
            
            // Send the ID back to the client letting it know it's
            // fully connected.
            m = new ClientRegistrationMessage();
            m.setId( addedConnection.getId() );
            m.setReliable(true);
            addedConnection.send(m);
            
            // Now we can notify the listeners about the
            // new connection.
            fireConnectionAdded( addedConnection );
            
            // Send a second registration message with an invalid ID
            // to let the connection know that it can start its services
            m = new ClientRegistrationMessage();
            m.setId(-1);
            m.setReliable(true);
            addedConnection.send(m);            
        }            
    }
A default implementation of the Server interface that delegates
 its network connectivity to kernel.Kernel.

 @version   $Revision$
 @author    Paul Speed
jme3-networking/src/main/java/com/jme3/network/base/DefaultServer.java