private Filter.FilterAction buildExtractionTreeForFollow(ExtractedNode node, Cmd cmd)
            throws Exception
    {
        if (cmd.getType() != Cmd.CmdType.FOLLOW) {
            throw new Exception("Expected FOLLOW command");
        }
        CmdArg link = cmd.getArg("FOLLOW");
        CmdArg with = cmd.getArg("WITH");
        CmdArg populate = cmd.getArg("POPULATE");
        CmdArg filterCmdArg = cmd.getArg("FILTER");
        CmdArg filterArgs = cmd.getArg("FILTER_ARGS");

        EvalContext evalContext = new EvalContext();
        populateEvalContext(evalContext, node);
        FileDownload fd = FileDownload.getInst();
        String nextURL = fd.createValidURL(thisURL, link.evaluate(evalContext));
        Filter.FilterAction ok = Filter.FilterAction.VISIT;
        Filter filter = null;
        nextURL = fd.normalizeURL(nextURL);
        // apply filter
        if (filterCmdArg != null) {
            FilterLoader filterLoader = FilterLoader.getFilterLoader();
            filter = filterLoader.loadFilter(filterCmdArg.toString());
            filter.init(filterArgs.toString());
            ok = filter.doVisit(nextURL, depth, childNum);
        }

        if (ok != Filter.FilterAction.VISIT) return ok;
        String file = null;
        try {
            file = fd.getDownloadedFile(nextURL);
            String fwdUrl = getMetaRefreshNextUrl(nextURL, file);
            if (fwdUrl != null) {
                nextURL = fwdUrl;
                file = fd.getDownloadedFile(nextURL);
            }
        } catch (Exception ex) {
            // do nothing. just make sure we continue
            // with remaining links
            return Filter.FilterAction.DONT_VISIT;
        }
        childNum++;
        if (filter != null) {
            filter.visit(file);
        }

        String newRuleFile = with.evaluate(evalContext);
        File rf = new File(newRuleFile);
        if (!rf.isFile()) {
            // file not present. try out file in parent rules file's dir
            File pf = new File(currRuleFile);
            String dir = pf.getParent();
            if (dir == null) {
                throw new Exception("Can't find rule file " + newRuleFile);
            }
            rf = new File(dir, newRuleFile);
            if (!rf.isFile()) {
                throw new Exception("Can't find rule file " + newRuleFile);
            }
            newRuleFile = rf.getPath();
        }

        RuleTreeExtractor rex = new RuleTreeExtractor(newRuleFile,
                                        depth + 1);
        ExtractedNode child = rex.collect(nextURL, file);

        //  now merge the new tree in the correct scope
        populateCorrectScope(child, populate);
        return ok;
    }