int CNBipartiteGraph::calcFullSrcMatch_IIIsortedSnks(CNBiGrMtc& mtc, int noFull)
{
    CNBiGrVtxIdxVec& result = mtc.getSrcToSnk();
    CNBiGrVtxIdxVec& usedBy = mtc.getSnkToSrc();

    // Perform a typed full source match where priority of types is
    // given by order of sinks. Sources are dense and order is not
    // important.
    // Parameter indicates that we don't search for full match -> max match
    // only, were max means maxim. number of matched sinks or srcs.
    // First sinks are taken first to match sources, therefore we store types
    // which are to be used as late as possible at the end. All sinks with
    // same type could be sorted by nearness to request (-> near objects
    // are calculated more often).
    //
    // Algorithm:
    //	The (typed) net in this bipartite graph is not used directly. Instead
    //  of we use a local bipartite graph for representation of actual graph.
    //	This local graph consists only of locSnks, the used sinks which are 
    //	inserted with all their edges (because they represent alternatives
    //	which can be used in augmenting paths). Initially locSnk is empty.
    //
    //	We iterate about given sorted sinks. For each we try to find a match.
    //  If there is a directly connected free source we use it. If all 
    //	connected sources are used we try to find an augmenting (or a switch)
    //	path to a free source. If there are no free sources at all we have
    //  reached a full (and therefore max) match and can return. If there is 
    //  no path this means all connected sources use sinks which can not 
    //  be switched.
    //  A path starts from a sink and ends at a source. So unused sinks are not
    //  of interest (if we search from a sink) because they can never be in a
    //	path (As start they were a flop as tested just now. As middle they
    //	can't be used because there is no matching edge to switch. As end
    //	they can't be used because if we start from sinks we need a source
    //	at the end.)
    //
    //	We don't use a first guess. It could cause use of sinks which may
    //  be avoided by finding an augmenting path for a sink with lesser index.
    //
    //	Complexity is better than #sinks * #edges because we use local edges
    //	and the number of local edges is at first = 0 and then increasing by
    //	number of edges to a used sink.
    //
    
    CNBiGrVtxIdx numSnks = getNumSnks();
    CNBiGrVtxIdx numSrcs = getNumSrcs();
    if (noFull == 0 && numSnks < numSrcs)
        return 0;   // no full source match possible

    result.resize(numSrcs); result.setAllToE0();    // stores actual match
    usedBy.resize(numSnks); usedBy.setAllToE0();    // stores actual match 
    if (getNumSrcs() == 0)	// no src -> always a match
	return 1;

    CNBiGrVtxVecFixed locSnks(numSnks,CNBiGrInvVtx);  // local sinks & edges
    CNBiGrVtxIdxBufFixed snkX(numSnks);  // snks to expand
    CNBiGrVtxIdxVecFixed snkC(numSnks,CNBiGrInvVtxIdx);  // to track paths
    CNBiGrVtxIdxVecFixed srcL(numSrcs,CNBiGrInvVtxIdx);  // layer info

    CNBiGrVtxIdx matches  = 0; // actual number of matches
    CNBiGrVtxIdx reserve  = numSnks - numSrcs; // max number of unmatched snks
	// reserve is only used in full matches !!!
    CNBiGrVtxIdx snk0, snk, src, nxt, i, n;
    for (snk0 = 0; snk0 < numSnks; snk0++){
	
	// search a path from snk0 to an unused source
	snkX.clear();
	nxt = 0;    // initially a valid idx

	// generate first generation (we prefer special test and do not
	// insert snk0 into locSnks before we know that it is ok)
	snk = snk0;
	n = snks[snk].getNumEdgs();
	for(i=1;i<=n;i++){ // orig: 0..<n  @@@1
	    src = snks[snk].getEdgTo(n-i); // @@@1
	    nxt = result[src];
	    if (nxt == CNBiGrInvVtxIdx) // path end found (src is the end)
		break;
	    else{ // nxt is index of next possible snk in path
		snkC[nxt] = snk;	    // we came from snk0
		snkX.append(nxt);	    // expand this snk too
	    }
	    srcL[src] = snk0; // now in layer for processing snk0
	}

	while(snkX.getLen() != 0   &&   nxt != CNBiGrInvVtxIdx){
	    snk = snkX.pop();
	    n = locSnks[snk].getNumEdgs();
	    for(i=1;i<=n;i++){ // orig: 0..<n  @@@1
		// In second generation one of these srcs is src from which we
		// reached this snk, don't worry it's detected fast via srcL.
		src = locSnks[snk].getEdgTo(n-i); // @@@1
		if (srcL[src] == snk0)
		    continue;	// this src is already checked
		srcL[src] = snk0; // now in layer for processing snk0 
		nxt = result[src];
		if (nxt == CNBiGrInvVtxIdx) // path end found (src is the end)
		    break;
		else{ // nxt is index of next possible snk in path
		    snkC[nxt] = snk;	    // we came from snk
		    snkX.append(nxt);	    // expand this snk too
		}
            }
    	}
	if (nxt != CNBiGrInvVtxIdx){ // snk not usable without making other unused
	    if (noFull == 0 && reserve-- == 0 ) // test reserve for full match
		return 0; // # no reserve for a FULL match
	    continue;	// this sink could not be used -> try next sink
	}

	// switch the path beginning from src, snk is first sink to switch 
	do {
	    nxt = usedBy[snk];	// next src to process
	    usedBy[snk] = src;
	    result[src] = snk;
	    src = nxt;
	    snk = snkC[snk];
	} while(nxt != CNBiGrInvVtxIdx);

    	// this sink could be used, test if full match reached now
	if (++matches == numSrcs)
	    return 1; // each full match is a max match too

	// store new sink and its edges in locSnks
	locSnks[snk0]=snks[snk0];
    }
    return noFull; // noFull (max) matches are OK here, full matches NOT
}