private ADTNode<ADTState<I, O>, I, O> evaluateAdtExtension(final ADTNode<ADTState<I, O>, I, O> ads) {

        final ExtensionResult<ADTState<I, O>, I, O> potentialExtension =
                this.adtExtender.computeExtension(this.hypothesis, this, ads);

        if (potentialExtension.isCounterExample()) {
            this.openCounterExamples.add(potentialExtension.getCounterExample());
            return ads;
        } else if (!potentialExtension.isReplacement()) {
            return ads;
        }

        final ADTNode<ADTState<I, O>, I, O> extension = potentialExtension.getReplacement();
        final ADTNode<ADTState<I, O>, I, O> nodeToReplace = ads.getParent(); // reset node

        assert this.validateADS(nodeToReplace, extension, Collections.emptySet());

        final ADTNode<ADTState<I, O>, I, O> replacement = this.verifyADS(nodeToReplace,
                                                                         extension,
                                                                         ADTUtil.collectLeaves(this.adt.getRoot()),
                                                                         Collections.emptySet());

        // verification may have introduced reset nodes
        final int oldCosts = ADTUtil.computeEffectiveResets(nodeToReplace);
        final int newCosts = ADTUtil.computeEffectiveResets(replacement);

        if (newCosts >= oldCosts) {
            return ads;
        }

        // replace
        this.adt.replaceNode(nodeToReplace, replacement);

        final ADTNode<ADTState<I, O>, I, O> finalizedADS = ADTUtil.getStartOfADS(replacement);

        // update
        this.resiftAffectedTransitions(ADTUtil.collectLeaves(extension), finalizedADS);

        return finalizedADS;
    }
private ADTNode < ADTState < I , O > , I , O > evaluateAdtExtension ( final ADTNode < ADTState < I , O > , I , O > ads ) { final ExtensionResult < ADTState < I , O > , I , O > potentialExtension = this . adtExtender . computeExtension ( this . hypothesis , this , ads ) ; if ( potentialExtension . isCounterExample ( ) ) { this . openCounterExamples . add ( potentialExtension . getCounterExample ( ) ) ; return ads ; } else if ( ! potentialExtension . isReplacement ( ) ) { return ads ; } final ADTNode < ADTState < I , O > , I , O > extension = potentialExtension . getReplacement ( ) ; final ADTNode < ADTState < I , O > , I , O > nodeToReplace = ads . getParent ( ) ; assert this . validateADS ( nodeToReplace , extension , Collections . emptySet ( ) ) ; final ADTNode < ADTState < I , O > , I , O > replacement = this . verifyADS ( nodeToReplace , extension , ADTUtil . collectLeaves ( this . adt . getRoot ( ) ) , Collections . emptySet ( ) ) ; final int oldCosts = ADTUtil . computeEffectiveResets ( nodeToReplace ) ; final int newCosts = ADTUtil . computeEffectiveResets ( replacement ) ; if ( newCosts >= oldCosts ) { return ads ; } this . adt . replaceNode ( nodeToReplace , replacement ) ; final ADTNode < ADTState < I , O > , I , O > finalizedADS = ADTUtil . getStartOfADS ( replacement ) ; this . resiftAffectedTransitions ( ADTUtil . collectLeaves ( extension ) , finalizedADS ) ; return finalizedADS ; }
Ask the current {@link #adtExtender} for a potential extension.

@param ads
the temporary ADS based on the inferred distinguishing suffix

@return a validated ADT that can be used to distinguish the states referenced in the given temporary ADS