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