public void run(String url) {

        logger.finest("depth = " + depth);
        logger.finest("url = " + url);

        // 条件によっては処理を終了する
        if (returnOrExitInSomeCasesBeforeRun(url) == ExitStatus.RETURN) {
            return;
        }

        // 2回目以降の処理の待機処理
        waitIfNeeded();

        // URLにアクセスしてリンクURLを取得する
        Spider spider = new Spider();
        List<String> urls = spider.run(url);

        List<String> urlsNeeded = null;
        // 1回目のアクセスでホスト名無しのドメイン名でアクセスし、3xxリダイレクトでホスト付き同ドメインURLが1だけ返ってきた場合
        if (whenRedirectingOn1stAccessWithDomainOnly(Process.getUrlsDone().size(), url, spider.getStatusCode(), urls)) {
            urlsNeeded = urls;
            // 元のURLを変更する
            Process.setUrlOrig(urls.get(0));
        } else {
            // これから処理すべきURLのみを抽出する
            urlsNeeded = extractUrlsNeeded(urls);
        }

        // 条件によっては処理を終了する
        if (returnOrExitInSomeCasesAfterRun(url) == ExitStatus.RETURN) {
            return;
        }

        // 次への処理
        if (this.depth == Constant.MAX_DEPTH) {
            // 見つけたURLは次の巡回で使用するために保存しておく。
            Process.getUrlsLeft().addAll(urlsNeeded);
        } else {
            // 追加されたURLにアクセスする
            for (String urlNeeded: urlsNeeded) {
                (new Process(this.depth + 1)).run(urlNeeded);
            }
        }
    }