bool BOARD_NETLIST_UPDATER::testConnectivity( NETLIST& aNetlist )
{
    // Last step: Some tests:
    // verify all pads found in netlist:
    // They should exist in footprints, otherwise the footprint is wrong
    // note also references or time stamps are updated, so we use only
    // the reference to find a footprint
    //
    // Also verify if zones have acceptable nets, i.e. nets with pads.
    // Zone with no pad belongs to a "dead" net which happens after changes in schematic
    // when no more pad use this net name.

    wxString msg;
    wxString padname;

    for( int i = 0; i < (int) aNetlist.GetCount(); i++ )
    {
        const COMPONENT* component = aNetlist.GetComponent( i );
        MODULE* footprint = m_board->FindModuleByReference( component->GetReference() );

        if( footprint == NULL )    // It can be missing in partial designs
            continue;

        // Explore all pins/pads in component
        for( unsigned jj = 0; jj < component->GetNetCount(); jj++ )
        {
            COMPONENT_NET net = component->GetNet( jj );
            padname = net.GetPinName();

            if( footprint->FindPadByName( padname ) )
                continue;   // OK, pad found

            // not found: bad footprint, report error
            msg.Printf( _( "Component %s pad %s not found in footprint %s\n" ),
                        GetChars( component->GetReference() ),
                        GetChars( padname ),
                        GetChars( footprint->GetFPID().Format() ) );
            m_reporter->Report( msg, REPORTER::RPT_ERROR );
            ++m_errorCount;
        }
    }

    // Test copper zones to detect "dead" nets (nets without any pad):
    for( int i = 0; i < m_board->GetAreaCount(); i++ )
    {
        ZONE_CONTAINER* zone = m_board->GetArea( i );

        if( !zone->IsOnCopperLayer() || zone->GetIsKeepout() )
            continue;

        int nc = zone->GetNet()->GetNodesCount();

        if( nc == 0 )
        {
            msg.Printf( _( "Copper zone (net name %s): net has no pads connected." ),
                        GetChars( zone->GetNet()->GetNetname() ) );
            m_reporter->Report( msg, REPORTER::RPT_WARNING );
            ++m_warningCount;
        }
    }

    return true;
}
/* Execute a remote command send by Eeschema via a socket,
 * port KICAD_PCB_PORT_SERVICE_NUMBER
 * cmdline = received command from Eeschema
 * Commands are
 * $PART: "reference"   put cursor on component
 * $PIN: "pin name"  $PART: "reference" put cursor on the footprint pin
 */
void PCB_EDIT_FRAME::ExecuteRemoteCommand( const char* cmdline )
{
    char            line[1024];
    wxString        msg;
    wxString        modName;
    char*           idcmd;
    char*           text;
    MODULE*         module = 0;
    BOARD* pcb = GetBoard();
    wxPoint         pos;

    strncpy( line, cmdline, sizeof(line) - 1 );

    idcmd = strtok( line, " \n\r" );
    text  = strtok( NULL, " \n\r" );

    if( !idcmd || !text )
        return;

    if( strcmp( idcmd, "$PART:" ) == 0 )
    {
        modName = FROM_UTF8( text );

        module = pcb->FindModuleByReference( modName );

        if( module )
            msg.Printf( _( "%s found" ), GetChars( modName ) );
        else
            msg.Printf( _( "%s not found" ), GetChars( modName ) );

        SetStatusText( msg );

        if( module )
            pos = module->GetPosition();
    }
    else if( strcmp( idcmd, "$PIN:" ) == 0 )
    {
        wxString pinName;
        D_PAD*   pad     = NULL;
        int      netcode = -1;

        pinName = FROM_UTF8( text );

        text = strtok( NULL, " \n\r" );
        if( text && strcmp( text, "$PART:" ) == 0 )
            text = strtok( NULL, "\n\r" );

        modName = FROM_UTF8( text );

        module = pcb->FindModuleByReference( modName );

        if( module )
            pad = module->FindPadByName( pinName );

        if( pad )
        {
            netcode = pad->GetNetCode();

            // put cursor on the pad:
            pos = pad->GetPosition();
        }

        if( netcode > 0 )               // highlight the pad net
        {
            pcb->HighLightON();
            pcb->SetHighLightNet( netcode );
        }
        else
        {
            pcb->HighLightOFF();
            pcb->SetHighLightNet( -1 );
        }

        if( module == NULL )
        {
            msg.Printf( _( "%s not found" ), GetChars( modName ) );
        }
        else if( pad == NULL )
        {
            msg.Printf( _( "%s pin %s not found" ), GetChars( modName ), GetChars( pinName ) );
            SetCurItem( module );
        }
        else
        {
            msg.Printf( _( "%s pin %s found" ), GetChars( modName ), GetChars( pinName ) );
            SetCurItem( pad );
        }

        SetStatusText( msg );
    }

    if( module )  // if found, center the module on screen, and redraw the screen.
    {
        SetCrossHairPosition( pos );
        RedrawScreen( pos, false );
    }
}