private static IProjectEventListener generateIProjectEventListener(final List<ExternalFinderItem> finderItems) {
        return new IProjectEventListener() {
            private final List<Component> menuItems = new ArrayList<Component>();

            @Override
            public void onProjectChanged(final IProjectEventListener.PROJECT_CHANGE_TYPE eventType) {
                switch (eventType) {
                    case LOAD:
                        onLoad();
                        break;
                    case CLOSE:
                        onClose();
                        break;
                    default:
                    // ignore
                }
            }

            private void onLoad() {
                // clear old items
                menuItems.clear();
                synchronized (finderItems) {
                    finderItems.clear();
                }

                // load user's xml file
                // Even though the file is independent from projects, it is
                // loaded when a project is loaded for providing a chance to reload it.
                final String configDir = StaticUtils.getConfigDir();
                final File userFile = new File(configDir, FINDER_FILE);
                if (userFile.canRead()) {
                    final IExternalFinderItemLoader userItemLoader = new ExternalFinderXMLItemLoader(userFile);
                    final List<ExternalFinderItem> loadedUserItems = userItemLoader.load();

                    synchronized (finderItems) {
                        finderItems.addAll(loadedUserItems);
                    }
                }

                // load project's xml file
                final IProject currentProject = Core.getProject();
                final ProjectProperties projectProperties = currentProject.getProjectProperties();
                final String projectRoot = projectProperties.getProjectRoot();
                final File projectFile = new File(projectRoot, FINDER_FILE);
                if (projectFile.canRead()) {
                    final IExternalFinderItemLoader projectItemLoader = new ExternalFinderXMLItemLoader(projectFile);
                    final List<ExternalFinderItem> loadedProjectItems = projectItemLoader.load();

                    synchronized (finderItems) {
                        // replace duplicated items based on name
                        for (ExternalFinderItem item : finderItems) {
                            if (loadedProjectItems.contains(item)) {
                                final int index = loadedProjectItems.indexOf(item);
                                final ExternalFinderItem newItem = loadedProjectItems.get(index);
                                item.replaceRefs(newItem);
                                loadedProjectItems.remove(index);
                            }
                        }

                        finderItems.addAll(loadedProjectItems);
                    }
                }

                // add finder items to menuItems
                final IExternalFinderItemMenuGenerator generator
                        = new ExternalFinderItemMenuGenerator(finderItems, ExternalFinderItem.TARGET.BOTH, false);
                final List<Component> newMenuItems = generator.generate();
                menuItems.addAll(newMenuItems);

                // add menuItems to menu
                final JMenu toolsMenu = Core.getMainWindow().getMainMenu().getToolsMenu();
                for (Component component : menuItems) {
                    toolsMenu.add(component);
                }
            }

            private void onClose() {
                // remove menu items
                final JMenu menu = Core.getMainWindow().getMainMenu().getToolsMenu();
                for (int i = 0, n = menuItems.size(); i < n; i++) {
                    menu.remove(menuItems.get(i));
                }
                menuItems.clear();

                synchronized (finderItems) {
                    finderItems.clear();
                }
            }
        };
    }