private String getVirtualAccessibleNameFromContext()

in src/jdk.accessibility/windows/classes/com/sun/java/accessibility/internal/AccessBridge.java [699:1400]


    private String getVirtualAccessibleNameFromContext(final AccessibleContext ac) {
        if (null != ac) {
            /*
            Step 1:
            =======
            Determine if we can obtain the Virtual Accessible Name from the
            Accessible Name or Accessible Description of the object.
            */
            String nameString = InvocationUtils.invokeAndWait(new Callable<String>() {
                @Override
                public String call() throws Exception {
                    return ac.getAccessibleName();
                }
            }, ac);
            if ( ( null != nameString ) && ( 0 != nameString.length () ) ) {
                debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained from AccessibleContext::getAccessibleName.");
                references.increment (nameString);
                return nameString;
            }
            String descriptionString = InvocationUtils.invokeAndWait(new Callable<String>() {
                @Override
                public String call() throws Exception {
                    return ac.getAccessibleDescription();
                }
            }, ac);
            if ( ( null != descriptionString ) && ( 0 != descriptionString.length () ) ) {
                debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained from AccessibleContext::getAccessibleDescription.");
                references.increment (descriptionString);
                return descriptionString;
            }

            debugString ("[WARN]: The Virtual Accessible Name was not found using AccessibleContext::getAccessibleDescription. or getAccessibleName");
            /*
            Step 2:
            =======
            Decide whether the extended name search algorithm should be
            used for this object.
            */
            boolean bExtendedSearch = false;
            AccessibleRole role = InvocationUtils.invokeAndWait(new Callable<AccessibleRole>() {
                @Override
                public AccessibleRole call() throws Exception {
                    return ac.getAccessibleRole();
                }
            }, ac);
            AccessibleContext parentContext = null;
            AccessibleRole parentRole = AccessibleRole.UNKNOWN;

            if ( extendedVirtualNameSearchRoles.contains (role) ) {
                parentContext = getAccessibleParentFromContext (ac);
                if ( null != parentContext ) {
                    final AccessibleContext parentContextInnerTemp = parentContext;
                    parentRole = InvocationUtils.invokeAndWait(new Callable<AccessibleRole>() {
                        @Override
                        public AccessibleRole call() throws Exception {
                            return parentContextInnerTemp.getAccessibleRole();
                        }
                    }, ac);
                    if ( AccessibleRole.UNKNOWN != parentRole ) {
                        bExtendedSearch = true;
                        if ( noExtendedVirtualNameSearchParentRoles.contains (parentRole) ) {
                            bExtendedSearch = false;
                        }
                    }
                }
            }

            if (false == bExtendedSearch) {
                debugString ("[INFO]: bk -- getVirtualAccessibleNameFromContext will not use the extended name search algorithm.  role = " + ( role != null ? role.toDisplayString(Locale.US) : "null") );
                /*
                Step 3:
                =======
                We have determined that we should not use the extended name
                search algorithm for this object (we must obtain the name of
                the object from the object itself and not from neighboring
                objects).  However the object name cannot be obtained from
                the Accessible Name or Accessible Description of the object.

                Handle several special cases here that might yield a value for
                the Virtual Accessible Name.  Return null if the object does
                not match the criteria for any of these special cases.
                */
                if (AccessibleRole.LABEL == role) {
                    /*
                    Does the label support the Accessible Text Interface?
                    */
                    final AccessibleText at = InvocationUtils.invokeAndWait(new Callable<AccessibleText>() {
                        @Override
                        public AccessibleText call() throws Exception {
                            return ac.getAccessibleText();
                        }
                    }, ac);
                    if (null != at) {
                        int charCount = InvocationUtils.invokeAndWait(new Callable<Integer>() {
                            @Override
                            public Integer call() throws Exception {
                                return at.getCharCount();
                            }
                        }, ac);
                        String text = getAccessibleTextRangeFromContext (ac, 0, charCount);
                        if (null != text) {
                            debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained from the Accessible Text of the LABEL object.");
                            references.increment (text);
                            return text;
                        }
                    }
                    /*
                    Does the label support the Accessible Icon Interface?
                    */
                    debugString ("[INFO]: bk -- Attempting to obtain the Virtual Accessible Name from the Accessible Icon information.");
                    final AccessibleIcon [] ai = InvocationUtils.invokeAndWait(new Callable<AccessibleIcon[]>() {
                        @Override
                        public AccessibleIcon[] call() throws Exception {
                            return ac.getAccessibleIcon();
                        }
                    }, ac);
                    if ( (null != ai) && (ai.length > 0) ) {
                        String iconDescription = InvocationUtils.invokeAndWait(new Callable<String>() {
                            @Override
                            public String call() throws Exception {
                                return ai[0].getAccessibleIconDescription();
                            }
                        }, ac);
                        if (iconDescription != null){
                            debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained from the description of the first Accessible Icon found in the LABEL object.");
                            references.increment (iconDescription);
                            return iconDescription;
                        }
                    } else {
                        parentContext = getAccessibleParentFromContext (ac);
                        if ( null != parentContext ) {
                            final AccessibleContext parentContextInnerTemp = parentContext;
                            parentRole = InvocationUtils.invokeAndWait(new Callable<AccessibleRole>() {
                                @Override
                                public AccessibleRole call() throws Exception {
                                    return parentContextInnerTemp.getAccessibleRole();
                                }
                            }, ac);
                            if ( AccessibleRole.TABLE == parentRole ) {
                                int indexInParent = InvocationUtils.invokeAndWait(new Callable<Integer>() {
                                    @Override
                                    public Integer call() throws Exception {
                                        return ac.getAccessibleIndexInParent();
                                    }
                                }, ac);
                                final AccessibleContext acTableCell = getAccessibleChildFromContext (parentContext, indexInParent);
                                debugString ("[INFO]: bk -- Making a second attempt to obtain the Virtual Accessible Name from the Accessible Icon information for the Table Cell.");
                                if (acTableCell != null) {
                                    final AccessibleIcon [] aiRet =InvocationUtils.invokeAndWait(new Callable<AccessibleIcon[]>() {
                                        @Override
                                        public AccessibleIcon[] call() throws Exception {
                                            return acTableCell.getAccessibleIcon();
                                        }
                                    }, ac);
                                    if ( (null != aiRet) && (aiRet.length > 0) ) {
                                        String iconDescription = InvocationUtils.invokeAndWait(new Callable<String>() {
                                            @Override
                                            public String call() throws Exception {
                                                return aiRet[0].getAccessibleIconDescription();
                                            }
                                        }, ac);
                                        if (iconDescription != null){
                                            debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained from the description of the first Accessible Icon found in the Table Cell object.");
                                            references.increment (iconDescription);
                                            return iconDescription;
                                        }
                                    }
                                }
                            }
                        }
                    }
                } else if ( (AccessibleRole.TOGGLE_BUTTON == role) ||
                            (AccessibleRole.PUSH_BUTTON == role) ) {
                    /*
                    Does the button support the Accessible Icon Interface?
                    */
                    debugString ("[INFO]: bk -- Attempting to obtain the Virtual Accessible Name from the Accessible Icon information.");
                    final AccessibleIcon [] ai = InvocationUtils.invokeAndWait(new Callable<AccessibleIcon[]>() {
                        @Override
                        public AccessibleIcon[] call() throws Exception {
                            return ac.getAccessibleIcon();
                        }
                    }, ac);
                    if ( (null != ai) && (ai.length > 0) ) {
                        String iconDescription = InvocationUtils.invokeAndWait(new Callable<String>() {
                            @Override
                            public String call() throws Exception {
                                return ai[0].getAccessibleIconDescription();
                            }
                        }, ac);
                        if (iconDescription != null){
                            debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained from the description of the first Accessible Icon found in the TOGGLE_BUTTON or PUSH_BUTTON object.");
                            references.increment (iconDescription);
                            return iconDescription;
                        }
                    }
                } else if ( AccessibleRole.CHECK_BOX == role ) {
                    /*
                    NOTE: The only case I know of in which a check box does not
                    have a name is when that check box is contained in a table.

                    In this case it would be appropriate to use the display string
                    of the check box object as the name (in US English the display
                    string is typically either "true" or "false").

                    I am using the AccessibleValue interface to obtain the display
                    string of the check box.  If the Accessible Value is 1, I am
                    returning Boolean.TRUE.toString (),  If the Accessible Value is
                    0, I am returning Boolean.FALSE.toString ().  If the Accessible
                    Value is some other number, I will return the display string of
                    the current numerical value of the check box.
                    */
                    final AccessibleValue av = InvocationUtils.invokeAndWait(new Callable<AccessibleValue>() {
                        @Override
                        public AccessibleValue call() throws Exception {
                            return ac.getAccessibleValue();
                        }
                    }, ac);
                    if ( null != av ) {
                        nameString = null;
                        Number value = InvocationUtils.invokeAndWait(new Callable<Number>() {
                            @Override
                            public Number call() throws Exception {
                                return av.getCurrentAccessibleValue();
                            }
                        }, ac);
                        if ( null != value ) {
                            if ( 1 == value.intValue () ) {
                                nameString = Boolean.TRUE.toString ();
                            } else if ( 0 == value.intValue () ) {
                                nameString = Boolean.FALSE.toString ();
                            } else {
                                nameString = value.toString ();
                            }
                            if ( null != nameString ) {
                                references.increment (nameString);
                                return nameString;
                            }
                        }
                    }
                }
                return null;
            }

            /*
            +
            Beginning of the extended name search
            +
            */
            final AccessibleContext parentContextOuterTemp = parentContext;
            String parentName = InvocationUtils.invokeAndWait(new Callable<String>() {
                @Override
                public String call() throws Exception {
                    return parentContextOuterTemp.getAccessibleName();
                }
            }, ac);
            String parentDescription = InvocationUtils.invokeAndWait(new Callable<String>() {
                @Override
                public String call() throws Exception {
                    return parentContextOuterTemp.getAccessibleDescription();
                }
            }, ac);

            /*
            Step 4:
            =======
            Special case for Slider Bar objects.
            */
            if ( (AccessibleRole.SLIDER == role) &&
                 (AccessibleRole.PANEL == parentRole) &&
                 (null != parentName) ) {
                debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained from the Accessible Name of the SLIDER object's parent object.");
                references.increment (parentName);
                return parentName;
            }

            boolean bIsEditCombo = false;

            AccessibleContext testContext = ac;
            /*
            Step 5:
            =======
            Special case for Edit Combo Boxes
            */
            if ( (AccessibleRole.TEXT == role) &&
                 (AccessibleRole.COMBO_BOX == parentRole) ) {
                bIsEditCombo = true;
                if (null != parentName) {
                    debugString ("[INFO]: bk -- The Virtual Accessible Name for this Edit Combo box was obtained from the Accessible Name of the object's parent object.");
                    references.increment (parentName);
                    return parentName;
                } else if (null != parentDescription) {
                    debugString ("[INFO]: bk -- The Virtual Accessible Name for this Edit Combo box was obtained from the Accessible Description of the object's parent object.");
                    references.increment (parentDescription);
                    return parentDescription;
                }
                testContext = parentContext;
                parentRole = AccessibleRole.UNKNOWN;
                parentContext = getAccessibleParentFromContext (testContext);
                if ( null != parentContext ) {
                    final AccessibleContext parentContextInnerTemp = parentContext;
                    parentRole = InvocationUtils.invokeAndWait(new Callable<AccessibleRole>() {
                        @Override
                        public AccessibleRole call() throws Exception {
                            return parentContextInnerTemp.getAccessibleRole();
                        }
                    }, ac);
                }
            }

            /*
            Step 6:
            =======
            Attempt to get the Virtual Accessible Name of the object using the
            Accessible Relation Set Info (the LABELED_BY Accessible Relation).
            */
            {
                final AccessibleContext parentContextTempInner = parentContext;
                AccessibleRelationSet ars = InvocationUtils.invokeAndWait(new Callable<AccessibleRelationSet>() {
                    @Override
                    public AccessibleRelationSet call() throws Exception {
                        return parentContextTempInner.getAccessibleRelationSet();
                    }
                }, ac);
                if ( ars != null && (ars.size () > 0) && (ars.contains (AccessibleRelation.LABELED_BY)) ) {
                    AccessibleRelation labeledByRelation = ars.get (AccessibleRelation.LABELED_BY);
                    if (labeledByRelation != null) {
                        Object [] targets = labeledByRelation.getTarget ();
                        Object o = targets [0];
                        if (o instanceof Accessible) {
                            AccessibleContext labelContext = ((Accessible)o).getAccessibleContext ();
                            if (labelContext != null) {
                                String labelName = labelContext.getAccessibleName ();
                                String labelDescription = labelContext.getAccessibleDescription ();
                                if (null != labelName) {
                                    debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained using the LABELED_BY AccessibleRelation -- Name Case.");
                                    references.increment (labelName);
                                    return labelName;
                                } else if (null != labelDescription) {
                                    debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained using the LABELED_BY AccessibleRelation -- Description Case.");
                                    references.increment (labelDescription);
                                    return labelDescription;
                                }
                            }
                        }
                    }
                }
            }

            //Note: add AccessibleContext to use InvocationUtils.invokeAndWait
            /*
            Step 7:
            =======
            Search for a label object that is positioned either just to the left
            or just above the object and get the Accessible Name of the Label
            object.
            */
            int testIndexMax = 0;
            int testX = 0;
            int testY = 0;
            int testWidth = 0;
            int testHeight = 0;
            int targetX = 0;
            int targetY = 0;
            final AccessibleContext tempContext = testContext;
            int testIndex = InvocationUtils.invokeAndWait(new Callable<Integer>() {
                @Override
                public Integer call() throws Exception {
                    return tempContext.getAccessibleIndexInParent();
                }
            }, ac);
            if ( null != parentContext ) {
                final AccessibleContext parentContextInnerTemp = parentContext;
                testIndexMax =  InvocationUtils.invokeAndWait(new Callable<Integer>() {
                    @Override
                    public Integer call() throws Exception {
                        return parentContextInnerTemp.getAccessibleChildrenCount() - 1;
                    }
                }, ac);
            }
            testX = getAccessibleXcoordFromContext (testContext);
            testY = getAccessibleYcoordFromContext (testContext);
            testWidth = getAccessibleWidthFromContext (testContext);
            testHeight = getAccessibleHeightFromContext (testContext);
            targetX = testX + 2;
            targetY = testY + 2;

            int childIndex = testIndex - 1;
            /*Accessible child = null;
            AccessibleContext childContext = null;
            AccessibleRole childRole = AccessibleRole.UNKNOWN;*/
            int childX = 0;
            int childY = 0;
            int childWidth = 0;
            int childHeight = 0;
            String childName = null;
            String childDescription = null;
            while (childIndex >= 0) {
                final int childIndexTemp = childIndex;
                final AccessibleContext parentContextInnerTemp = parentContext;
                final Accessible child  =  InvocationUtils.invokeAndWait(new Callable<Accessible>() {
                    @Override
                    public Accessible call() throws Exception {
                        return parentContextInnerTemp.getAccessibleChild(childIndexTemp);
                    }
                }, ac);
                if ( null != child ) {
                    final AccessibleContext childContext = InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
                        @Override
                        public AccessibleContext call() throws Exception {
                            return child.getAccessibleContext();
                        }
                    }, ac);
                    if ( null != childContext ) {
                        AccessibleRole childRole = InvocationUtils.invokeAndWait(new Callable<AccessibleRole>() {
                            @Override
                            public AccessibleRole call() throws Exception {
                                return childContext.getAccessibleRole();
                            }
                        }, ac);
                        if ( AccessibleRole.LABEL == childRole ) {
                            childX = getAccessibleXcoordFromContext (childContext);
                            childY = getAccessibleYcoordFromContext (childContext);
                            childWidth = getAccessibleWidthFromContext (childContext);
                            childHeight = getAccessibleHeightFromContext (childContext);
                            if ( (childX < testX) &&
                                 ((childY <= targetY) && (targetY <= (childY + childHeight))) ) {
                                childName = InvocationUtils.invokeAndWait(new Callable<String>() {
                                    @Override
                                    public String call() throws Exception {
                                        return childContext.getAccessibleName();
                                    }
                                }, ac);
                                if ( null != childName ) {
                                    debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained from Accessible Name of a LABEL object positioned to the left of the object.");
                                    references.increment (childName);
                                    return childName;
                                }
                                childDescription = InvocationUtils.invokeAndWait(new Callable<String>() {
                                    @Override
                                    public String call() throws Exception {
                                        return childContext.getAccessibleDescription();
                                    }
                                }, ac);
                                if ( null != childDescription ) {
                                    debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained from Accessible Description of a LABEL object positioned to the left of the object.");
                                    references.increment (childDescription);
                                    return childDescription;
                                }
                            } else if ( (childY < targetY) &&
                                        ((childX <= targetX) && (targetX <= (childX + childWidth))) ) {
                                childName = InvocationUtils.invokeAndWait(new Callable<String>() {
                                    @Override
                                    public String call() throws Exception {
                                        return childContext.getAccessibleName();
                                    }
                                }, ac);
                                if ( null != childName ) {
                                    debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained from Accessible Name of a LABEL object positioned above the object.");
                                    references.increment (childName);
                                    return childName;
                                }
                                childDescription = InvocationUtils.invokeAndWait(new Callable<String>() {
                                    @Override
                                    public String call() throws Exception {
                                        return childContext.getAccessibleDescription();
                                    }
                                }, ac);
                                if ( null != childDescription ) {
                                    debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained from Accessible Description of a LABEL object positioned above the object.");
                                    references.increment (childDescription);
                                    return childDescription;
                                }
                            }
                        }
                    }
                }
                childIndex --;
            }
            childIndex = testIndex + 1;
            while (childIndex <= testIndexMax) {
                final int childIndexTemp = childIndex;
                final AccessibleContext parentContextInnerTemp = parentContext;
                final Accessible child  =  InvocationUtils.invokeAndWait(new Callable<Accessible>() {
                    @Override
                    public Accessible call() throws Exception {
                        return parentContextInnerTemp.getAccessibleChild(childIndexTemp);
                    }
                }, ac);
                if ( null != child ) {
                    final AccessibleContext childContext = InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
                        @Override
                        public AccessibleContext call() throws Exception {
                            return child.getAccessibleContext();
                        }
                    }, ac);
                    if ( null != childContext ) {
                        AccessibleRole childRole = InvocationUtils.invokeAndWait(new Callable<AccessibleRole>() {
                            @Override
                            public AccessibleRole call() throws Exception {
                                return childContext.getAccessibleRole();
                            }
                        }, ac);
                        if ( AccessibleRole.LABEL == childRole ) {
                            childX = getAccessibleXcoordFromContext (childContext);
                            childY = getAccessibleYcoordFromContext (childContext);
                            childWidth = getAccessibleWidthFromContext (childContext);
                            childHeight = getAccessibleHeightFromContext (childContext);
                            if ( (childX < testX) &&
                                 ((childY <= targetY) && (targetY <= (childY + childHeight))) ) {
                                childName = InvocationUtils.invokeAndWait(new Callable<String>() {
                                    @Override
                                    public String call() throws Exception {
                                        return childContext.getAccessibleName();
                                    }
                                }, ac);
                                if ( null != childName ) {
                                    debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained from Accessible Name of a LABEL object positioned to the left of the object.");
                                    references.increment (childName);
                                    return childName;
                                }
                                childDescription = InvocationUtils.invokeAndWait(new Callable<String>() {
                                    @Override
                                    public String call() throws Exception {
                                        return childContext.getAccessibleDescription();
                                    }
                                }, ac);
                                if ( null != childDescription ) {
                                    debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained from Accessible Description of a LABEL object positioned to the left of the object.");
                                    references.increment (childDescription);
                                    return childDescription;
                                }
                            } else if ( (childY < targetY) &&
                                        ((childX <= targetX) && (targetX <= (childX + childWidth))) ) {
                                childName = InvocationUtils.invokeAndWait(new Callable<String>() {
                                    @Override
                                    public String call() throws Exception {
                                        return childContext.getAccessibleName();
                                    }
                                }, ac);
                                if ( null != childName ) {
                                    debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained from Accessible Name of a LABEL object positioned above the object.");
                                    references.increment (childName);
                                    return childName;
                                }
                                childDescription = InvocationUtils.invokeAndWait(new Callable<String>() {
                                    @Override
                                    public String call() throws Exception {
                                        return childContext.getAccessibleDescription();
                                    }
                                }, ac);
                                if ( null != childDescription ) {
                                    debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained from Accessible Description of a LABEL object positioned above the object.");
                                    references.increment (childDescription);
                                    return childDescription;
                                }
                            }
                        }
                    }
                }
                childIndex ++;
            }
            /*
            Step 8:
            =======
            Special case for combo boxes and text objects, based on a
            similar special case I found in some of our internal JAWS code.

            Search for a button object that is positioned either just to the left
            or just above the object and get the Accessible Name of the button
            object.
            */
            if ( (AccessibleRole.TEXT == role) ||
                 (AccessibleRole.COMBO_BOX == role) ||
                 (bIsEditCombo) ) {
                childIndex = testIndex - 1;
                while (childIndex >= 0) {
                    final int childIndexTemp = childIndex;
                    final AccessibleContext parentContextInnerTemp = parentContext;
                    final Accessible child = InvocationUtils.invokeAndWait(new Callable<Accessible>() {
                        @Override
                        public Accessible call() throws Exception {
                            return parentContextInnerTemp.getAccessibleChild(childIndexTemp);
                        }
                    }, ac);
                    if ( null != child ) {
                        final AccessibleContext childContext = InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
                            @Override
                            public AccessibleContext call() throws Exception {
                                return child.getAccessibleContext();
                            }
                        }, ac);
                        if ( null != childContext ) {
                            AccessibleRole childRole = InvocationUtils.invokeAndWait(new Callable<AccessibleRole>() {
                                @Override
                                public AccessibleRole call() throws Exception {
                                    return childContext.getAccessibleRole();
                                }
                            }, ac);
                            if ( ( AccessibleRole.PUSH_BUTTON == childRole ) ||
                                 ( AccessibleRole.TOGGLE_BUTTON == childRole )) {
                                childX = getAccessibleXcoordFromContext (childContext);
                                childY = getAccessibleYcoordFromContext (childContext);
                                childWidth = getAccessibleWidthFromContext (childContext);
                                childHeight = getAccessibleHeightFromContext (childContext);
                                if ( (childX < testX) &&
                                     ((childY <= targetY) && (targetY <= (childY + childHeight))) ) {
                                    childName = InvocationUtils.invokeAndWait(new Callable<String>() {
                                        @Override
                                        public String call() throws Exception {
                                            return childContext.getAccessibleName();
                                        }
                                    }, ac);
                                    if ( null != childName ) {
                                        debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained from Accessible Name of a PUSH_BUTTON or TOGGLE_BUTTON object positioned to the left of the object.");
                                        references.increment (childName);
                                        return childName;
                                    }
                                    childDescription = InvocationUtils.invokeAndWait(new Callable<String>() {
                                        @Override
                                        public String call() throws Exception {
                                            return childContext.getAccessibleDescription();
                                        }
                                    }, ac);
                                    if ( null != childDescription ) {
                                        debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained from Accessible Description of a PUSH_BUTTON or TOGGLE_BUTTON object positioned to the left of the object.");
                                        references.increment (childDescription);
                                        return childDescription;
                                    }
                                }
                            }
                        }
                    }
                    childIndex --;
                }
                childIndex = testIndex + 1;
                while (childIndex <= testIndexMax) {
                    final int childIndexTemp = childIndex;
                    final AccessibleContext parentContextInnerTemp = parentContext;
                    final Accessible child  =  InvocationUtils.invokeAndWait(new Callable<Accessible>() {
                        @Override
                        public Accessible call() throws Exception {
                            return parentContextInnerTemp.getAccessibleChild(childIndexTemp);
                        }
                    }, ac);
                    if ( null != child ) {
                        final AccessibleContext childContext = InvocationUtils.invokeAndWait(new Callable<AccessibleContext>() {
                            @Override
                            public AccessibleContext call() throws Exception {
                                return child.getAccessibleContext();
                            }
                        }, ac);
                        if ( null != childContext ) {
                            AccessibleRole childRole = InvocationUtils.invokeAndWait(new Callable<AccessibleRole>() {
                                @Override
                                public AccessibleRole call() throws Exception {
                                    return childContext.getAccessibleRole();
                                }
                            }, ac);
                            if ( ( AccessibleRole.PUSH_BUTTON == childRole ) ||
                                    ( AccessibleRole.TOGGLE_BUTTON == childRole ) ) {
                                childX = getAccessibleXcoordFromContext (childContext);
                                childY = getAccessibleYcoordFromContext (childContext);
                                childWidth = getAccessibleWidthFromContext (childContext);
                                childHeight = getAccessibleHeightFromContext (childContext);
                                if ( (childX < testX) &&
                                     ((childY <= targetY) && (targetY <= (childY + childHeight))) ) {
                                    childName = InvocationUtils.invokeAndWait(new Callable<String>() {
                                        @Override
                                        public String call() throws Exception {
                                            return childContext.getAccessibleName();
                                        }
                                    }, ac);
                                    if ( null != childName ) {
                                        debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained from Accessible Name of a PUSH_BUTTON or TOGGLE_BUTTON object positioned to the left of the object.");
                                        references.increment (childName);
                                        return childName;
                                    }
                                    childDescription = InvocationUtils.invokeAndWait(new Callable<String>() {
                                        @Override
                                        public String call() throws Exception {
                                            return childContext.getAccessibleDescription();
                                        }
                                    }, ac);
                                    if ( null != childDescription ) {
                                        debugString ("[INFO]: bk -- The Virtual Accessible Name was obtained from Accessible Description of a PUSH_BUTTON or TOGGLE_BUTTON object positioned to the left of the object.");
                                        references.increment (childDescription);
                                        return childDescription;
                                    }
                                }
                            }
                        }
                    }
                    childIndex ++;
                }
            }
            return null;
        } else {
            debugString ("[ERROR]: AccessBridge::getVirtualAccessibleNameFromContext error - ac == null.");
            return null;
        }
    }