bool PNS_DIFF_PAIR_PLACER::findDpPrimitivePair( const VECTOR2I& aP, PNS_ITEM* aItem, PNS_DP_PRIMITIVE_PAIR& aPair )
{
    int netP, netN;

    wxLogTrace( "PNS", "world %p\n", m_world );

    bool result = m_world->GetRuleResolver()->DpNetPair( aItem, netP, netN );

    if( !result )
        return false;

    int refNet = aItem->Net();
    int coupledNet = ( refNet == netP ) ? netN : netP;

    wxLogTrace( "PNS", "result %d\n", !!result );

    OPT_VECTOR2I refAnchor = getDanglingAnchor( m_currentNode, aItem );
    PNS_ITEM* primRef = aItem;

    wxLogTrace( "PNS", "refAnchor %p\n", aItem );

    if( !refAnchor )
        return false;

    std::set<PNS_ITEM*> coupledItems;

    m_currentNode->AllItemsInNet( coupledNet, coupledItems );
    double bestDist = std::numeric_limits<double>::max();
    bool found = false;

    for( PNS_ITEM* item : coupledItems )
    {
        if( item->Kind() == aItem->Kind() )
        {
            OPT_VECTOR2I anchor = getDanglingAnchor( m_currentNode, item );
            if( !anchor )
                continue;

            double dist = ( *anchor - *refAnchor ).EuclideanNorm();

            bool shapeMatches = true;

            if( item->OfKind( PNS_ITEM::SOLID ) && item->Layers() != aItem->Layers() )
            {
                shapeMatches = false;
            }

            if( dist < bestDist && shapeMatches )
            {
                found = true;
                bestDist = dist;

                if( refNet == netP )
                {
                    aPair = PNS_DP_PRIMITIVE_PAIR ( item, primRef );
                    aPair.SetAnchors( *anchor, *refAnchor );
                }
                else
                {
                    aPair = PNS_DP_PRIMITIVE_PAIR( primRef, item );
                    aPair.SetAnchors( *refAnchor, *anchor );
                }
            }
        }
    }

    return found;
}
bool PNS_DIFF_PAIR_PLACER::findDpPrimitivePair( const VECTOR2I& aP, PNS_ITEM* aItem, PNS_DP_PRIMITIVE_PAIR& aPair )
{
    if( !aItem || !aItem->Parent() || !aItem->Parent()->GetNet() )
        return false;

    wxString netNameP = aItem->Parent()->GetNet()->GetNetname();
    wxString netNameN, netNameBase;

    BOARD* brd = Router()->GetBoard();
    PNS_ITEM *primRef = NULL, *primP = NULL, *primN = NULL;

    int refNet;

    wxString suffix;

    int r = matchDpSuffix ( netNameP, suffix, netNameBase );

    if( r == 0 )
        return false;
    else if( r == 1 )
    {
        primRef = primP = static_cast<PNS_SOLID*>( aItem );
        netNameN = netNameBase + suffix;
    }
    else
    {
        primRef = primN = static_cast<PNS_SOLID*>( aItem );
        netNameN = netNameP;
        netNameP = netNameBase + suffix;
    }

    NETINFO_ITEM* netInfoP = brd->FindNet( netNameP );
    NETINFO_ITEM* netInfoN = brd->FindNet( netNameN );
    
    if( !netInfoP || !netInfoN )
        return false;

    int netP = netInfoP->GetNet();
    int netN = netInfoN->GetNet();

    if( primP )
        refNet = netN;
    else
        refNet = netP;


    std::set<PNS_ITEM*> items;

    OPT_VECTOR2I refAnchor = getDanglingAnchor( m_currentNode, primRef );

    if( !refAnchor )
        return false;

    m_currentNode->AllItemsInNet( refNet, items );
    double bestDist = std::numeric_limits<double>::max();
    bool found = false;

    BOOST_FOREACH(PNS_ITEM* item, items )
    {
        if( item->Kind() == aItem->Kind() )
        {
            OPT_VECTOR2I anchor = getDanglingAnchor( m_currentNode, item );
            if( !anchor )
                continue;

            double dist = ( *anchor - *refAnchor ).EuclideanNorm();

            if( dist < bestDist )
            {
                found = true;
                bestDist = dist;

                if( refNet == netP )
                {
                    aPair = PNS_DP_PRIMITIVE_PAIR ( item, primRef );
                    aPair.SetAnchors( *anchor, *refAnchor );
                }
                else
                {
                    aPair = PNS_DP_PRIMITIVE_PAIR( primRef, item );
                    aPair.SetAnchors( *refAnchor, *anchor );
                }
            }
        }
    }

    return found;
}