001package jmri.jmrit.beantable;
002
003import java.awt.BorderLayout;
004import java.awt.Component;
005import java.awt.Frame;
006import java.awt.event.ActionEvent;
007import java.awt.event.ActionListener;
008import java.text.MessageFormat;
009import java.util.*;
010
011import javax.swing.*;
012
013import javax.annotation.*;
014
015import jmri.*;
016import jmri.jmrit.blockboss.BlockBossLogic;
017import jmri.jmrit.display.Editor;
018import jmri.jmrit.display.EditorManager;
019import jmri.jmrit.display.Positionable;
020import jmri.jmrit.display.layoutEditor.LayoutBlockManager;
021
022import org.slf4j.Logger;
023import org.slf4j.LoggerFactory;
024
025/**
026 * A collection of static utilities to provide cross referencing information
027 * among the various PanelPro objects. Most likely, this is incomplete as there
028 * still may be references held by objects unknown to the author. It is intended
029 * to inform users where and how the various elements are used. In particular to
030 * identify useless elements ('orphans'). Currently, called only from the Logix
031 * JFrame, which is probably not its ultimate UI.
032 *
033 * @author Pete Cressman Copyright 2009
034 */
035public class Maintenance {
036
037    static final ResourceBundle rbm = ResourceBundle.getBundle("jmri.jmrit.beantable.MaintenanceBundle");
038
039    /**
040     * Find references of a System or User name in the various Manager Objects.
041     *
042     * @param devName name to look for
043     * @param parent Frame calling this method
044     */
045    public static void deviceReportPressed(String devName, Frame parent) {
046        JTextArea text = null;
047        JScrollPane scrollPane = null;
048        text = new javax.swing.JTextArea(25, 50);
049        text.setEditable(false);
050        text.setTabSize(4);
051        search(devName, text);
052        scrollPane = new JScrollPane(text);
053        makeDialog(scrollPane, null, parent, rbm.getString("CrossReferenceTitle"));
054    }
055    
056    /**
057     * get a String List of System Names for a given manager.
058     * <p>
059     * This is NOT a live list, so has to be called each time through.
060     * Do NOT cache the result of this call for later use.
061     * <p>
062     * TODO: Ideally a future refactor will use the getNamedBeanSet directly.
063     * @param mgr the Manager to get the system names for.
064     * @return List of system names.
065     */
066    private static List<String> getSystemNameList(Manager<?> mgr) {
067        ArrayList<String> systemNameList = new ArrayList<>();
068        mgr.getNamedBeanSet().forEach(b -> systemNameList.add(b.getSystemName()));
069        return Collections.unmodifiableList(systemNameList);
070    }
071
072    /**
073     * Find orphaned elements in the various Manager Objects.
074     *
075     * @param parent Frame to check
076     */
077    public static void findOrphansPressed(Frame parent) {
078        Vector<String> display = new Vector<String>();
079        Vector<String> names = new Vector<String>();
080
081        Iterator<String> iter = getSystemNameList(InstanceManager.sensorManagerInstance()).iterator();
082        while (iter.hasNext()) {
083            String name = iter.next();
084            if (!search(name, null) && !name.equals("ISCLOCKRUNNING")) {
085                display.add(MessageFormat.format(rbm.getString("OrphanName"),
086                        (Object[]) getTypeAndNames(name)));
087                names.add(name);
088            }
089        }
090        iter = getSystemNameList(InstanceManager.turnoutManagerInstance()).iterator();
091        while (iter.hasNext()) {
092            String name = iter.next();
093            if (!search(name, null)) {
094                display.add(MessageFormat.format(rbm.getString("OrphanName"),
095                        (Object[]) getTypeAndNames(name)));
096                names.add(name);
097            }
098        }
099        iter = getSystemNameList(InstanceManager.getDefault(SignalHeadManager.class)).iterator();
100        while (iter.hasNext()) {
101            String name = iter.next();
102            if (!search(name, null)) {
103                display.add(MessageFormat.format(rbm.getString("OrphanName"),
104                        (Object[]) getTypeAndNames(name)));
105                names.add(name);
106            }
107        }
108        iter = getSystemNameList(InstanceManager.lightManagerInstance()).iterator();
109        while (iter.hasNext()) {
110            String name = iter.next();
111            if (!search(name, null)) {
112                display.add(MessageFormat.format(rbm.getString("OrphanName"),
113                        (Object[]) getTypeAndNames(name)));
114                names.add(name);
115            }
116        }
117        iter = getSystemNameList(InstanceManager.getDefault(ConditionalManager.class)).iterator();
118        while (iter.hasNext()) {
119            String name = iter.next();
120            if (!search(name, null)) {
121                display.add(MessageFormat.format(rbm.getString("OrphanName"),
122                        (Object[]) getTypeAndNames(name)));
123                names.add(name);
124            }
125        }
126        iter = getSystemNameList(InstanceManager.getDefault(SectionManager.class)).iterator();
127        while (iter.hasNext()) {
128            String name = iter.next();
129            if (!search(name, null)) {
130                display.add(MessageFormat.format(rbm.getString("OrphanName"),
131                        (Object[]) getTypeAndNames(name)));
132                names.add(name);
133            }
134        }
135        iter = getSystemNameList(InstanceManager.getDefault(BlockManager.class)).iterator();
136        while (iter.hasNext()) {
137            String name = iter.next();
138            if (!search(name, null)) {
139                display.add(MessageFormat.format(rbm.getString("OrphanName"),
140                        (Object[]) getTypeAndNames(name)));
141                names.add(name);
142            }
143        }
144        DefaultListModel<String> listModel = new DefaultListModel<>();
145        for (int i = 0; i < display.size(); i++) {
146            listModel.addElement(display.get(i));
147        }
148        JList<String> list = new JList<>(listModel);
149        list.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
150
151        JButton button = new JButton(Bundle.getMessage("ButtonDelete"));
152        button.setToolTipText(rbm.getString("OrphanDeleteHint"));
153
154        class SearchListener implements ActionListener {
155
156            JList<String> list;
157            Vector<String> n;
158
159            SearchListener(JList<String> list, Vector<String> name) {
160                this.list = list;
161                this.n = name;
162            }
163
164            @Override
165            public void actionPerformed(ActionEvent e) {
166                int index = list.getMaxSelectionIndex();
167                if (index < 0) {
168                    javax.swing.JOptionPane.showMessageDialog(null,
169                            rbm.getString("OrphanDeleteHint"),
170                            rbm.getString("DeleteTitle"),
171                            javax.swing.JOptionPane.INFORMATION_MESSAGE);
172                    return;
173                }
174                int min = list.getMinSelectionIndex();
175                DefaultListModel<String> model = (DefaultListModel<String>) list.getModel();
176                while (index >= min) {
177                    String[] names = getTypeAndNames(n.get(index));
178                    if (names[0].equals("Sensor")) { // NOI18N
179                        Sensor s = InstanceManager.sensorManagerInstance().getBySystemName(names[2]);
180                        if (s == null) {
181                            s = InstanceManager.sensorManagerInstance().getBySystemName(names[1]);
182                        }
183                        if (s != null) {
184                            InstanceManager.sensorManagerInstance().deregister(s);
185                        }
186                    } else if (names[0].equals("Turnout")) { // NOI18N
187                        Turnout t = InstanceManager.turnoutManagerInstance().getBySystemName(names[2]);
188                        if (t == null) {
189                            t = InstanceManager.turnoutManagerInstance().getBySystemName(names[1]);
190                        }
191                        if (t != null) {
192                            InstanceManager.turnoutManagerInstance().deregister(t);
193                        }
194                    } else if (names[0].equals("SignalHead")) { // NOI18N
195                        SignalHead sh = InstanceManager.getDefault(jmri.SignalHeadManager.class).getBySystemName(names[2]);
196                        if (sh == null) {
197                            sh = InstanceManager.getDefault(jmri.SignalHeadManager.class).getBySystemName(names[1]);
198                        }
199                        if (sh != null) {
200                            InstanceManager.getDefault(jmri.SignalHeadManager.class).deregister(sh);
201                        }
202                    } else if (names[0].equals("Light")) { // NOI18N
203                        Light l = InstanceManager.lightManagerInstance().getBySystemName(names[2]);
204                        if (l == null) {
205                            l = InstanceManager.lightManagerInstance().getBySystemName(names[1]);
206                        }
207                        if (l != null) {
208                            InstanceManager.lightManagerInstance().deregister(l);
209                        }
210                    } else if (names[0].equals("Conditional")) { // NOI18N
211                        Conditional c = InstanceManager.getDefault(jmri.ConditionalManager.class).getBySystemName(names[2]);
212                        if (c == null) {
213                            c = InstanceManager.getDefault(jmri.ConditionalManager.class).getBySystemName(names[1]);
214                        }
215                        if (c != null) {
216                            InstanceManager.getDefault(jmri.ConditionalManager.class).deregister(c);
217                        }
218                    } else if (names[0].equals("Section")) { // NOI18N
219                        jmri.Section sec = InstanceManager.getDefault(jmri.SectionManager.class).getBySystemName(names[2]);
220                        if (sec == null) {
221                            sec = InstanceManager.getDefault(jmri.SectionManager.class).getBySystemName(names[1]);
222                        }
223                        if (sec != null) {
224                            InstanceManager.getDefault(jmri.SectionManager.class).deregister(sec);
225                        }
226                    } else if (names[0].equals("Block")) { // NOI18N
227                        jmri.Block b = InstanceManager.getDefault(jmri.BlockManager.class).getBySystemName(names[2]);
228                        if (b == null) {
229                            b = InstanceManager.getDefault(jmri.BlockManager.class).getBySystemName(names[1]);
230                        }
231                        if (b != null) {
232                            InstanceManager.getDefault(jmri.BlockManager.class).deregister(b);
233                        }
234                    }
235                    model.remove(index);
236                    n.remove(index);
237                    index--;
238                }
239                index++;
240                if (index >= model.getSize()) {
241                    index = model.getSize() - 1;
242                }
243                if (index >= 0) {
244                    list.setSelectedIndex(index);
245                }
246            }
247        }
248        JScrollPane scrollPane = new JScrollPane(list);
249        button.addActionListener(new SearchListener(list, names));
250        button.setMaximumSize(button.getPreferredSize());
251        makeDialog(scrollPane, button, parent, rbm.getString("OrphanTitle"));
252    }
253
254    /**
255     * Find useless Conditionals in the various Manager Objects.
256     *
257     * @param parent Frame to check
258     */
259    public static void findEmptyPressed(Frame parent) {
260        Vector<String> display = new Vector<String>();
261        Vector<String> names = new Vector<String>();
262
263        log.debug("findEmptyPressed");
264        Iterator<String> iter = getSystemNameList(InstanceManager.getDefault(ConditionalManager.class)).iterator();
265        jmri.ConditionalManager cm = InstanceManager.getDefault(jmri.ConditionalManager.class);
266        while (iter.hasNext()) {
267            String name = iter.next();
268            Conditional c = cm.getBySystemName(name);
269            if (c != null) {
270                List<ConditionalVariable> variableList = c.getCopyOfStateVariables();
271                if (variableList.isEmpty()) {
272                    String userName = c.getUserName();
273                    display.add(MessageFormat.format(rbm.getString("OrphanName"),
274                            new Object[]{"Conditional", userName, name}));
275                    names.add(name);
276                }
277            }
278        }
279        DefaultListModel<String> listModel = new DefaultListModel<>();
280        for (int i = 0; i < display.size(); i++) {
281            listModel.addElement(display.get(i));
282        }
283        JList<String> list = new JList<>(listModel);
284        list.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
285
286        JButton button = new JButton(Bundle.getMessage("ButtonDelete"));
287        button.setToolTipText(rbm.getString("OrphanDeleteHint") + Bundle.getMessage("ButtonDelete"));
288
289        class EmptyListener implements ActionListener {
290
291            JList<String> list;
292            Vector<String> name;
293
294            EmptyListener(JList<String> list, Vector<String> name) {
295                this.list = list;
296                this.name = name;
297            }
298
299            @Override
300            public void actionPerformed(ActionEvent e) {
301                int index = list.getMaxSelectionIndex();
302                if (index < 0) {
303                    javax.swing.JOptionPane.showMessageDialog(null,
304                            rbm.getString("OrphanDeleteHint"),
305                            rbm.getString("DeleteTitle"),
306                            javax.swing.JOptionPane.INFORMATION_MESSAGE);
307                    return;
308                }
309                int min = list.getMinSelectionIndex();
310                DefaultListModel<String> model = (DefaultListModel<String>) list.getModel();
311                while (index >= min) {
312                    String[] names = getTypeAndNames(name.get(index));
313                    model.remove(index);
314                    Conditional c = InstanceManager.getDefault(jmri.ConditionalManager.class).getBySystemName(names[2]);
315                    if (c != null) {
316                        Logix x = InstanceManager.getDefault(jmri.ConditionalManager.class).getParentLogix(names[2]);
317                        if (x != null) {
318                            x.deActivateLogix();
319                            x.deleteConditional(names[2]);
320                            x.activateLogix();
321                        }
322                        InstanceManager.getDefault(jmri.ConditionalManager.class).deregister(c);
323                        name.remove(index);
324                        index--;
325                    }
326                }
327                index++;
328                if (index >= model.getSize()) {
329                    index = model.getSize() - 1;
330                }
331                if (index >= 0) {
332                    list.setSelectedIndex(index);
333                }
334            }
335        }
336        JScrollPane scrollPane = new JScrollPane(list);
337        button.addActionListener(new EmptyListener(list, names));
338        button.setMaximumSize(button.getPreferredSize());
339        makeDialog(scrollPane, button, parent, rbm.getString("EmptyConditionalTitle"));
340    }
341
342    /**
343     * Find type of element and its names from a name that may be a user name or
344     * a system name.
345     * <p>
346     * Searches each Manager for a reference to the "name".
347     *
348     * @param name string (name base) to look for
349     * @return 4 element String array: {Type, userName, sysName, numListeners}  - 
350     * This should probably return an instance of a custom type rather than a bunch of string names
351     */
352    @Nonnull
353    static String[] getTypeAndNames(@Nonnull String name) {
354        log.debug("getTypeAndNames for \"{}\"", name);
355
356        String[] result;
357
358        result = checkForOneTypeAndNames(InstanceManager.getDefault(SensorManager.class), "Sensor", name);
359        if (result != null) return result;
360
361        result = checkForOneTypeAndNames(InstanceManager.getDefault(TurnoutManager.class), "Turnout", name);
362        if (result != null) return result;
363
364        result = checkForOneTypeAndNames(InstanceManager.getDefault(LightManager.class), "Light", name);
365        if (result != null) return result;
366
367        result = checkForOneTypeAndNames(InstanceManager.getDefault(SignalHeadManager.class), "SignalHead", name);
368        if (result != null) return result;
369
370        result = checkForOneTypeAndNames(InstanceManager.getDefault(ConditionalManager.class), "Conditional", name);
371        if (result != null) return result;
372
373        result = checkForOneTypeAndNames(InstanceManager.getDefault(BlockManager.class), "Block", name);
374        if (result != null) return result;
375
376        result = checkForOneTypeAndNames(InstanceManager.getDefault(SectionManager.class), "Section", name);  // old code has "Block" for type
377        if (result != null) return result;
378
379        result = checkForOneTypeAndNames(InstanceManager.getDefault(jmri.jmrit.logix.OBlockManager.class), "OBlock", name);
380        if (result != null) return result;
381
382
383        return new String[]{"", name, name, "0"};
384
385    }
386    // captive for above
387    @edu.umd.cs.findbugs.annotations.SuppressFBWarnings(value = "PZLA_PREFER_ZERO_LENGTH_ARRAYS",
388        justification = "null return for normal (no error) case is easy to check, and this is a really wierd array")
389    // This should probably return an instance of a custom type rather than a bunch of string names
390    static private String[] checkForOneTypeAndNames( @Nonnull Manager<? extends NamedBean> manager, @Nonnull String type, @Nonnull String beanName) {
391        NamedBean bean = manager.getBySystemName(beanName);
392        if (bean != null) return new String[]{type, bean.getUserName(), bean.getSystemName(), Integer.toString(bean.getNumPropertyChangeListeners())};
393
394        bean = manager.getByUserName(beanName);
395        if (bean != null) return new String[]{type, bean.getUserName(), bean.getSystemName(), Integer.toString(bean.getNumPropertyChangeListeners())};
396
397        return null;
398    }
399
400    /**
401     * Check if a given string is either a user or a system name.
402     *
403     * @param name the string to compare
404     * @param found whether the item has already been found somewhere
405     * @param names array containing system and user name as items 0 and 1
406     * @param line1 message line 1 to use if string is not matched
407     * @param line2 message line 2 to use if string is not matched
408     * @param line message line to use if string is matched
409     * @param tempText body of text to add to, a global variable
410     * @return false if name is null or cannot be matched to the names array
411     */
412    static boolean testName(String name, boolean found, String[] names, String line1, String line2,
413            String line, StringBuilder tempText) {
414        if (name == null) {
415            return false;
416        }
417        String sysName = names[2];
418        String userName = names[1];
419        if (name.equals(sysName) || name.equals(userName)) {
420            if (!found) {
421                if (line1 != null) {
422                    tempText.append(line1);
423                }
424                if (line2 != null) {
425                    tempText.append(line2);
426                }
427            }
428            tempText.append(line);
429            return true;
430        }
431        return false;
432    }
433
434    /**
435     * Search if a given string is used as the name of a NamedBean.
436     *
437     * @param name the string to look for
438     * @param text body of the message to be displayed reporting the result
439     * @return true if name is found at least once as a bean name
440     */
441    static boolean search(String name, JTextArea text) {
442        String[] names = getTypeAndNames(name);
443        if (log.isDebugEnabled()) {
444            log.debug("search for {} as {} \"{}\" ({})", name, names[0], names[1], names[2]);
445        }
446        if (names[0].length() == 0) {
447            if (text != null) {
448                text.append(MessageFormat.format(rbm.getString("ElementNotFound"), (Object[]) names));
449                return false;
450            }
451        }
452        if (text != null) {
453            text.append(MessageFormat.format(rbm.getString("ReferenceFollows"), (Object[]) names));
454        }
455        String sysName = names[2];
456        String userName = names[1];
457        int referenceCount = 0;
458        StringBuilder tempText;
459        boolean found = false;
460        boolean empty = true;
461        // search for references among each class known to be listeners
462        Iterator<String> iter1 = getSystemNameList(InstanceManager.getDefault(LogixManager.class)).iterator();
463        while (iter1.hasNext()) {
464            // get the next Logix
465            String sName = iter1.next();
466            Logix x = InstanceManager.getDefault(jmri.LogixManager.class).getBySystemName(sName);
467            if (x == null) {
468                log.error("Error getting Logix  - {}", sName);
469                break;
470            }
471            tempText = new StringBuilder();
472            String uName = x.getUserName();
473            String line1 = MessageFormat.format(rbm.getString("ReferenceTitle"),
474                    new Object[]{"", Bundle.getMessage("BeanNameLogix"), uName, sName});
475            for (int i = 0; i < x.getNumConditionals(); i++) {
476                sName = x.getConditionalByNumberOrder(i);
477                if (sName == null) {
478                    log.error("Null conditional system name");
479                    break;
480                }
481                Conditional c = InstanceManager.getDefault(jmri.ConditionalManager.class).getBySystemName(sName);
482                if (c == null) {
483                    log.error("Invalid conditional system name - {}", sName);
484                    break;
485                }
486                uName = c.getUserName();
487                String line2 = MessageFormat.format(rbm.getString("ReferenceTitle"),
488                        new Object[]{"\t", Bundle.getMessage("BeanNameConditional"), uName, sName});
489                String line = MessageFormat.format(rbm.getString("ConditionalReference"), "\t");
490                if (sysName.equals(sName) || (userName != null && userName.length() > 0 && userName.equals(uName))) {
491                    if (testName(sysName, found, names, line1, null, line, tempText)) {
492                        found = true;
493                        referenceCount++;
494                    }
495                }
496                List<ConditionalVariable> variableList = c.getCopyOfStateVariables();
497                for (int k = 0; k < variableList.size(); k++) {
498                    ConditionalVariable v = variableList.get(k);
499                    line = MessageFormat.format(rbm.getString("VariableReference"),
500                            new Object[]{"\t\t", v.getTestTypeString(), v.getDataString()});
501                    if (testName(v.getName(), found, names, line1, line2, line, tempText)) {
502                        found = true;
503                        referenceCount++;
504                    }
505                }
506                List<ConditionalAction> actionList = c.getCopyOfActions();
507                for (int k = 0; k < actionList.size(); k++) {
508                    ConditionalAction a = actionList.get(k);
509                    line = MessageFormat.format(rbm.getString("ActionReference"),
510                            new Object[]{"\t\t", a.getTypeString(), a.getOptionString(false), a.getActionDataString()});
511                    if (testName(a.getDeviceName(), found, names, line1, line2, line, tempText)) {
512                        found = true;
513                        referenceCount++;
514                    }
515                }
516                if (text != null && found) {
517                    text.append(tempText.toString());
518                    tempText = new StringBuilder();
519                    found = false;
520                    empty = false;
521                    line1 = null;
522                }
523            }
524            if (text != null && found) {
525                text.append(tempText.toString());
526                found = false;
527                empty = false;
528            }
529        }
530        if (text != null) {
531            if (empty) {
532                text.append("\t" + MessageFormat.format(rbm.getString("NoReference"), "Logix"));
533                // cannot put escaped tab char at start of getString
534            } else {
535                text.append("\n");
536            }
537        }
538
539        tempText = new StringBuilder();
540        found = false;
541        empty = true;
542        jmri.jmrit.logix.OBlockManager oBlockManager = InstanceManager.getDefault(jmri.jmrit.logix.OBlockManager.class);
543        iter1 = getSystemNameList(oBlockManager).iterator();
544        while (iter1.hasNext()) {
545            // get the next Logix
546            String sName = iter1.next();
547            jmri.jmrit.logix.OBlock block = oBlockManager.getBySystemName(sName);
548            if (block==null){
549                continue;
550            }
551            String uName = block.getUserName();
552            String line1 = MessageFormat.format(rbm.getString("ReferenceTitle"),
553                    new Object[]{" ", Bundle.getMessage("BeanNameOBlock"), uName, sName});
554            Sensor sensor = block.getSensor();
555            if (sensor != null) {
556                String line = MessageFormat.format(rbm.getString("OBlockSensor"), "\t");
557                if (testName(sensor.getSystemName(), found, names, line1, null, line, tempText)) {
558                    found = true;
559                    referenceCount++;
560                }
561            }
562            if (text != null && found) {
563                text.append(tempText.toString());
564                tempText = new StringBuilder();
565                found = false;
566                empty = false;
567            }
568        }
569        if (text != null) {
570            if (empty) {
571                text.append(MessageFormat.format(rbm.getString("NoReference"), "OBlock"));
572            } else {
573                text.append("\n");
574            }
575        }
576
577        tempText = new StringBuilder();
578        found = false;
579        empty = true;
580        jmri.RouteManager routeManager = InstanceManager.getDefault(jmri.RouteManager.class);
581        iter1 = getSystemNameList(routeManager).iterator();
582        while (iter1.hasNext()) {
583            // get the next Logix
584            String sName = iter1.next();
585            jmri.Route r = routeManager.getBySystemName(sName);
586            if (r == null) {
587                log.error("Error getting Route  - {}", sName);
588                break;
589            }
590            String uName = r.getUserName();
591            String line1 = MessageFormat.format(rbm.getString("ReferenceTitle"),
592                    new Object[]{" ", Bundle.getMessage("BeanNameRoute"), uName, sName});
593            for (int i = 0; i < jmri.Route.MAX_CONTROL_SENSORS; i++) {
594                String line = "\t" + MessageFormat.format(rbm.getString("ControlReference"), Bundle.getMessage("BeanNameSensor"));
595                if (testName(r.getRouteSensorName(i), found, names, line1, null, line, tempText)) {
596                    found = true;
597                    referenceCount++;
598                }
599            }
600            String line = MessageFormat.format("TurnoutsAlignedSensor", Bundle.getMessage("BeanNameSensor"));
601            if (testName(r.getTurnoutsAlignedSensor(), found, names, line1, null, line, tempText)) {
602                found = true;
603                referenceCount++;
604            }
605            line = "\t" + MessageFormat.format(rbm.getString("ControlReference"), Bundle.getMessage("BeanNameTurnout"));
606            if (testName(r.getControlTurnout(), found, names, line1, null, line, tempText)) {
607                found = true;
608                referenceCount++;
609            }
610            line = MessageFormat.format("LockControlTurnout", Bundle.getMessage("BeanNameTurnout"));
611            if (testName(r.getLockControlTurnout(), found, names, line1, null, line, tempText)) {
612                found = true;
613                referenceCount++;
614            }
615            for (int i = 0; i < r.getNumOutputTurnouts(); i++) {
616                line = "\t" + MessageFormat.format(rbm.getString("OutputReference"), Bundle.getMessage("BeanNameTurnout"));
617                if (testName(r.getOutputTurnoutByIndex(i), found, names, line1, null, line, tempText)) {
618                    found = true;
619                    referenceCount++;
620                }
621            }
622            for (int i = 0; i < r.getNumOutputSensors(); i++) {
623                line = "\t" +  MessageFormat.format(rbm.getString("OutputReference"), Bundle.getMessage("BeanNameSensor"));
624                if (testName(r.getOutputSensorByIndex(i), found, names, line1, null, line, tempText)) {
625                    found = true;
626                    referenceCount++;
627                }
628            }
629            if (text != null && found) {
630                text.append(tempText.toString());
631                tempText = new StringBuilder();
632                found = false;
633                empty = false;
634            }
635        }
636        if (text != null) {
637            if (empty) {
638                text.append(MessageFormat.format(rbm.getString("NoReference"), "Route"));
639            } else {
640                text.append("\n");
641            }
642        }
643
644        tempText = new StringBuilder();
645        found = false;
646        empty = true;
647        jmri.TransitManager transitManager = InstanceManager.getDefault(jmri.TransitManager.class);
648        iter1 = getSystemNameList(transitManager).iterator();
649        while (iter1.hasNext()) {
650            // get the next Logix
651            String sName = iter1.next();
652            jmri.Transit transit = transitManager.getBySystemName(sName);
653            if (transit == null) {
654                log.error("Error getting Transit - {}", sName);
655                break;
656            }
657            String uName = transit.getUserName();
658            String line1 = MessageFormat.format(rbm.getString("ReferenceTitle"),
659                    new Object[]{" ", Bundle.getMessage("BeanNameTransit"), uName, sName});
660            List<jmri.TransitSection> sectionList = transit.getTransitSectionList();
661            for (int i = 0; i < sectionList.size(); i++) {
662                jmri.TransitSection transitSection = sectionList.get(i);
663                jmri.Section section = transitSection.getSection();
664                uName = section.getUserName();
665                sName = section.getSystemName();
666                String line2 = MessageFormat.format(rbm.getString("ReferenceTitle"),
667                        new Object[]{"\t", rbm.getString("TransitSection"), uName, sName});
668                if (sName.equals(sysName) || uName.equals(userName)) {
669                    tempText.append(line1);
670                    tempText.append(line2);
671                    tempText.append(MessageFormat.format(rbm.getString("SectionReference"), "\t\t"));
672                    found = true;
673                    referenceCount++;
674                }
675                String line = MessageFormat.format(rbm.getString("ForwardBlocking"), "\t\t");
676                if (testName(section.getForwardBlockingSensorName(), found, names, line1, line2, line, tempText)) {
677                    found = true;
678                    referenceCount++;
679                }
680                line = MessageFormat.format(rbm.getString("ForwardStopping"), "\t\t");
681                if (testName(section.getForwardStoppingSensorName(), found, names, line1, line2, line, tempText)) {
682                    found = true;
683                    referenceCount++;
684                }
685                line = MessageFormat.format(rbm.getString("ReverseBlocking"), "\t\t");
686                if (testName(section.getReverseBlockingSensorName(), found, names, line1, line2, line, tempText)) {
687                    found = true;
688                    referenceCount++;
689                }
690                line = MessageFormat.format(rbm.getString("ReverseStopping"), "\t\t");
691                if (testName(section.getReverseStoppingSensorName(), found, names, line1, line2, line, tempText)) {
692                    found = true;
693                    referenceCount++;
694                }
695                List<jmri.Block> blockList = section.getBlockList();
696
697                for (int k = 0; k < blockList.size(); k++) {
698                    jmri.Block block = blockList.get(k);
699                    sName = block.getSystemName();
700                    uName = block.getUserName();
701                    tempText.append(MessageFormat.format(rbm.getString("ReferenceTitle"),
702                            new Object[]{"\t\t", Bundle.getMessage("BeanNameBlock"), uName, sName}));
703                    if (sName.equals(sysName) || uName.equals(userName)) {
704                        tempText.append(MessageFormat.format(rbm.getString("BlockReference"), "\t\t"));
705                        found = true;
706                        referenceCount++;
707                    }
708                    Sensor sensor = block.getSensor();
709                    if (sensor != null) {
710                        line = MessageFormat.format(rbm.getString("BlockSensor"), "\t\t");
711                        if (testName(sensor.getSystemName(), found, names, line1, line2, line, tempText)) {
712                            found = true;
713                            referenceCount++;
714                        }
715                    }
716                }
717                if (text != null && found) {
718                    text.append(tempText.toString());
719                    tempText = new StringBuilder();
720                    found = false;
721                    empty = false;
722                    line1 = null;
723                }
724            }
725            if (text != null && found) {
726                text.append(tempText.toString());
727                tempText = new StringBuilder();
728                found = false;
729                empty = false;
730            }
731        }
732        if (text != null) {
733            if (empty) {
734                text.append(MessageFormat.format(rbm.getString("NoReference"), "Transit"));
735            } else {
736                text.append("\n");
737            }
738        }
739
740        // if (text != null) {
741        //   text.append(rbm.getString("NestMessage"));
742        // }
743        tempText = new StringBuilder();
744        found = false;
745        empty = true;
746        jmri.SectionManager sectionManager = InstanceManager.getDefault(jmri.SectionManager.class);
747        java.util.List<String> sysNameList = new java.util.ArrayList<>(getSystemNameList(sectionManager));
748
749        transitManager = InstanceManager.getDefault(jmri.TransitManager.class);
750        iter1 = getSystemNameList(transitManager).iterator();
751        while (iter1.hasNext()) {
752            // get the next Logix
753            String sName = iter1.next();
754            jmri.Transit transit = transitManager.getBySystemName(sName);
755            if (transit != null) {
756                List<jmri.TransitSection> sectionList = transit.getTransitSectionList();
757                for (int i = 0; i < sectionList.size(); i++) {
758                    jmri.TransitSection transitSection = sectionList.get(i);
759                    jmri.Section section = transitSection.getSection();
760                    sysNameList.remove(section.getSystemName());
761                }
762            }
763        }
764        iter1 = sysNameList.iterator();
765        while (iter1.hasNext()) {
766            // get the next Logix
767            String sName = iter1.next();
768            jmri.Section section = sectionManager.getBySystemName(sName);
769            if (section == null) {
770                log.error("Error getting Section - {}", sName);
771                break;
772            }
773            String uName = section.getUserName();
774            String line1 = MessageFormat.format(rbm.getString("ReferenceTitle"),
775                    new Object[]{" ", Bundle.getMessage("BeanNameSection"), uName, sName});
776            if (sName.equals(sysName) || uName.equals(userName)) {
777                tempText.append(MessageFormat.format(rbm.getString("SectionReference"), "\t"));
778
779                found = true;
780                referenceCount++;
781            }
782            String line = MessageFormat.format(rbm.getString("ForwardBlocking"), "\t");
783            if (testName(section.getForwardBlockingSensorName(), found, names, line1, null, line, tempText)) {
784                found = true;
785                referenceCount++;
786            }
787            line = MessageFormat.format(rbm.getString("ForwardStopping"), "\t");
788            if (testName(section.getForwardStoppingSensorName(), found, names, line1, null, line, tempText)) {
789                found = true;
790                referenceCount++;
791            }
792            line = MessageFormat.format(rbm.getString("ReverseBlocking"), "\t");
793            if (testName(section.getReverseBlockingSensorName(), found, names, line1, null, line, tempText)) {
794                found = true;
795                referenceCount++;
796            }
797            line = MessageFormat.format(rbm.getString("ReverseStopping"), "\t");
798            if (testName(section.getReverseStoppingSensorName(), found, names, line1, null, line, tempText)) {
799                found = true;
800                referenceCount++;
801            }
802
803            List<jmri.Block> blockList = section.getBlockList();
804            for (int k = 0; k < blockList.size(); k++) {
805                jmri.Block block = blockList.get(k);
806                sName = block.getSystemName();
807                uName = block.getUserName();
808                String line2 = MessageFormat.format(rbm.getString("ReferenceTitle"),
809                        new Object[]{"\t", Bundle.getMessage("BeanNameBlock"), uName, sName});
810                if (sName.equals(sysName) || (uName != null && uName.equals(userName))) {
811                    tempText.append(line2);
812                    tempText.append(MessageFormat.format(rbm.getString("BlockReference"), "\t"));
813                    found = true;
814                    referenceCount++;
815                }
816                Sensor sensor = block.getSensor();
817                if (sensor != null) {
818                    line = MessageFormat.format(rbm.getString("BlockSensor"), "\t\t");
819                    if (testName(sensor.getSystemName(), found, names, line1, line2, line, tempText)) {
820                        found = true;
821                        referenceCount++;
822                    }
823                }
824            }
825            if (text != null && found) {
826                text.append(tempText.toString());
827                tempText = new StringBuilder();
828                found = false;
829                empty = false;
830            }
831        }
832        if (text != null) {
833            if (empty) {
834                text.append(MessageFormat.format(rbm.getString("NoReference"), "Section"));
835            } else {
836                text.append("\n");
837            }
838        }
839
840        tempText = new StringBuilder();
841        found = false;
842        empty = true;
843        jmri.BlockManager blockManager = InstanceManager.getDefault(jmri.BlockManager.class);
844        sysNameList = new java.util.ArrayList<>(getSystemNameList(blockManager));
845
846        sectionManager = InstanceManager.getDefault(jmri.SectionManager.class);
847        iter1 = getSystemNameList(sectionManager).iterator();
848        while (iter1.hasNext()) {
849            String sName = iter1.next();
850            jmri.Section section = sectionManager.getBySystemName(sName);
851            if (section != null) {
852                for (Block block : section.getBlockList()) {
853                    sysNameList.remove(block.getSystemName());
854                }
855            }
856        }
857        iter1 = sysNameList.iterator();
858        while (iter1.hasNext()) {
859            // get the next Logix
860            String sName = iter1.next();
861            jmri.Block b = blockManager.getBySystemName(sName);
862            if (b == null) {
863                continue;
864            }
865            String uName = b.getUserName();
866            String line1 = MessageFormat.format(rbm.getString("ReferenceTitle"),
867                    new Object[]{" ", Bundle.getMessage("BeanNameBlock"), uName, sName});
868            if (sName.equals(sysName) || (uName != null && uName.equals(userName))) {
869                tempText.append(line1);
870                tempText.append(MessageFormat.format(rbm.getString("BlockReference"), "\t"));
871                found = true;
872                referenceCount++;
873            }
874            jmri.Sensor s = b.getSensor();
875            if (s != null) {
876                String line = MessageFormat.format(rbm.getString("BlockSensor"), "\t\t");
877                if (testName(s.getSystemName(), found, names, line1, null, line, tempText)) {
878                    found = true;
879                    referenceCount++;
880                }
881            }
882            if (text != null && found) {
883                text.append(tempText.toString());
884                tempText = new StringBuilder();
885                found = false;
886                empty = false;
887            }
888        }
889        if (text != null) {
890            if (empty) {
891                text.append(MessageFormat.format(rbm.getString("NoReference"), "Block"));
892            } else {
893                text.append("\n");
894            }
895        }
896
897        tempText = new StringBuilder();
898        found = false;
899        empty = true;
900        jmri.jmrit.display.layoutEditor.LayoutBlockManager lbm = InstanceManager.getDefault(LayoutBlockManager.class);
901        iter1 = getSystemNameList(lbm).iterator();
902        while (iter1.hasNext()) {
903            // get the next Logix
904            String sName = iter1.next();
905            jmri.jmrit.display.layoutEditor.LayoutBlock lb = lbm.getBySystemName(sName);
906            if (lb == null) {
907                log.error("Error getting LayoutBlock - {}", sName);
908                break;
909            }
910            String uName = lb.getUserName();
911            String line1 = MessageFormat.format(rbm.getString("ReferenceTitle"),
912                    new Object[]{" ", rbm.getString("LayoutBlock"), uName, sName});
913            jmri.Sensor s = lb.getOccupancySensor();
914            if (s != null) {
915                String line = MessageFormat.format(rbm.getString("OccupancySensor"), "\t\t");
916                if (testName(s.getSystemName(), found, names, line1, null, line, tempText)) {
917                    found = true;
918                    referenceCount++;
919                }
920            }
921            if (text != null && found) {
922                text.append(tempText.toString());
923                tempText = new StringBuilder();
924                found = false;
925                empty = false;
926            }
927        }
928        if (text != null) {
929            if (empty) {
930                text.append(MessageFormat.format(rbm.getString("NoReference"), "LayoutBlock"));
931            } else {
932                text.append("\n");
933            }
934        }
935
936        tempText = new StringBuilder();
937        found = false;
938        empty = true;
939        Enumeration<BlockBossLogic> enumeration = Collections.enumeration(
940            InstanceManager.getDefault(jmri.jmrit.blockboss.BlockBossLogicProvider.class).provideAll());
941        while (enumeration.hasMoreElements()) {
942            // get the next Logix
943            BlockBossLogic bbl = enumeration.nextElement();
944            String sName = bbl.getName();
945            String uName = bbl.getDrivenSignal();
946            String line1 = MessageFormat.format(rbm.getString("ReferenceTitle"),
947                    new Object[]{" ", rbm.getString("BlockBossLogic"), uName, sName});
948            if (uName.equals(sysName) || uName.equals(userName) || sName.equals(sysName) || sName.equals(userName)) {
949                tempText.append(line1);
950                tempText.append(MessageFormat.format(rbm.getString("SignalReference"), "\t"));
951                found = true;
952                referenceCount++;
953            }
954            String line = MessageFormat.format(rbm.getString("WatchSensorReference"), "1\t");
955            if (testName(bbl.getSensor1(), found, names, line1, null, line, tempText)) {
956                found = true;
957                referenceCount++;
958            }
959            line = MessageFormat.format(rbm.getString("WatchSensorReference"), "2\t");
960            if (testName(bbl.getSensor2(), found, names, line1, null, line, tempText)) {
961                found = true;
962                referenceCount++;
963            }
964            line = MessageFormat.format(rbm.getString("WatchSensorReference"), "3\t");
965            if (testName(bbl.getSensor3(), found, names, line1, null, line, tempText)) {
966                found = true;
967                referenceCount++;
968            }
969            line = MessageFormat.format(rbm.getString("WatchSensorReference"), "4\t");
970            if (testName(bbl.getSensor4(), found, names, line1, null, line, tempText)) {
971                found = true;
972                referenceCount++;
973            }
974            line = MessageFormat.format(rbm.getString("WatchSensorReference"), "5\t");
975            if (testName(bbl.getSensor5(), found, names, line1, null, line, tempText)) {
976                found = true;
977                referenceCount++;
978            }
979            line = MessageFormat.format(rbm.getString("WatchTurnoutReference"), "\t");
980            if (testName(bbl.getTurnout(), found, names, line1, null, line, tempText)) {
981                found = true;
982                referenceCount++;
983            }
984            line = MessageFormat.format(rbm.getString("WatchSignalReference"), "1\t");
985            if (testName(bbl.getWatchedSignal1(), found, names, line1, null, line, tempText)) {
986                found = true;
987                referenceCount++;
988            }
989            line = MessageFormat.format(rbm.getString("WatchTurnoutReference"), "1Alt\t");
990            if (testName(bbl.getWatchedSignal1Alt(), found, names, line1, null, line, tempText)) {
991                found = true;
992                referenceCount++;
993            }
994            line = MessageFormat.format(rbm.getString("WatchTurnoutReference"), "2\t");
995            if (testName(bbl.getWatchedSignal2(), found, names, line1, null, line, tempText)) {
996                found = true;
997                referenceCount++;
998            }
999            line = MessageFormat.format(rbm.getString("WatchTurnoutReference"), "2Alt\t");
1000            if (testName(bbl.getWatchedSignal2Alt(), found, names, line1, null, line, tempText)) {
1001                found = true;
1002                referenceCount++;
1003            }
1004            line = MessageFormat.format(rbm.getString("WatchSensorReference"), "1\t");
1005            if (testName(bbl.getWatchedSensor1(), found, names, line1, null, line, tempText)) {
1006                found = true;
1007                referenceCount++;
1008            }
1009            line = MessageFormat.format(rbm.getString("WatchSensorReference"), "1Alt\t");
1010            if (testName(bbl.getWatchedSensor1Alt(), found, names, line1, null, line, tempText)) {
1011                found = true;
1012                referenceCount++;
1013            }
1014            line = MessageFormat.format(rbm.getString("WatchSensorReference"), "2\t");
1015            if (testName(bbl.getWatchedSensor2(), found, names, line1, null, line, tempText)) {
1016                found = true;
1017                referenceCount++;
1018            }
1019            line = MessageFormat.format(rbm.getString("WatchSensorReference"), "2Alt\t");
1020            if (testName(bbl.getWatchedSensor2Alt(), found, names, line1, null, line, tempText)) {
1021                found = true;
1022                referenceCount++;
1023            }
1024            if (text != null && found) {
1025                text.append(tempText.toString());
1026                tempText = new StringBuilder();
1027                found = false;
1028                empty = false;
1029            }
1030        }
1031        if (text != null) {
1032            if (empty) {
1033                text.append(MessageFormat.format(rbm.getString("NoReference"), "BlockBossLogic"));
1034            } else {
1035                text.append("\n");
1036            }
1037        }
1038
1039        tempText = new StringBuilder();
1040        found = false;
1041        empty = true;
1042        jmri.ConditionalManager conditionalManager = InstanceManager.getDefault(jmri.ConditionalManager.class);
1043        sysNameList = new ArrayList<>(getSystemNameList(conditionalManager));
1044
1045        iter1 = getSystemNameList(InstanceManager.getDefault(LogixManager.class)).iterator();
1046        while (iter1.hasNext()) {
1047            String sName = iter1.next();
1048            Logix x = InstanceManager.getDefault(jmri.LogixManager.class).getBySystemName(sName);
1049            if (x == null){
1050                continue;
1051            }
1052            for (int i = 0; i < x.getNumConditionals(); i++) {
1053                sName = x.getConditionalByNumberOrder(i);
1054                sysNameList.remove(sName);
1055            }
1056        }
1057        iter1 = sysNameList.iterator();
1058        while (iter1.hasNext()) {
1059            // get the next Logix
1060            String sName = iter1.next();
1061            jmri.Conditional c = conditionalManager.getBySystemName(sName);
1062            if (c == null) {
1063                log.error("Error getting Condition - {}", sName);
1064                break;
1065            }
1066            String uName = c.getUserName();
1067            String line1 = MessageFormat.format(rbm.getString("ReferenceTitle"),
1068                    new Object[]{" ", Bundle.getMessage("BeanNameConditional"), uName, sName});
1069            if (sName.equals(sysName) || uName.equals(userName)) {
1070                tempText.append(line1);
1071                tempText.append(MessageFormat.format(rbm.getString("ConditionalReference"), "\t"));
1072                found = true;
1073                //referenceCount++; Don't count, this conditional is orphaned by logix(es)
1074            }
1075            List<ConditionalVariable> variableList = c.getCopyOfStateVariables();
1076            for (int k = 0; k < variableList.size(); k++) {
1077                ConditionalVariable v = variableList.get(k);
1078                String line = MessageFormat.format(rbm.getString("VariableReference"),
1079                        new Object[]{"\t\t", v.getTestTypeString(), v.getDataString()});
1080                if (testName(v.getName(), found, names, line1, null, line, tempText)) {
1081                    found = true;
1082                    //referenceCount++; Don't count, this conditional is orphaned by logix(es)
1083                }
1084            }
1085            List<ConditionalAction> actionList = c.getCopyOfActions();
1086            for (int k = 0; k < actionList.size(); k++) {
1087                ConditionalAction a = actionList.get(k);
1088                String line = MessageFormat.format(rbm.getString("ActionReference"),
1089                        new Object[]{"\t\t", a.getTypeString(), a.getOptionString(false), a.getActionDataString()});
1090                if (testName(a.getDeviceName(), found, names, line1, null, line, tempText)) {
1091                    found = true;
1092                    //referenceCount++; Don't count, this conditional is orphaned by logix(es)
1093                }
1094            }
1095            if (text != null && found) {
1096                text.append(tempText.toString());
1097                tempText = new StringBuilder();
1098                found = false;
1099                empty = false;
1100                line1 = null;
1101            }
1102        }
1103        if (text != null) {
1104            if (empty) {
1105                text.append(MessageFormat.format(rbm.getString("NoReference"), "Conditional"));
1106            }
1107            text.append("\n");
1108        }
1109
1110        found = false;
1111        empty = true;
1112        Set<Editor> panelList = InstanceManager.getDefault(EditorManager.class).getAll();
1113        for (Editor panelEditor : panelList) {
1114            name = panelEditor.getTitle();
1115            String line1 = MessageFormat.format(rbm.getString("ReferenceTitle"),
1116                    new Object[]{" ", rbm.getString("Panel"), name, name});
1117            List<Positionable> contents = panelEditor.getContents();
1118            for (int k = 0; k < contents.size(); k++) {
1119                Positionable o = contents.get(k);
1120                if (o.getClass().getName().equals("jmri.jmrit.display.SensorIcon")) {
1121                    name = ((jmri.jmrit.display.SensorIcon) o).getSensor().getSystemName();
1122                    String line = MessageFormat.format(rbm.getString("PanelReference"),
1123                            new Object[]{"\t", Bundle.getMessage("BeanNameSensor")});
1124                    if (testName(name, found, names, line1, null, line, tempText)) {
1125                        found = true;
1126                        referenceCount++;
1127                    }
1128                } else if (o.getClass().getName().equals("jmri.jmrit.display.TurnoutIcon")) {
1129                    name = ((jmri.jmrit.display.TurnoutIcon) o).getTurnout().getSystemName();
1130                    String line = MessageFormat.format(rbm.getString("PanelReference"),
1131                            new Object[]{"\t", Bundle.getMessage("BeanNameTurnout")});
1132                    if (testName(name, found, names, line1, null, line, tempText)) {
1133                        found = true;
1134                        referenceCount++;
1135                    }
1136                } else if (o.getClass().getName().equals("jmri.jmrit.display.SignalHeadIcon")) {
1137                    name = ((jmri.jmrit.display.SignalHeadIcon) o).getSignalHead().getSystemName();
1138                    String line = MessageFormat.format(rbm.getString("PanelReference"),
1139                            new Object[]{"\t", Bundle.getMessage("BeanNameSignalHead")});
1140                    if (testName(name, found, names, line1, null, line, tempText)) {
1141                        found = true;
1142                        referenceCount++;
1143                    }
1144                } else if (o.getClass().getName().equals("jmri.jmrit.display.MultiSensorIcon")) {
1145                    jmri.jmrit.display.MultiSensorIcon msi = (jmri.jmrit.display.MultiSensorIcon) o;
1146                    for (int j = 0; j < msi.getNumEntries(); j++) {
1147                        name = msi.getSensorName(j);
1148                        String line = MessageFormat.format(rbm.getString("PanelReference"),
1149                                new Object[]{"\t", Bundle.getMessage("MultiSensor")});
1150                        if (testName(name, found, names, line1, null, line, tempText)) {
1151                            found = true;
1152                            referenceCount++;
1153                        }
1154                    }
1155                } else if (o.getClass().getName().equals("jmri.jmrit.display.IndicatorTurnoutIcon")) {
1156                    jmri.jmrit.display.IndicatorTurnoutIcon ito = (jmri.jmrit.display.IndicatorTurnoutIcon) o;
1157                    name = ito.getTurnout().getSystemName();
1158                    String line = MessageFormat.format(rbm.getString("PanelReference"),
1159                            new Object[]{"\t", Bundle.getMessage("IndicatorTO")});
1160                    if (testName(name, found, names, line1, null, line, tempText)) {
1161                        found = true;
1162                        referenceCount++;
1163                    }
1164                    Sensor sensor = ito.getOccSensor();
1165                    if (sensor != null) {
1166                        name = sensor.getSystemName();
1167                        line = MessageFormat.format(rbm.getString("PanelReference"),
1168                                new Object[]{"\t", Bundle.getMessage("IndicatorTO")});
1169                        if (testName(name, found, names, line1, null, line, tempText)) {
1170                            found = true;
1171                            referenceCount++;
1172                        }
1173                    }
1174                    jmri.jmrit.logix.OBlock block = ito.getOccBlock();
1175                    if (block != null) {
1176                        sensor = block.getSensor();
1177                        if (sensor != null) {
1178                            name = sensor.getSystemName();
1179                            line = MessageFormat.format(rbm.getString("PanelReference"),
1180                                    new Object[]{"\t", Bundle.getMessage("IndicatorTO")});
1181                            if (testName(name, found, names, line1, null, line, tempText)) {
1182                                found = true;
1183                                referenceCount++;
1184                            }
1185                        }
1186                    }
1187                } else if (o.getClass().getName().equals("jmri.jmrit.display.IndicatorTrackIcon")) {
1188                    jmri.jmrit.display.IndicatorTrackIcon track = (jmri.jmrit.display.IndicatorTrackIcon) o;
1189                    Sensor sensor = track.getOccSensor();
1190                    if (sensor != null) {
1191                        name = sensor.getSystemName();
1192                        String line = MessageFormat.format(rbm.getString("PanelReference"),
1193                                new Object[]{"\t", Bundle.getMessage("IndicatorTrack")});
1194                        if (testName(name, found, names, line1, null, line, tempText)) {
1195                            found = true;
1196                            referenceCount++;
1197                        }
1198                    }
1199                    jmri.jmrit.logix.OBlock block = track.getOccBlock();
1200                    if (block != null) {
1201                        sensor = block.getSensor();
1202                        if (sensor != null) {
1203                            name = sensor.getSystemName();
1204                            String line = MessageFormat.format(rbm.getString("PanelReference"),
1205                                    new Object[]{"\t", Bundle.getMessage("IndicatorTrack")});
1206                            if (testName(name, found, names, line1, null, line, tempText)) {
1207                                found = true;
1208                                referenceCount++;
1209                            }
1210                        }
1211                    }
1212                }
1213                if (text != null && found) {
1214                    text.append(tempText.toString());
1215                    tempText = new StringBuilder();
1216                    found = false;
1217                    empty = false;
1218                    line1 = null;
1219                }
1220            }
1221            if (text != null) {
1222                if (empty) {
1223                    text.append(MessageFormat.format(rbm.getString("NoReference"), "Panel"));
1224                }
1225            }
1226        }
1227
1228        if (text != null) {
1229            if (referenceCount == 0) {
1230                text.append(MessageFormat.format(rbm.getString("Orphan"), (Object[]) names));
1231            } else {
1232                text.append(MessageFormat.format(rbm.getString("ReferenceFound"),
1233                        new Object[]{referenceCount, userName, sysName}));
1234            }
1235        }
1236        if (names[0] != null) {
1237            // The manager is always a listener
1238            int numListeners = Integer.parseInt(names[3]) - 1;
1239            // PickLists are also listeners
1240            numListeners = numListeners - jmri.jmrit.picker.PickListModel.getNumInstances(names[0]);
1241            if (names[0].equals("Sensor")) {
1242                numListeners = numListeners - jmri.jmrit.picker.PickListModel.getNumInstances("MultiSensor"); // NOI18N
1243            }
1244
1245            if (numListeners > referenceCount) {
1246                if (names[0].length() == 0) {
1247                    names[0] = "Unknown Type?";
1248                }
1249                /*
1250                 JOptionPane.showMessageDialog(null,
1251                 MessageFormat.format(rbm.getString("OrphanName"), (Object[])names)+" has "+numListeners+
1252                 " listeners installed and only "+referenceCount+
1253                 " references found.\n"+names[0]+
1254                 " Tables are listeneners.  Check that the table is closed.",
1255                 rbm.getString("infoTitle"), JOptionPane.INFORMATION_MESSAGE);
1256                 */
1257                if (text != null) {
1258                    text.append(MessageFormat.format(rbm.getString("OrphanName"), (Object[]) names) + " has " + numListeners
1259                            + " listeners installed and only " + referenceCount
1260                            + " references found.\n" + names[0]
1261                            + " Tables are listeneners.  Check that the table is closed.");
1262                }
1263            }
1264        }
1265        return (referenceCount > 0);
1266    }
1267
1268    /**
1269     * Build and display a dialog box with an OK button and optional 2nd button.
1270     *
1271     * @param component Body of message to put in dialog box
1272     * @param button optional second button to add to pane
1273     * @param parent Frame that asked for this dialog
1274     * @param title text do use as title of the dialog box
1275     */
1276    static void makeDialog(Component component, Component button, Frame parent, String title) {
1277        JDialog dialog = new JDialog(parent, title, true);
1278        JButton ok = new JButton(Bundle.getMessage("ButtonOK"));
1279        class myListener implements ActionListener {
1280
1281            java.awt.Window _w;
1282
1283            myListener(java.awt.Window w) {
1284                _w = w;
1285            }
1286
1287            @Override
1288            public void actionPerformed(ActionEvent e) {
1289                // dispose on the GUI thread _later_
1290                jmri.util.ThreadingUtil.runOnGUIEventually( ()->{ 
1291                    _w.dispose();
1292                });
1293            }
1294        }
1295        ok.addActionListener(new myListener(dialog));
1296        ok.setMaximumSize(ok.getPreferredSize());
1297
1298        java.awt.Container contentPane = dialog.getContentPane();
1299        contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.Y_AXIS));
1300        contentPane.add(component, BorderLayout.CENTER);
1301        contentPane.add(Box.createVerticalStrut(5));
1302        contentPane.add(Box.createVerticalGlue());
1303        JPanel panel = new JPanel();
1304        panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
1305        panel.add(ok);
1306        if (button != null) {
1307            panel.add(Box.createHorizontalStrut(5));
1308            panel.add(button);
1309        }
1310        contentPane.add(panel, BorderLayout.SOUTH);
1311        dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
1312        dialog.setLocationRelativeTo(parent);
1313        dialog.pack();
1314        // dispose on the GUI thread _later_
1315        jmri.util.ThreadingUtil.runOnGUIEventually( ()->{ 
1316            dialog.setVisible(true);
1317        });
1318    }
1319
1320    private final static Logger log = LoggerFactory.getLogger(Maintenance.class);
1321}