public Path<DirectedGraphNode> 
        search(final DirectedGraphNode source,
               final DirectedGraphNode target,
               final WeightFunction<DirectedGraphNode> w) {
        OPEN.clear();
        GSCORE.clear();
        PARENT.clear();
        
        OPEN.add(source, 0.0);
        GSCORE.put(source, 0.0);
        PARENT.put(source, null);
        CLOSED.clear();
        
        final int TARGET_REGION_NUMBER = regionMap.get(target);
        
        while (OPEN.isEmpty() == false) {
            final DirectedGraphNode current = OPEN.extractMinimum();
            
            if (current.equals(target)) {
                return PathFinder.
                       <DirectedGraphNode>constructPath(target, PARENT);
            }
            
            CLOSED.add(current);
            
            for (final DirectedGraphNode child : current) {
                if (CLOSED.contains(child)) {
                    continue;
                }
                
                if (!arcFlags.get(current, child).get(TARGET_REGION_NUMBER)) {
                    continue;
                }
                
                double tmpg = GSCORE.get(current) + w.get(current, child);
                
                if (GSCORE.containsKey(child) == false) {
                    GSCORE.put(child, tmpg);
                    PARENT.put(child, current);
                    OPEN.add(child, tmpg);
                } else if (GSCORE.get(child) > tmpg) {
                    GSCORE.put(child, tmpg);
                    PARENT.put(child, current);
                    OPEN.decreasePriority(child, tmpg);
                }
            }
        }
        
        return Path.NO_PATH;
    }