public static ResolvedType leastUpperBound(Set<ResolvedType> types) {
        if (types.size() == 0) {
            throw new IllegalArgumentException();
        }

        // The least upper bound, or "lub", of a set of reference types is a shared supertype that is more specific than
        // any other shared supertype (that is, no other shared supertype is a subtype of the least upper bound).
        // This type, lub(U1, ..., Uk), is determined as follows.
        //
        // If k = 1, then the lub is the type itself: lub(U) = U.

        if (types.size() == 1) {
            return types.stream().findFirst().get();
        }

        //
        //Otherwise:
        //
        //For each Ui (1 ≤ i ≤ k):
        //
        //Let ST(Ui) be the set of supertypes of Ui.
        //
        //Let EST(Ui), the set of erased supertypes of Ui, be:
        //
        //EST(Ui) = { |W| | W in ST(Ui) } where |W| is the erasure of W.
        //
        //The reason for computing the set of erased supertypes is to deal with situations where the set of types includes several distinct parameterizations of a generic type.
        //
        //For example, given List<String> and List<Object>, simply intersecting the sets ST(List<String>) = { List<String>, Collection<String>, Object } and ST(List<Object>) = { List<Object>, Collection<Object>, Object } would yield a set { Object }, and we would have lost track of the fact that the upper bound can safely be assumed to be a List.
        //
        //In contrast, intersecting EST(List<String>) = { List, Collection, Object } and EST(List<Object>) = { List, Collection, Object } yields { List, Collection, Object }, which will eventually enable us to produce List<?>.
        //
        //Let EC, the erased candidate set for U1 ... Uk, be the intersection of all the sets EST(Ui) (1 ≤ i ≤ k).
        //
        //Let MEC, the minimal erased candidate set for U1 ... Uk, be:
        //
        //MEC = { V | V in EC, and for all W ≠ V in EC, it is not the case that W <: V }
        //
        //Because we are seeking to infer more precise types, we wish to filter out any candidates that are supertypes of other candidates. This is what computing MEC accomplishes. In our running example, we had EC = { List, Collection, Object }, so MEC = { List }. The next step is to recover type arguments for the erased types in MEC.
        //
        //For any element G of MEC that is a generic type:
        //
        //Let the "relevant" parameterizations of G, Relevant(G), be:
        //
        //Relevant(G) = { V | 1 ≤ i ≤ k: V in ST(Ui) and V = G<...> }
        //
        //In our running example, the only generic element of MEC is List, and Relevant(List) = { List<String>, List<Object> }. We will now seek to find a type argument for List that contains (§4.5.1) both String and Object.
        //
        //This is done by means of the least containing parameterization (lcp) operation defined below. The first line defines lcp() on a set, such as Relevant(List), as an operation on a list of the elements of the set. The next line defines the operation on such lists, as a pairwise reduction on the elements of the list. The third line is the definition of lcp() on pairs of parameterized types, which in turn relies on the notion of least containing type argument (lcta). lcta() is defined for all possible cases.
        //
        //Let the "candidate" parameterization of G, Candidate(G), be the most specific parameterization of the generic type G that contains all the relevant parameterizations of G:
        //
        //Candidate(G) = lcp(Relevant(G))
        //
        //where lcp(), the least containing invocation, is:
        //
        //lcp(S) = lcp(e1, ..., en) where ei (1 ≤ i ≤ n) in S
        //
        //lcp(e1, ..., en) = lcp(lcp(e1, e2), e3, ..., en)
        //
        //lcp(G<X1, ..., Xn>, G<Y1, ..., Yn>) = G<lcta(X1, Y1), ..., lcta(Xn, Yn)>
        //
        //lcp(G<X1, ..., Xn>) = G<lcta(X1), ..., lcta(Xn)>
        //
        //and where lcta(), the least containing type argument, is: (assuming U and V are types)
        //
        //lcta(U, V) = U if U = V, otherwise ? extends lub(U, V)
        //
        //lcta(U, ? extends V) = ? extends lub(U, V)
        //
        //lcta(U, ? super V) = ? super glb(U, V)
        //
        //lcta(? extends U, ? extends V) = ? extends lub(U, V)
        //
        //lcta(? extends U, ? super V) = U if U = V, otherwise ?
        //
        //lcta(? super U, ? super V) = ? super glb(U, V)
        //
        //lcta(U) = ? if U's upper bound is Object, otherwise ? extends lub(U,Object)
        //
        //and where glb() is as defined in §5.1.10.
        //
        //Let lub(U1 ... Uk) be:
        //
        //Best(W1) & ... & Best(Wr)
        //
        //where Wi (1 ≤ i ≤ r) are the elements of MEC, the minimal erased candidate set of U1 ... Uk;
        //
        //and where, if any of these elements are generic, we use the candidate parameterization (so as to recover type arguments):
        //
        //Best(X) = Candidate(X) if X is generic; X otherwise.
        //
        //Strictly speaking, this lub() function only approximates a least upper bound. Formally, there may exist some other type T such that all of U1 ... Uk are subtypes of T and T is a subtype of lub(U1, ..., Uk). However, a compiler for the Java programming language must implement lub() as specified above.
        //
        //It is possible that the lub() function yields an infinite type. This is permissible, and a compiler for the Java programming language must recognize such situations and represent them appropriately using cyclic data structures.
        //
        //The possibility of an infinite type stems from the recursive calls to lub(). Readers familiar with recursive types should note that an infinite type is not the same as a recursive type
        throw new UnsupportedOperationException();
    }

See JLS 4 . 10 . 4 . Least Upper Bound .


public static Pair<ResolvedType, Boolean> groundTargetTypeOfLambda(LambdaExpr lambdaExpr, ResolvedType T, TypeSolver typeSolver) {
        // The ground target type is derived from T as follows:
        //
        boolean used18_5_3 = false;

        boolean wildcardParameterized = T.asReferenceType().typeParametersValues().stream()
                .anyMatch(tp -> tp.isWildcard());
        if (wildcardParameterized) {
            // - If T is a wildcard-parameterized functional interface type and the lambda expression is explicitly typed,
            //   then the ground target type is inferred as described in §18.5.3.

            if (ExpressionHelper.isExplicitlyTyped(lambdaExpr)) {
                used18_5_3 = true;
                throw new UnsupportedOperationException();
            }

            // - If T is a wildcard-parameterized functional interface type and the lambda expression is implicitly typed,
            //   then the ground target type is the non-wildcard parameterization (§9.9) of T.

            else {
                return new Pair<>(nonWildcardParameterizationOf(T.asReferenceType(), typeSolver), used18_5_3);
            }
        }

        // - Otherwise, the ground target type is T.
        return new Pair<>(T, used18_5_3);
    }

See JLS 15.27.3. Type of a Lambda Expression
@return

See JLS 15 . 27 . 3 . Type of a Lambda Expression


private static ResolvedReferenceType nonWildcardParameterizationOf(ResolvedReferenceType originalType, TypeSolver typeSolver) {
        List<ResolvedType> TIs = new LinkedList<>();
        List<ResolvedType> AIs = originalType.typeParametersValues();
        List<ResolvedTypeParameterDeclaration> TPs = originalType.getTypeDeclaration().getTypeParameters();

        // Let P1...Pn be the type parameters of I with corresponding bounds B1...Bn. For all i (1 ≤ i ≤ n),
        // Ti is derived according to the form of Ai:

        ResolvedReferenceType object = new ReferenceTypeImpl(typeSolver.solveType(Object.class.getCanonicalName()), typeSolver);

        for (int i=0;i<AIs.size();i++) {
            ResolvedType Ai = AIs.get(i);
            ResolvedType Ti = null;

            // - If Ai is a type, then Ti = Ai.

            if (!Ai.isWildcard()) {
                Ti = Ai;
            }

            // - If Ai is a wildcard, and the corresponding type parameter's bound, Bi, mentions one of P1...Pn, then
            //   Ti is undefined and there is no function type.

            if (Ti == null && Ai.isWildcard() && Ai.asWildcard().mention(originalType.getTypeDeclaration().getTypeParameters())) {
                throw new IllegalArgumentException();
            }

            // - Otherwise:

            if (Ti == null) {

                ResolvedType Bi = TPs.get(i).hasLowerBound() ? TPs.get(i).getLowerBound() : object;

                //   - If Ai is an unbound wildcard ?, then Ti = Bi.

                if (Ai.isWildcard() && !Ai.asWildcard().isBounded()) {
                    Ti = Bi;
                }

                //   - If Ai is a upper-bounded wildcard ? extends Ui, then Ti = glb(Ui, Bi) (§5.1.10).

                else if (Ai.isWildcard() && Ai.asWildcard().isUpperBounded()) {
                    ResolvedType Ui = Ai.asWildcard().getBoundedType();
                    Ti = glb(new HashSet<>(Arrays.asList(Ui, Bi)));
                }

                //   - If Ai is a lower-bounded wildcard ? super Li, then Ti = Li.

                else if (Ai.isWildcard() && Ai.asWildcard().isLowerBounded()) {
                    Ti = Ai.asWildcard().getBoundedType();
                }

                else throw new RuntimeException("This should not happen");
            }

            TIs.add(Ti);
        }

        return new ReferenceTypeImpl(originalType.getTypeDeclaration(), TIs, typeSolver);
    }


public static ResolvedType glb(Set<ResolvedType> types) {
        if (types.size() == 0) {
            throw new IllegalArgumentException();
        }
        if (types.size() == 1) {
            return types.iterator().next();
        }
        return new ResolvedIntersectionType(types);
    }

public static ResolvedType glb ( Set < ResolvedType > types ) { if ( types . size ( ) == 0 ) { throw new IllegalArgumentException ( ) ; } if ( types . size ( ) == 1 ) { return types . iterator ( ) . next ( ) ; } return new ResolvedIntersectionType ( types ) ; }

See JLS 5 . 1 . 10 . Capture Conversion .


private ResolvedType solveDotExpressionType(ResolvedReferenceTypeDeclaration parentType, FieldAccessExpr node) {
        // Fields and internal type declarations cannot have the same name.
        // Thus, these checks will always be mutually exclusive.
        if (parentType.hasField(node.getName().getId())) {
            return parentType.getField(node.getName().getId()).getType();
        } else if (parentType.hasInternalType(node.getName().getId())) {
            return new ReferenceTypeImpl(parentType.getInternalType(node.getName().getId()), typeSolver);
        } else {
            throw new UnsolvedSymbolException(node.getName().getId());
        }
    }

Java Parser can't differentiate between packages, internal types, and fields.
All three are lumped together into FieldAccessExpr. We need to differentiate them.

Java Parser can t differentiate between packages internal types and fields . All three are lumped together into FieldAccessExpr . We need to differentiate them .


public SymbolReference<ResolvedConstructorDeclaration> solve(ObjectCreationExpr objectCreationExpr, boolean solveLambdas) {
        List<ResolvedType> argumentTypes = new LinkedList<>();
        List<LambdaArgumentTypePlaceholder> placeholders = new LinkedList<>();

        solveArguments(objectCreationExpr, objectCreationExpr.getArguments(), solveLambdas, argumentTypes, placeholders);

        ResolvedType classDecl = JavaParserFacade.get(typeSolver).convert(objectCreationExpr.getType(), objectCreationExpr);
        if (!classDecl.isReferenceType()) {
            return SymbolReference.unsolved(ResolvedConstructorDeclaration.class);
        }
        SymbolReference<ResolvedConstructorDeclaration> res = ConstructorResolutionLogic.findMostApplicable(((ResolvedClassDeclaration) classDecl.asReferenceType().getTypeDeclaration()).getConstructors(), argumentTypes, typeSolver);
        for (LambdaArgumentTypePlaceholder placeholder : placeholders) {
            placeholder.setMethod(res);
        }
        return res;
    }

public SymbolReference < ResolvedConstructorDeclaration > solve ( ObjectCreationExpr objectCreationExpr , boolean solveLambdas ) { List < ResolvedType > argumentTypes = new LinkedList <> ( ) ; List < LambdaArgumentTypePlaceholder > placeholders = new LinkedList <> ( ) ; solveArguments ( objectCreationExpr , objectCreationExpr . getArguments ( ) , solveLambdas , argumentTypes , placeholders ) ; ResolvedType classDecl = JavaParserFacade . get ( typeSolver ) . convert ( objectCreationExpr . getType ( ) , objectCreationExpr ) ; if ( ! classDecl . isReferenceType ( ) ) { return SymbolReference . unsolved ( ResolvedConstructorDeclaration . class ) ; } SymbolReference < ResolvedConstructorDeclaration > res = ConstructorResolutionLogic . findMostApplicable ( ( ( ResolvedClassDeclaration ) classDecl . asReferenceType ( ) . getTypeDeclaration ( ) ) . getConstructors ( ) , argumentTypes , typeSolver ) ; for ( LambdaArgumentTypePlaceholder placeholder : placeholders ) { placeholder . setMethod ( res ) ; } return res ; }

Given a constructor call find out to which constructor declaration it corresponds.

Given a constructor call find out to which constructor declaration it corresponds .


public SymbolReference<ResolvedMethodDeclaration> solve(MethodCallExpr methodCallExpr, boolean solveLambdas) {
        List<ResolvedType> argumentTypes = new LinkedList<>();
        List<LambdaArgumentTypePlaceholder> placeholders = new LinkedList<>();

        solveArguments(methodCallExpr, methodCallExpr.getArguments(), solveLambdas, argumentTypes, placeholders);

        SymbolReference<ResolvedMethodDeclaration> res = JavaParserFactory.getContext(methodCallExpr, typeSolver).solveMethod(methodCallExpr.getName().getId(), argumentTypes, false, typeSolver);
        for (LambdaArgumentTypePlaceholder placeholder : placeholders) {
            placeholder.setMethod(res);
        }
        return res;
    }

public SymbolReference < ResolvedMethodDeclaration > solve ( MethodCallExpr methodCallExpr , boolean solveLambdas ) { List < ResolvedType > argumentTypes = new LinkedList <> ( ) ; List < LambdaArgumentTypePlaceholder > placeholders = new LinkedList <> ( ) ; solveArguments ( methodCallExpr , methodCallExpr . getArguments ( ) , solveLambdas , argumentTypes , placeholders ) ; SymbolReference < ResolvedMethodDeclaration > res = JavaParserFactory . getContext ( methodCallExpr , typeSolver ) . solveMethod ( methodCallExpr . getName ( ) . getId ( ) , argumentTypes , false , typeSolver ) ; for ( LambdaArgumentTypePlaceholder placeholder : placeholders ) { placeholder . setMethod ( res ) ; } return res ; }

Given a method call find out to which method declaration it corresponds.

Given a method call find out to which method declaration it corresponds .


private Optional<ResolvedType> find(Map<Node, ResolvedType> map, LambdaExpr lambdaExpr) {
        for (Node key : map.keySet()) {
            if (key instanceof LambdaExpr) {
                LambdaExpr keyLambdaExpr = (LambdaExpr) key;
                if (keyLambdaExpr.toString().equals(lambdaExpr.toString()) && getParentNode(keyLambdaExpr) == getParentNode(lambdaExpr)) {
                    return Optional.of(map.get(keyLambdaExpr));
                }
            }
        }
        return Optional.empty();
    }

private Optional < ResolvedType > find ( Map < Node , ResolvedType > map , LambdaExpr lambdaExpr ) { for ( Node key : map . keySet ( ) ) { if ( key instanceof LambdaExpr ) { LambdaExpr keyLambdaExpr = ( LambdaExpr ) key ; if ( keyLambdaExpr . toString ( ) . equals ( lambdaExpr . toString ( ) ) && getParentNode ( keyLambdaExpr ) == getParentNode ( lambdaExpr ) ) { return Optional . of ( map . get ( keyLambdaExpr ) ) ; } } } return Optional . empty ( ) ; }

For some reasons LambdaExprs are duplicate and the equals method is not implemented correctly.

@param map
@return

For some reasons LambdaExprs are duplicate and the equals method is not implemented correctly .


private String qName(ClassOrInterfaceType classOrInterfaceType) {
        String name = classOrInterfaceType.getName().getId();
        if (classOrInterfaceType.getScope().isPresent()) {
            return qName(classOrInterfaceType.getScope().get()) + "." + name;
        } else {
            return name;
        }
    }

private String qName ( ClassOrInterfaceType classOrInterfaceType ) { String name = classOrInterfaceType . getName ( ) . getId ( ) ; if ( classOrInterfaceType . getScope ( ) . isPresent ( ) ) { return qName ( classOrInterfaceType . getScope ( ) . get ( ) ) + "." + name ; } else { return name ; } }

This is an hack around an issue in JavaParser


public ResolvedType getTypeOfThisIn(Node node) {
        // TODO consider static methods
        if (node instanceof ClassOrInterfaceDeclaration) {
            return new ReferenceTypeImpl(getTypeDeclaration((ClassOrInterfaceDeclaration) node), typeSolver);
        } else if (node instanceof EnumDeclaration) {
            JavaParserEnumDeclaration enumDeclaration = new JavaParserEnumDeclaration((EnumDeclaration) node, typeSolver);
            return new ReferenceTypeImpl(enumDeclaration, typeSolver);
        } else if (node instanceof ObjectCreationExpr && ((ObjectCreationExpr) node).getAnonymousClassBody().isPresent()) {
            JavaParserAnonymousClassDeclaration anonymousDeclaration = new JavaParserAnonymousClassDeclaration((ObjectCreationExpr) node, typeSolver);
            return new ReferenceTypeImpl(anonymousDeclaration, typeSolver);
        } else {
            return getTypeOfThisIn(getParentNode(node));
        }
    }

public
ResolvedType
getTypeOfThisIn
(
Node
node
)
{
// TODO consider static methods
if
(
node
instanceof
ClassOrInterfaceDeclaration
)
{
return
new
ReferenceTypeImpl
(
getTypeDeclaration
(
(
ClassOrInterfaceDeclaration
)
node
)
,
typeSolver
)
;
}
else
if
(
node
instanceof
EnumDeclaration
)
{
JavaParserEnumDeclaration
enumDeclaration
=
new
JavaParserEnumDeclaration
(
(
EnumDeclaration
)
node
,
typeSolver
)
;
return
new
ReferenceTypeImpl
(
enumDeclaration
,
typeSolver
)
;
}
else
if
(
node
instanceof
ObjectCreationExpr
&&
(
(
ObjectCreationExpr
)
node
)
.
getAnonymousClassBody
(
)
.
isPresent
(
)
)
{
JavaParserAnonymousClassDeclaration
anonymousDeclaration
=
new
JavaParserAnonymousClassDeclaration
(
(
ObjectCreationExpr
)
node
,
typeSolver
)
;
return
new
ReferenceTypeImpl
(
anonymousDeclaration
,
typeSolver
)
;
}
else
{
return
getTypeOfThisIn
(
getParentNode
(
node
)
)
;
}
}

"this" inserted in the given point, which type would have?

this inserted in the given point which type would have?


public boolean exitTheStatement(BreakStmt breakStmt) {
        if (!isReachable(breakStmt)) {
            return false;
        }
        Statement breakTarget = breakTarget(breakStmt);
        for (TryStmt tryStmt : containedTryStmts(breakTarget)) {
            if (contains(tryStmt.getTryBlock(), breakStmt)) {
                if (!tryStmt.getFinallyBlock().isPresent() && !canCompleteNormally(tryStmt.getFinallyBlock().get())) {
                    return false;
                }
            }
        }
        return true;
    }

public boolean exitTheStatement ( BreakStmt breakStmt ) { if ( ! isReachable ( breakStmt ) ) { return false ; } Statement breakTarget = breakTarget ( breakStmt ) ; for ( TryStmt tryStmt : containedTryStmts ( breakTarget ) ) { if ( contains ( tryStmt . getTryBlock ( ) , breakStmt ) ) { if ( ! tryStmt . getFinallyBlock ( ) . isPresent ( ) && ! canCompleteNormally ( tryStmt . getFinallyBlock ( ) . get ( ) ) ) { return false ; } } } return true ; }

A reachable break statement exits a statement if, within the break target, either there are no try statements
whose try blocks contain the break statement, or there are try statements whose try blocks contain the break
statement and all finally clauses of those try statements can complete normally.

A reachable break statement exits a statement if within the break target either there are no try statements whose try blocks contain the break statement or there are try statements whose try blocks contain the break statement and all finally clauses of those try statements can complete normally .


public boolean canCompleteNormally(Statement statement) {
        if (!isReachable(statement)) {
            return false;
        }
        GenericVisitor<Boolean, Void> visitor = new GenericVisitorAdapter<Boolean, Void>(){
            @Override
            public Boolean visit(BlockStmt n, Void arg) {
                // An empty block that is not a switch block can complete normally iff it is reachable
                if (n.isEmpty() && !parentIs(statement, SwitchStmt.class)) {
                    return isReachable(statement);
                }
                // A non-empty block that is not a switch block can complete normally iff the last statement in
                // it can complete normally.
                if (!n.isEmpty() && !parentIs(statement, SwitchStmt.class)) {
                    return canCompleteNormally(n.getStatement(n.getStatements().size() - 1));
                }
                throw new UnsupportedOperationException();
            }

            @Override
            public Boolean visit(LabeledStmt n, Void arg) {
                // A labeled statement can complete normally if at least one of the following is true:
                // – The contained statement can complete normally.
                // – There is a reachable break statement that exits the labeled statement.
                throw new UnsupportedOperationException();
            }

            @Override
            public Boolean visit(EmptyStmt n, Void arg) {
                // An empty statement can complete normally iff it is reachable.
                return isReachable(n);
            }

            @Override
            public Boolean visit(LocalClassDeclarationStmt n, Void arg) {
                // A local class declaration statement can complete normally iff it is reachable.
                return isReachable(n);
            }

            @Override
            public Boolean visit(IfStmt n, Void arg) {
                if (n.getElseStmt().isPresent()) {
                    // An if-then-else statement can complete normally iff the then-statement can
                    // complete normally or the else-statement can complete normally.
                    return canCompleteNormally(n.getThenStmt()) || canCompleteNormally(n.getElseStmt().get());
                } else {
                    // An if-then statement can complete normally iff it is reachable.
                    return isReachable(n);
                }
            }

            @Override
            public Boolean visit(AssertStmt n, Void arg) {
                // An assert statement can complete normally iff it is reachable.
                return isReachable(n);
            }

            @Override
            public Boolean visit(ExpressionStmt n, Void arg) {
                // A local variable declaration statement can complete normally iff it is reachable.
                if (n.getExpression() instanceof VariableDeclarationExpr) {
                    VariableDeclarationExpr expr = (VariableDeclarationExpr) n.getExpression();
                    return isReachable(n);
                }
                // An expression statement can complete normally iff it is reachable.
                return isReachable(n);
            }
        };
        return statement.accept(visitor, null);
    }


@Deprecated
    public SymbolReference<ResolvedTypeDeclaration> solveTypeInType(ResolvedTypeDeclaration typeDeclaration, String name) {
        if (typeDeclaration instanceof JavaParserClassDeclaration) {
            return ((JavaParserClassDeclaration) typeDeclaration).solveType(name, typeSolver);
        }
        if (typeDeclaration instanceof JavaParserInterfaceDeclaration) {
            return ((JavaParserInterfaceDeclaration) typeDeclaration).solveType(name, typeSolver);
        }
        return SymbolReference.unsolved(ResolvedReferenceTypeDeclaration.class);
    }

@ Deprecated public SymbolReference < ResolvedTypeDeclaration > solveTypeInType ( ResolvedTypeDeclaration typeDeclaration , String name ) { if ( typeDeclaration instanceof JavaParserClassDeclaration ) { return ( ( JavaParserClassDeclaration ) typeDeclaration ) . solveType ( name , typeSolver ) ; } if ( typeDeclaration instanceof JavaParserInterfaceDeclaration ) { return ( ( JavaParserInterfaceDeclaration ) typeDeclaration ) . solveType ( name , typeSolver ) ; } return SymbolReference . unsolved ( ResolvedReferenceTypeDeclaration . class ) ; }

Try to solve a symbol just in the declaration, it does not delegate to the container.

Try to solve a symbol just in the declaration it does not delegate to the container .


public static SymbolReference<ResolvedMethodDeclaration> solveMethodInType(ResolvedTypeDeclaration typeDeclaration,
                                                                               String name, List<ResolvedType> argumentsTypes, boolean staticOnly,
                                                                               TypeSolver typeSolver) {
        if (typeDeclaration instanceof JavaParserClassDeclaration) {
            Context ctx = ((JavaParserClassDeclaration) typeDeclaration).getContext();
            return ctx.solveMethod(name, argumentsTypes, staticOnly, typeSolver);
        }
        if (typeDeclaration instanceof JavaParserInterfaceDeclaration) {
            Context ctx = ((JavaParserInterfaceDeclaration) typeDeclaration).getContext();
            return ctx.solveMethod(name, argumentsTypes, staticOnly, typeSolver);
        }
        if (typeDeclaration instanceof JavaParserEnumDeclaration) {
            if (name.equals("values") && argumentsTypes.isEmpty()) {
                return SymbolReference.solved(new JavaParserEnumDeclaration.ValuesMethod((JavaParserEnumDeclaration) typeDeclaration, typeSolver));
            }
            Context ctx = ((JavaParserEnumDeclaration) typeDeclaration).getContext();
            return ctx.solveMethod(name, argumentsTypes, staticOnly, typeSolver);
        }
        if (typeDeclaration instanceof JavaParserAnonymousClassDeclaration) {
        	Context ctx = ((JavaParserAnonymousClassDeclaration) typeDeclaration).getContext();
            return ctx.solveMethod(name, argumentsTypes, staticOnly, typeSolver);
        }
        if (typeDeclaration instanceof ReflectionClassDeclaration) {
            return ((ReflectionClassDeclaration) typeDeclaration).solveMethod(name, argumentsTypes, staticOnly);
        }
        if (typeDeclaration instanceof ReflectionInterfaceDeclaration) {
          return ((ReflectionInterfaceDeclaration) typeDeclaration).solveMethod(name, argumentsTypes, staticOnly);
        }
          if (typeDeclaration instanceof ReflectionEnumDeclaration) {
            return ((ReflectionEnumDeclaration) typeDeclaration).solveMethod(name, argumentsTypes, staticOnly);
        }
        if (typeDeclaration instanceof JavassistInterfaceDeclaration) {
            return ((JavassistInterfaceDeclaration) typeDeclaration).solveMethod(name, argumentsTypes, staticOnly);
        }
        if (typeDeclaration instanceof JavassistClassDeclaration) {
          return ((JavassistClassDeclaration) typeDeclaration).solveMethod(name, argumentsTypes, staticOnly);
        }
          if (typeDeclaration instanceof JavassistEnumDeclaration) {
            return ((JavassistEnumDeclaration) typeDeclaration).solveMethod(name, argumentsTypes, staticOnly);
        }
        throw new UnsupportedOperationException(typeDeclaration.getClass().getCanonicalName());
    }

public static SymbolReference < ResolvedMethodDeclaration > solveMethodInType ( ResolvedTypeDeclaration typeDeclaration , String name , List < ResolvedType > argumentsTypes , boolean staticOnly , TypeSolver typeSolver ) { if ( typeDeclaration instanceof JavaParserClassDeclaration ) { Context ctx = ( ( JavaParserClassDeclaration ) typeDeclaration ) . getContext ( ) ; return ctx . solveMethod ( name , argumentsTypes , staticOnly , typeSolver ) ; } if ( typeDeclaration instanceof JavaParserInterfaceDeclaration ) { Context ctx = ( ( JavaParserInterfaceDeclaration ) typeDeclaration ) . getContext ( ) ; return ctx . solveMethod ( name , argumentsTypes , staticOnly , typeSolver ) ; } if ( typeDeclaration instanceof JavaParserEnumDeclaration ) { if ( name . equals ( "values" ) && argumentsTypes . isEmpty ( ) ) { return SymbolReference . solved ( new JavaParserEnumDeclaration . ValuesMethod ( ( JavaParserEnumDeclaration ) typeDeclaration , typeSolver ) ) ; } Context ctx = ( ( JavaParserEnumDeclaration ) typeDeclaration ) . getContext ( ) ; return ctx . solveMethod ( name , argumentsTypes , staticOnly , typeSolver ) ; } if ( typeDeclaration instanceof JavaParserAnonymousClassDeclaration ) { Context ctx = ( ( JavaParserAnonymousClassDeclaration ) typeDeclaration ) . getContext ( ) ; return ctx . solveMethod ( name , argumentsTypes , staticOnly , typeSolver ) ; } if ( typeDeclaration instanceof ReflectionClassDeclaration ) { return ( ( ReflectionClassDeclaration ) typeDeclaration ) . solveMethod ( name , argumentsTypes , staticOnly ) ; } if ( typeDeclaration instanceof ReflectionInterfaceDeclaration ) { return ( ( ReflectionInterfaceDeclaration ) typeDeclaration ) . solveMethod ( name , argumentsTypes , staticOnly ) ; } if ( typeDeclaration instanceof ReflectionEnumDeclaration ) { return ( ( ReflectionEnumDeclaration ) typeDeclaration ) . solveMethod ( name , argumentsTypes , staticOnly ) ; } if ( typeDeclaration instanceof JavassistInterfaceDeclaration ) { return ( ( JavassistInterfaceDeclaration ) typeDeclaration ) . solveMethod ( name , argumentsTypes , staticOnly ) ; } if ( typeDeclaration instanceof JavassistClassDeclaration ) { return ( ( JavassistClassDeclaration ) typeDeclaration ) . solveMethod ( name , argumentsTypes , staticOnly ) ; } if ( typeDeclaration instanceof JavassistEnumDeclaration ) { return ( ( JavassistEnumDeclaration ) typeDeclaration ) . solveMethod ( name , argumentsTypes , staticOnly ) ; } throw new UnsupportedOperationException ( typeDeclaration . getClass ( ) . getCanonicalName ( ) ) ; }

Replace TypeDeclaration.solveMethod

@param typeDeclaration
@param name
@param argumentsTypes
@param staticOnly
@return


public static Value from(ResolvedValueDeclaration decl) {
        ResolvedType type = decl.getType();
        return new Value(type, decl.getName());
    }

public static Value from ( ResolvedValueDeclaration decl ) { ResolvedType type = decl . getType ( ) ; return new Value ( type , decl . getName ( ) ) ; }

Create a Value from a ValueDeclaration .


public boolean invocationApplicabilityInference(MethodCallExpr methodCallExpr, ResolvedMethodDeclaration methodDeclaration) {
        if (!methodCallExpr.getNameAsString().equals(methodDeclaration.getName())) {
            throw new IllegalArgumentException();
        }
        Optional<InstantiationSet> partial = instantiationInference(methodCallExpr, methodDeclaration);
        if (!partial.isPresent()) {
            return false;
        }
        int nActualParams = methodCallExpr.getArguments().size();
        int nFormalParams = methodDeclaration.getNumberOfParams();
        if (nActualParams != nFormalParams) {
            if (methodDeclaration.hasVariadicParameter()) {
                if (nActualParams < (nFormalParams - 1)) {
                    return false;
                }
            } else {
                return false;
            }
        }
        //MethodUsage methodUsage = instantiationSetToMethodUsage(methodDeclaration, partial.get());
//        for (int i=0;i<nActualParams;i++) {
//            int formalIndex = i >= nFormalParams ? nFormalParams - 1 : i;
//            Type formalType = methodDeclaration.getParam(formalIndex).getType();
//            Type actualType = JavaParserFacade.get(typeSolver).getType(methodCallExpr.getArgument(i));
//            //if (!formalType.isAssignableBy(actualType)) {
//            //    return false;
//            //}
//        }
        return true;
    }

//        for (int i=0;i<nActualParams;i++) {

Determine whether a potentially applicable generic method m is applicable for a method invocation that
provides no explicit type arguments.

Determine whether a potentially applicable generic method m is applicable for a method invocation that provides no explicit type arguments .


public boolean moreSpecificMethodInference(MethodCallExpr methodCall, ResolvedMethodDeclaration m1, ResolvedMethodDeclaration m2) {
        // When testing that one applicable method is more specific than another (§15.12.2.5), where the second method
        // is generic, it is necessary to test whether some instantiation of the second method's type parameters can be
        // inferred to make the first method more specific than the second.

        if (!m2.isGeneric()) {
            throw new IllegalArgumentException("M2 is not generic (m2: " + m2 + ")");
        }

        // Let m1 be the first method and m2 be the second method. Where m2 has type parameters P1, ..., Pp,
        // let α1, ..., αp be inference variables, and let θ be the substitution [P1:=α1, ..., Pp:=αp].
        //
        // Let e1, ..., ek be the argument expressions of the corresponding invocation. Then:
        //
        // - If m1 and m2 are applicable by strict or loose invocation (§15.12.2.2, §15.12.2.3), then let S1, ..., Sk be the formal parameter types of m1, and let T1, ..., Tk be the result of θ applied to the formal parameter types of m2.
        //
        // - If m1 and m2 are applicable by variable arity invocation (§15.12.2.4), then let S1, ..., Sk be the first k variable arity parameter types of m1, and let T1, ..., Tk be the result of θ applied to the first k variable arity parameter types of m2.
        //
        // Note that no substitution is applied to S1, ..., Sk; even if m1 is generic, the type parameters of m1 are treated as type variables, not inference variables.
        //
        // The process to determine if m1 is more specific than m2 is as follows:
        //
        // - First, an initial bound set, B, is constructed from the declared bounds of P1, ..., Pp, as specified in §18.1.3.
        //
        // - Second, for all i (1 ≤ i ≤ k), a set of constraint formulas or bounds is generated.
        //
        //   If Ti is a proper type, the result is true if Si is more specific than Ti for ei (§15.12.2.5), and false otherwise. (Note that Si is always a proper type.)
        //
        //   Otherwise, if Ti is not a functional interface type, the constraint formula ‹Si <: Ti› is generated.
        //
        //   Otherwise, Ti is a parameterization of a functional interface, I. It must be determined whether Si satisfies the following five conditions:
        //
        //   1. Si is a functional interface type.
        //
        //   2. Si is not a superinterface of I, nor a parameterization of a superinterface of I.
        //
        //   3. Si is not a subinterface of I, nor a parameterization of a subinterface of I.
        //
        //   4. If Si is an intersection type, at least one element of the intersection is not a superinterface of I, nor a parameterization of a superinterface of I.
        //
        //   5. If Si is an intersection type, no element of the intersection is a subinterface of I, nor a parameterization of a subinterface of I.
        //
        //   If all five conditions are true, then the following constraint formulas or bounds are generated (where U1 ... Uk and R1 are the parameter types and return type of the function type of the capture of Si, and V1 ... Vk and R2 are the parameter types and return type of the function type of Ti):
        //
        //   - If ei is an explicitly typed lambda expression:
        //
        //     - For all j (1 ≤ j ≤ k), ‹Uj = Vj›.
        //
        //     - If R2 is void, true.
        //
        //     - Otherwise, if R1 and R2 are functional interface types, and neither interface is a subinterface of the other, and ei has at least one result expression, then these rules are applied recursively to R1 and R2, for each result expression in ei.
        //
        //     - Otherwise, if R1 is a primitive type and R2 is not, and ei has at least one result expression, and each result expression of ei is a standalone expression (§15.2) of a primitive type, true.
        //
        //     - Otherwise, if R2 is a primitive type and R1 is not, and ei has at least one result expression, and each result expression of ei is either a standalone expression of a reference type or a poly expression, true.
        //
        //     - Otherwise, ‹R1 <: R2›.
        //
        //   - If ei is an exact method reference:
        //
        //     - For all j (1 ≤ j ≤ k), ‹Uj = Vj›.
        //
        //     - If R2 is void, true.
        //
        //     - Otherwise, if R1 is a primitive type and R2 is not, and the compile-time declaration for ei has a primitive return type, true.
        //
        //     - Otherwise if R2 is a primitive type and R1 is not, and the compile-time declaration for ei has a reference return type, true.
        //
        //     - Otherwise, ‹R1 <: R2›.
        //
        //   - If ei is a parenthesized expression, these rules are applied recursively to the contained expression.
        //
        //   - If ei is a conditional expression, these rules are applied recursively to each of the second and third operands.
        //
        //   - Otherwise, false.
        //
        //   If the five constraints on Si are not satisfied, the constraint formula ‹Si <: Ti› is generated instead.
        //
        // - Third, if m2 is applicable by variable arity invocation and has k+1 parameters, then where Sk+1 is the k+1'th variable arity parameter type of m1 and Tk+1 is the result of θ applied to the k+1'th variable arity parameter type of m2, the constraint ‹Sk+1 <: Tk+1› is generated.
        //
        // - Fourth, the generated bounds and constraint formulas are reduced and incorporated with B to produce a bound set B'.
        //
        //   If B' does not contain the bound false, and resolution of all the inference variables in B' succeeds, then m1 is more specific than m2.
        //
        //   Otherwise, m1 is not more specific than m2.

        throw new UnsupportedOperationException();
    }

//     - For all j (1 ≤ j ≤ k), ‹Uj = Vj›.

Return if m2 is more specific than m1
@param methodCall
@param m1
@param m2


private static boolean appearsInAssignmentContext(Expression expression) {
        if (expression.getParentNode().isPresent()) {
            Node parent = expression.getParentNode().get();
            if (parent instanceof ExpressionStmt) {
                return false;
            }
            if (parent instanceof MethodCallExpr) {
                return false;
            }
            if (parent instanceof ReturnStmt) {
                return false;
            }
            throw new UnsupportedOperationException(parent.getClass().getCanonicalName());
        }
        return false;
    }

private static boolean appearsInAssignmentContext ( Expression expression ) { if ( expression . getParentNode ( ) . isPresent ( ) ) { Node parent = expression . getParentNode ( ) . get ( ) ; if ( parent instanceof ExpressionStmt ) { return false ; } if ( parent instanceof MethodCallExpr ) { return false ; } if ( parent instanceof ReturnStmt ) { return false ; } throw new UnsupportedOperationException ( parent . getClass ( ) . getCanonicalName ( ) ) ; } return false ; }

Not sure if should look if the parent is an assignment context


public float[] predict(FVec feat, boolean output_margin, int ntree_limit) {
        float[] preds = predictRaw(feat, ntree_limit);
        if (! output_margin) {
            preds = obj.predTransform(preds);
        }
        return preds;
    }

public float [ ] predict ( FVec feat , boolean output_margin , int ntree_limit ) { float [ ] preds = predictRaw ( feat , ntree_limit ) ; if ( ! output_margin ) { preds = obj . predTransform ( preds ) ; } return preds ; }

Generates predictions for given feature vector.

@param feat          feature vector
@param output_margin whether to only predict margin value instead of transformed prediction
@param ntree_limit   limit the number of trees used in prediction
@return prediction values

Generates predictions for given feature vector .


public void loadModel(ModelReader reader) throws IOException {
        param = new Param(reader);

        nodes = new Node[param.num_nodes];
        for (int i = 0; i < param.num_nodes; i++) {
            nodes[i] = new Node(reader);
        }

        stats = new RTreeNodeStat[param.num_nodes];
        for (int i = 0; i < param.num_nodes; i++) {
            stats[i] = new RTreeNodeStat(reader);
        }
    }

public void loadModel ( ModelReader reader ) throws IOException { param = new Param ( reader ) ; nodes = new Node [ param . num_nodes ] ; for ( int i = 0 ; i < param . num_nodes ; i ++ ) { nodes [ i ] = new Node ( reader ) ; } stats = new RTreeNodeStat [ param . num_nodes ] ; for ( int i = 0 ; i < param . num_nodes ; i ++ ) { stats [ i ] = new RTreeNodeStat ( reader ) ; } }

Loads model from stream.

@param reader input stream
@throws IOException If an I/O error occurs


@Override
    public int getLeafIndex(FVec feat, int root_id) {
        int pid = root_id;

        Node n;
        while (!(n = nodes[pid])._isLeaf) {
            pid = n.next(feat);
        }

        return pid;
    }

@ Override public int getLeafIndex ( FVec feat , int root_id ) { int pid = root_id ; Node n ; while ( ! ( n = nodes [ pid ] ) . _isLeaf ) { pid = n . next ( feat ) ; } return pid ; }

Retrieves nodes from root to leaf and returns leaf index.

@param feat    feature vector
@param root_id starting root index
@return leaf index

Retrieves nodes from root to leaf and returns leaf index .


@Override
    public float getLeafValue(FVec feat, int root_id) {
        Node n = nodes[root_id];
        while (!n._isLeaf) {
            n = nodes[n.next(feat)];
        }

        return n.leaf_value;
    }

@ Override public float getLeafValue ( FVec feat , int root_id ) { Node n = nodes [ root_id ] ; while ( ! n . _isLeaf ) { n = nodes [ n . next ( feat ) ] ; } return n . leaf_value ; }

Retrieves nodes from root to leaf and returns leaf value.

@param feat    feature vector
@param root_id starting root index
@return leaf value

Retrieves nodes from root to leaf and returns leaf value .


public String unflatten() {
    StringWriter sw = new StringWriter();
    if (root.isArray()) {
      try {
        unflattenArray(root.asArray()).writeTo(sw, getWriterConfig());
      } catch (IOException e) {}
      return sw.toString();
    }
    if (!root.isObject()) {
      return root.toString();
    }

    JsonObject flattened = root.asObject();
    JsonValue unflattened = flattened.names().isEmpty() ? Json.object() : null;

    for (String key : flattened.names()) {
      JsonValue currentVal = unflattened;
      String objKey = null;
      Integer aryIdx = null;

      Matcher matcher = keyPartPattern().matcher(key);
      while (matcher.find()) {
        String keyPart = matcher.group();

        if (objKey != null ^ aryIdx != null) {
          if (isJsonArray(keyPart)) {
            currentVal = findOrCreateJsonArray(currentVal, objKey, aryIdx);
            objKey = null;
            aryIdx = extractIndex(keyPart);
          } else { // JSON object
            if (flattened.get(key).isArray()) { // KEEP_ARRAYS mode
              flattened.set(key, unflattenArray(flattened.get(key).asArray()));
            }
            currentVal = findOrCreateJsonObject(currentVal, objKey, aryIdx);
            objKey = extractKey(keyPart);
            aryIdx = null;
          }
        }

        if (objKey == null && aryIdx == null) {
          if (isJsonArray(keyPart)) {
            aryIdx = extractIndex(keyPart);
            if (currentVal == null) currentVal = Json.array();
          } else { // JSON object
            objKey = extractKey(keyPart);
            if (currentVal == null) currentVal = Json.object();
          }
        }

        if (unflattened == null) unflattened = currentVal;
      }

      setUnflattenedValue(flattened, key, currentVal, objKey, aryIdx);
    }

    try {
      unflattened.writeTo(sw, getWriterConfig());
    } catch (IOException e) {}
    return sw.toString();
  }

public
String
unflatten
(
)
{
StringWriter
sw
=
new
StringWriter
(
)
;
if
(
root
.
isArray
(
)
)
{
try
{
unflattenArray
(
root
.
asArray
(
)
)
.
writeTo
(
sw
,
getWriterConfig
(
)
)
;
}
catch
(
IOException
e
)
{
}
return
sw
.
toString
(
)
;
}
if
(
!
root
.
isObject
(
)
)
{
return
root
.
toString
(
)
;
}
JsonObject
flattened
=
root
.
asObject
(
)
;
JsonValue
unflattened
=
flattened
.
names
(
)
.
isEmpty
(
)
Json
.
object
(
)
:
;
for
(
String
key
:
flattened
.
names
(
)
)
{
JsonValue
currentVal
=
unflattened
;
String
objKey
=
;
Integer
aryIdx
=
;
Matcher
matcher
=
keyPartPattern
(
)
.
matcher
(
key
)
;
while
(
matcher
.
find
(
)
)
{
String
keyPart
=
matcher
.
group
(
)
;
if
(
objKey
!=
^
aryIdx
!=
)
{
if
(
isJsonArray
(
keyPart
)
)
{
currentVal
=
findOrCreateJsonArray
(
currentVal
,
objKey
,
aryIdx
)
;
objKey
=
;
aryIdx
=
extractIndex
(
keyPart
)
;
}
else
{
// JSON object
if
(
flattened
.
get
(
key
)
.
isArray
(
)
)
{
// KEEP_ARRAYS mode
flattened
.
set
(
key
,
unflattenArray
(
flattened
.
get
(
key
)
.
asArray
(
)
)
)
;
}
currentVal
=
findOrCreateJsonObject
(
currentVal
,
objKey
,
aryIdx
)
;
objKey
=
extractKey
(
keyPart
)
;
aryIdx
=
;
}
}
if
(
objKey
==
&&
aryIdx
==
)
{
if
(
isJsonArray
(
keyPart
)
)
{
aryIdx
=
extractIndex
(
keyPart
)
;
if
(
currentVal
==
)
currentVal
=
Json
.
array
(
)
;
}
else
{
// JSON object
objKey
=
extractKey
(
keyPart
)
;
if
(
currentVal
==
)
currentVal
=
Json
.
object
(
)
;
}
}
if
(
unflattened
==
)
unflattened
=
currentVal
;
}
setUnflattenedValue
(
flattened
,
key
,
currentVal
,
objKey
,
aryIdx
)
;
}
try
{
unflattened
.
writeTo
(
sw
,
getWriterConfig
(
)
)
;
}
catch
(
IOException
e
)
{
}
return
sw
.
toString
(
)
;
}

Returns a JSON string of nested objects by the given flattened JSON string.

@return a JSON string of nested objects

Returns a JSON string of nested objects by the given flattened JSON string .


public String flatten() {
    flattenAsMap();

    if (source.isObject() || isObjectifiableArray())
      return flattenedMap.toString(printMode);
    else
      return javaObj2Json(flattenedMap.get(ROOT));
  }

public String flatten ( ) { flattenAsMap ( ) ; if ( source . isObject ( ) || isObjectifiableArray ( ) ) return flattenedMap . toString ( printMode ) ; else return javaObj2Json ( flattenedMap . get ( ROOT ) ) ; }

Returns a flattened JSON string.

@return a flattened JSON string


public Map<String, Object> flattenAsMap() {
    if (flattenedMap != null) return flattenedMap;

    flattenedMap = newJsonifyLinkedHashMap();
    reduce(source);

    while (!elementIters.isEmpty()) {
      IndexedPeekIterator<?> deepestIter = elementIters.getLast();
      if (!deepestIter.hasNext()) {
        elementIters.removeLast();
      } else if (deepestIter.peek() instanceof Member) {
        Member mem = (Member) deepestIter.next();
        reduce(mem.getValue());
      } else { // JsonValue
        JsonValue val = (JsonValue) deepestIter.next();
        reduce(val);
      }
    }

    return flattenedMap;
  }

public
Map
<
String
,
Object
>
flattenAsMap
(
)
{
if
(
flattenedMap
!=
)
return
flattenedMap
;
flattenedMap
=
newJsonifyLinkedHashMap
(
)
;
reduce
(
source
)
;
while
(
!
elementIters
.
isEmpty
(
)
)
{
IndexedPeekIterator
<
>
deepestIter
=
elementIters
.
getLast
(
)
;
if
(
!
deepestIter
.
hasNext
(
)
)
{
elementIters
.
removeLast
(
)
;
}
else
if
(
deepestIter
.
peek
(
)
instanceof
Member
)
{
Member
mem
=
(
Member
)
deepestIter
.
next
(
)
;
reduce
(
mem
.
getValue
(
)
)
;
}
else
{
// JsonValue
JsonValue
val
=
(
JsonValue
)
deepestIter
.
next
(
)
;
reduce
(
val
)
;
}
}
return
flattenedMap
;
}

Returns a flattened JSON as Map.

@return a flattened JSON as Map


public static <E> List<E> concatView(List<List<? extends E>> lists) {
        if(lists.isEmpty()) {
            return Collections.emptyList();
        } else {
            return ConcatView.create(lists);
        }
    }

public static < E > List < E > concatView ( List < List < ? extends E > > lists ) { if ( lists . isEmpty ( ) ) { return Collections . emptyList ( ) ; } else { return ConcatView . create ( lists ) ; } }

Returns a list that is a concatenation of the given lists. The returned
list is a view of the underlying lists, without copying the elements.
The returned list is unmodifiable. Modifications to underlying lists
will be visible through the concatenation view.

Returns a list that is a concatenation of the given lists . The returned list is a view of the underlying lists without copying the elements . The returned list is unmodifiable . Modifications to underlying lists will be visible through the concatenation view .


public static EventStream<Void> invalidationsOf(Observable observable) {
        return new EventStreamBase<Void>() {
            @Override
            protected Subscription observeInputs() {
                InvalidationListener listener = obs -> emit(null);
                observable.addListener(listener);
                return () -> observable.removeListener(listener);
            }
        };
    }

public static EventStream < Void > invalidationsOf ( Observable observable ) { return new EventStreamBase < Void > ( ) { @ Override protected Subscription observeInputs ( ) { InvalidationListener listener = obs -> emit ( null ) ; observable . addListener ( listener ) ; return ( ) -> observable . removeListener ( listener ) ; } } ; }

Creates an event stream that emits an impulse on every invalidation
of the given observable.

Creates an event stream that emits an impulse on every invalidation of the given observable .


public static <O extends Observable>
    EventStream<O> repeatOnInvalidation(O observable) {
        return new EventStreamBase<O>() {
            @Override
            protected Subscription observeInputs() {
                InvalidationListener listener = obs -> emit(observable);
                observable.addListener(listener);
                return () -> observable.removeListener(listener);
            }

            @Override
            protected void newObserver(Consumer<? super O> subscriber) {
                subscriber.accept(observable);
            }
        };
    }

public static < O extends Observable > EventStream < O > repeatOnInvalidation ( O observable ) { return new EventStreamBase < O > ( ) { @ Override protected Subscription observeInputs ( ) { InvalidationListener listener = obs -> emit ( observable ) ; observable . addListener ( listener ) ; return ( ) -> observable . removeListener ( listener ) ; } @ Override protected void newObserver ( Consumer < ? super O > subscriber ) { subscriber . accept ( observable ) ; } } ; }

Creates an event stream that emits the given observable immediately for
every subscriber and re-emits it on every subsequent invalidation of the
observable.

Creates an event stream that emits the given observable immediately for every subscriber and re - emits it on every subsequent invalidation of the observable .


public static EventStream<Long> animationFrames() {
        return animationTicks()
                .accumulate(t(0L, -1L), (state, now) -> state.map((d, last) -> {
                        return t(last == -1L ? 0L : now - last, now);
                }))
                .map(t -> t._1);
    }

public static EventStream < Long > animationFrames ( ) { return animationTicks ( ) . accumulate ( t ( 0L , - 1L ) , ( state , now ) -> state . map ( ( d , last ) -> { return t ( last == - 1L ? 0L : now - last , now ) ; } ) ) . map ( t -> t . _1 ) ; }

Returns a stream that, on each animation frame, emits the duration
elapsed since the previous animation frame, in nanoseconds.

Returns a stream that on each animation frame emits the duration elapsed since the previous animation frame in nanoseconds .


public static <T> EventStream<T> merge(
            ObservableSet<? extends EventStream<T>> set) {
        return new EventStreamBase<T>() {
            @Override
            protected Subscription observeInputs() {
                return Subscription.dynamic(set, s -> s.subscribe(this::emit));
            }
        };
    }

public static < T > EventStream < T > merge ( ObservableSet < ? extends EventStream < T > > set ) { return new EventStreamBase < T > ( ) { @ Override protected Subscription observeInputs ( ) { return Subscription . dynamic ( set , s -> s . subscribe ( this :: emit ) ) ; } } ; }

Returns an event stream that emits all the events emitted from any of
the event streams in the given observable set. When an event stream is
added to the set, the returned stream will start emitting its events.
When an event stream is removed from the set, its events will no longer
be emitted from the returned stream.

Returns an event stream that emits all the events emitted from any of the event streams in the given observable set . When an event stream is added to the set the returned stream will start emitting its events . When an event stream is removed from the set its events will no longer be emitted from the returned stream .


@Deprecated
    public static <E> ObservableList<E> wrap(javafx.collections.ObservableList<E> delegate) {
        return LiveList.suspendable(delegate);
    }

@ Deprecated public static < E > ObservableList < E > wrap ( javafx . collections . ObservableList < E > delegate ) { return LiveList . suspendable ( delegate ) ; }

Creates an ObservableList wrapper that is able to temporarily block
list change notifications.
@param delegate the underlying observable list.
@deprecated Use {@link LiveList#suspendable(javafx.collections.ObservableList)} instead.

Creates an ObservableList wrapper that is able to temporarily block list change notifications .


public <T> T onWhile(Supplier<T> f) {
        try(Guard g = on()) {
            return f.get();
        }
    }

public < T > T onWhile ( Supplier < T > f ) { try ( Guard g = on ( ) ) { return f . get ( ) ; } }

Runs the given computation, making sure this indicator is on.
When done, this indicator is reset to the previous state.

T t = indicator.onWhile(f);

is equivalent to

T t;
try(Guard g = on()) {
t = f.get();
}

Runs the given computation making sure this indicator is on . When done this indicator is reset to the previous state .


@Override
    public final Subscription observe(O observer) {
        P adapted = adaptObserver(observer);
        underlying.addObserver(adapted);
        return () -> underlying.removeObserver(adapted);
    }

@ Override public final Subscription observe ( O observer ) { P adapted = adaptObserver ( observer ) ; underlying . addObserver ( adapted ) ; return ( ) -> underlying . removeObserver ( adapted ) ; }

Overridden to avoid second transformation on removeObserver


public Metadata copy()
   {
      Metadata result = new Metadata();
      result.setEncoding(encoding);
      result.setTrailingSlash(trailingSlash);
      result.setLeadingSlash(leadingSlash);
      return result;
   }

public Metadata copy ( ) { Metadata result = new Metadata ( ) ; result . setEncoding ( encoding ) ; result . setTrailingSlash ( trailingSlash ) ; result . setLeadingSlash ( leadingSlash ) ; return result ; }


protected String stripKnownPrefix(String str, String prefix)
   {

      int startIndex = str.lastIndexOf(prefix);
      if (startIndex != -1)
      {
         return str.substring(startIndex + prefix.length());
      }

      return null;
   }

protected String stripKnownPrefix ( String str , String prefix ) { int startIndex = str . lastIndexOf ( prefix ) ; if ( startIndex != - 1 ) { return str . substring ( startIndex + prefix . length ( ) ) ; } return null ; }

Strip everything up to and including a given prefix from a string.

@param str The string to process
@param prefix The prefix
@return the stripped string or null if the prefix has not been found

Strip everything up to and including a given prefix from a string .


private Digester configureDigester(final Digester digester)
   {

      /*
       * We use the context class loader to resolve classes. This fixes
       * ClassNotFoundExceptions on Geronimo.
       */
      digester.setUseContextClassLoader(true);

      /*
       * Parse RewriteRules
       */
      digester.addObjectCreate("pretty-config/rewrite", RewriteRule.class);
      digester.addSetProperties("pretty-config/rewrite");
      digester.addSetNext("pretty-config/rewrite", "addRewriteRule");

      /*
       * Create Mapping Object
       */
      digester.addObjectCreate("pretty-config/url-mapping", UrlMapping.class);
      digester.addSetProperties("pretty-config/url-mapping");
      digester.addCallMethod("pretty-config/url-mapping/pattern", "setPattern", 1);
      digester.addCallParam("pretty-config/url-mapping/pattern", 0, "value");
      digester.addCallMethod("pretty-config/url-mapping/pattern", "setPattern", 0);

      /*
       * Parse View Id
       */
      digester.addCallMethod("pretty-config/url-mapping/view-id", "setViewId", 1);
      digester.addCallParam("pretty-config/url-mapping/view-id", 0, "value");
      digester.addCallMethod("pretty-config/url-mapping/view-id", "setViewId", 0);

      /*
       * Parse Path Validators
       */
      digester.addObjectCreate("pretty-config/url-mapping/pattern/validate", PathValidator.class);
      digester.addSetProperties("pretty-config/url-mapping/pattern/validate");
      digester.addSetNext("pretty-config/url-mapping/pattern/validate", "addPathValidator");

      /*
       * Parse Query Params
       */
      digester.addObjectCreate("pretty-config/url-mapping/query-param", QueryParameter.class);
      digester.addSetProperties("pretty-config/url-mapping/query-param");
      digester.addCallMethod("pretty-config/url-mapping/query-param", "setExpression", 0);
      digester.addSetNext("pretty-config/url-mapping/query-param", "addQueryParam");

      /*
       * Parse Action Methods
       */
      digester.addObjectCreate("pretty-config/url-mapping/action", UrlAction.class);
      digester.addSetProperties("pretty-config/url-mapping/action");
      digester.addCallMethod("pretty-config/url-mapping/action", "setAction", 0);
      digester.addSetNext("pretty-config/url-mapping/action", "addAction");

      /*
       * Add Mapping to Builder
       */
      digester.addSetNext("pretty-config/url-mapping", "addMapping");
      return digester;
   }

/*
       * Parse RewriteRules
       */

/*
       * Create Mapping Object
       */

/*
       * Parse Path Validators
       */

/*
       * Parse Query Params
       */

/*
       * Parse Action Methods
       */

/*
       * Add Mapping to Builder
       */

Configure the digester. Assume that the builder object will be pushed
after this method is called.

Configure the digester . Assume that the builder object will be pushed after this method is called .


public String[] processClassMappingAnnotations(Class<?> clazz)
   {

      // list of all mapping IDs found on the class
      List<String> classMappingIds = new ArrayList<String>();

      // get reference to @URLMapping annotation
      URLMapping mappingAnnotation = (URLMapping) clazz.getAnnotation(URLMapping.class);

      // process annotation if it exists
      if (mappingAnnotation != null)
      {
         String mappingId = processPrettyMappingAnnotation(clazz, mappingAnnotation);
         classMappingIds.add(mappingId);
      }

      // container annotation
      URLMappings mappingsAnnotation = (URLMappings) clazz.getAnnotation(URLMappings.class);

      if (mappingsAnnotation != null)
      {

         // process all contained @URLMapping annotations
         for (URLMapping child : mappingsAnnotation.mappings())
         {
            String mappingId = processPrettyMappingAnnotation(clazz, child);
            classMappingIds.add(mappingId);
         }

      }

      // return list of mappings found
      return classMappingIds.toArray(new String[classMappingIds.size()]);

   }

Checks for PrettyFaces mapping annotations on a single class

@param clazz Class to scan
@return The IDs of the mappings found on the class


private static String join(String[] values, String separator)
   {
      StringBuilder result = new StringBuilder();
      if (values != null)
      {
         for (int i = 0; i < values.length; i++)
         {
            if (i > 0)
            {
               result.append(separator);
            }
            result.append(values[i]);
         }
      }
      return result.toString();
   }

private static String join ( String [ ] values , String separator ) { StringBuilder result = new StringBuilder ( ) ; if ( values != null ) { for ( int i = 0 ; i < values . length ; i ++ ) { if ( i > 0 ) { result . append ( separator ) ; } result . append ( values [ i ] ) ; } } return result . toString ( ) ; }

Joins the list of values.

@param values values to join
@param separator the separator to use
@return joined list of values


public void initDeviceScan()
   {
      // Save these properties to speed processing
      this.isWebkit = detectWebkit();
      this.isIphone = detectIphone();
      this.isAndroid = detectAndroid();
      this.isAndroidPhone = detectAndroidPhone();

      // Generally, these tiers are the most useful for web development
      this.isMobilePhone = detectMobileQuick();
      this.isTierTablet = detectTierTablet();
      this.isTierIphone = detectTierIphone();

      // Optional: Comment these out if you NEVER use them
      this.isTierRichCss = detectTierRichCss();
      this.isTierGenericMobile = detectTierOtherPhones();

      this.initCompleted = true;
   }


public boolean detectIphone()
   {
      if ((this.initCompleted == true) ||
               (this.isIphone == true))
         return this.isIphone;

      // The iPad and iPod touch say they're an iPhone! So let's disambiguate.
      if (userAgent.indexOf(deviceIphone) != -1 &&
               !detectIpad() &&
               !detectIpod()) {
         return true;
      }
      return false;
   }

Detects if the current device is an iPhone.

@return detection of an iPhone

Detects if the current device is an iPhone .


public boolean detectWebkit()
   {
      if ((this.initCompleted == true) ||
               (this.isWebkit == true))
         return this.isWebkit;

      if (userAgent.indexOf(engineWebKit) != -1) {
         return true;
      }
      return false;
   }

public boolean detectWebkit ( ) { if ( ( this . initCompleted == true ) || ( this . isWebkit == true ) ) return this . isWebkit ; if ( userAgent . indexOf ( engineWebKit ) != - 1 ) { return true ; } return false ; }

Detects if the current browser is based on WebKit.

@return detection of a WebKit browser

Detects if the current browser is based on WebKit .


public boolean detectWindowsMobile()
   {
      if (detectWindowsPhone()) {
         return false;
      }
      // Most devices use 'Windows CE', but some report 'iemobile'
      // and some older ones report as 'PIE' for Pocket IE.
      // We also look for instances of HTC and Windows for many of their WinMo devices.
      if (userAgent.indexOf(deviceWinMob) != -1
               || userAgent.indexOf(deviceWinMob) != -1
               || userAgent.indexOf(deviceIeMob) != -1
               || userAgent.indexOf(enginePie) != -1
               || (userAgent.indexOf(manuHtc) != -1 && userAgent.indexOf(deviceWindows) != -1)
               || (detectWapWml() && userAgent.indexOf(deviceWindows) != -1)) {
         return true;
      }

      // Test for Windows Mobile PPC but not old Macintosh PowerPC.
      if (userAgent.indexOf(devicePpc) != -1 &&
               !(userAgent.indexOf(deviceMacPpc) != -1))
         return true;

      return false;
   }

Detects if the current browser is a Windows Mobile device. Excludes Windows Phone 7.x and 8 devices. Focuses on
Windows Mobile 6.xx and earlier.

@return detection of Windows Mobile

Detects if the current browser is a Windows Mobile device . Excludes Windows Phone 7 . x and 8 devices . Focuses on Windows Mobile 6 . xx and earlier .


public boolean detectBlackBerry()
   {
      if (userAgent.indexOf(deviceBB) != -1 ||
               httpAccept.indexOf(vndRIM) != -1)
         return true;

      if (detectBlackBerry10Phone())
         return true;

      return false;
   }

public boolean detectBlackBerry ( ) { if ( userAgent . indexOf ( deviceBB ) != - 1 || httpAccept . indexOf ( vndRIM ) != - 1 ) return true ; if ( detectBlackBerry10Phone ( ) ) return true ; return false ; }

Detects if the current browser is any BlackBerry. Includes BB10 OS, but excludes the PlayBook.

@return detection of Blackberry

Detects if the current browser is any BlackBerry . Includes BB10 OS but excludes the PlayBook .


public boolean detectS60OssBrowser()
   {
      // First, test for WebKit, then make sure it's either Symbian or S60.
      if (detectWebkit()
               && (userAgent.indexOf(deviceSymbian) != -1
               || userAgent.indexOf(deviceS60) != -1)) {
         return true;
      }
      return false;
   }

Detects if the current browser is the Symbian S60 Open Source Browser.

@return detection of Symbian S60 Browser

Detects if the current browser is the Symbian S60 Open Source Browser .


public boolean detectPalmOS()
   {
      // Make sure it's not WebOS first
      if (detectPalmWebOS())
         return false;

      // Most devices nowadays report as 'Palm', but some older ones reported as Blazer or Xiino.
      if (userAgent.indexOf(devicePalm) != -1
               || userAgent.indexOf(engineBlazer) != -1
               || userAgent.indexOf(engineXiino) != -1) {
         return true;
      }
      return false;
   }

Detects if the current browser is on a PalmOS device.

@return detection of a PalmOS device

Detects if the current browser is on a PalmOS device .


public boolean detectOperaAndroidPhone()
   {
      if (userAgent.indexOf(engineOpera) != -1
               && (userAgent.indexOf(deviceAndroid) != -1
               && userAgent.indexOf(mobi) != -1)) {
         return true;
      }
      return false;
   }

public boolean detectOperaAndroidPhone ( ) { if ( userAgent . indexOf ( engineOpera ) != - 1 && ( userAgent . indexOf ( deviceAndroid ) != - 1 && userAgent . indexOf ( mobi ) != - 1 ) ) { return true ; } return false ; }

Detects Opera Mobile on an Android phone.

@return detection of an Opera browser on an Android phone

Detects Opera Mobile on an Android phone .


public boolean detectOperaAndroidTablet()
   {
      if (userAgent.indexOf(engineOpera) != -1
               && (userAgent.indexOf(deviceAndroid) != -1
               && userAgent.indexOf(deviceTablet) != -1)) {
         return true;
      }
      return false;
   }

public boolean detectOperaAndroidTablet ( ) { if ( userAgent . indexOf ( engineOpera ) != - 1 && ( userAgent . indexOf ( deviceAndroid ) != - 1 && userAgent . indexOf ( deviceTablet ) != - 1 ) ) { return true ; } return false ; }

Detects Opera Mobile on an Android tablet.

@return detection of an Opera browser on an Android tablet

Detects Opera Mobile on an Android tablet .


public boolean detectMaemoTablet()
   {
      if (userAgent.indexOf(maemo) != -1) {
         return true;
      }
      else if (userAgent.indexOf(linux) != -1
               && userAgent.indexOf(deviceTablet) != -1
               && !detectWebOSTablet()
               && !detectAndroid()) {
         return true;
      }
      return false;
   }

public boolean detectMaemoTablet ( ) { if ( userAgent . indexOf ( maemo ) != - 1 ) { return true ; } else if ( userAgent . indexOf ( linux ) != - 1 && userAgent . indexOf ( deviceTablet ) != - 1 && ! detectWebOSTablet ( ) && ! detectAndroid ( ) ) { return true ; } return false ; }

Detects if the current device is on one of the Maemo-based Nokia Internet Tablets.

@return detection of a Maemo OS tablet

Detects if the current device is on one of the Maemo - based Nokia Internet Tablets .


public boolean detectMobileQuick()
   {
      // Let's exclude tablets
      if (detectTierTablet())
         return false;

      if ((initCompleted == true) ||
               (isMobilePhone == true))
         return isMobilePhone;

      // Most mobile browsing is done on smartphones
      if (detectSmartphone())
         return true;

      if (detectWapWml()
               || detectBrewDevice()
               || detectOperaMobile())
         return true;

      if ((userAgent.indexOf(engineObigo) != -1)
               || (userAgent.indexOf(engineNetfront) != -1)
               || (userAgent.indexOf(engineUpBrowser) != -1)
               || (userAgent.indexOf(engineOpenWeb) != -1))
         return true;

      if (detectDangerHiptop()
               || detectMidpCapable()
               || detectMaemoTablet()
               || detectArchos())
         return true;

      if ((userAgent.indexOf(devicePda) != -1) &&
               (userAgent.indexOf(disUpdate) < 0)) // no index found
         return true;

      if (userAgent.indexOf(mobile) != -1)
         return true;

      // We also look for Kindle devices
      if (detectKindle()
               || detectAmazonSilk())
         return true;

      return false;
   }

Detects if the current device is a mobile device. This method catches most of the popular modern devices. Excludes
Apple iPads and other modern tablets.

@return detection of any mobile device using the quicker method

Detects if the current device is a mobile device . This method catches most of the popular modern devices . Excludes Apple iPads and other modern tablets .


public boolean detectTierIphone()
   {
      if ((this.initCompleted == true) ||
               (this.isTierIphone == true))
         return this.isTierIphone;

      if (detectIphoneOrIpod()
               || detectAndroidPhone()
               || detectWindowsPhone()
               || detectBlackBerry10Phone()
               || (detectBlackBerryWebKit()
               && detectBlackBerryTouch())
               || detectPalmWebOS()
               || detectBada()
               || detectTizen()
               || detectGamingHandheld()) {
         return true;
      }
      return false;
   }

public boolean detectTierIphone ( ) { if ( ( this . initCompleted == true ) || ( this . isTierIphone == true ) ) return this . isTierIphone ; if ( detectIphoneOrIpod ( ) || detectAndroidPhone ( ) || detectWindowsPhone ( ) || detectBlackBerry10Phone ( ) || ( detectBlackBerryWebKit ( ) && detectBlackBerryTouch ( ) ) || detectPalmWebOS ( ) || detectBada ( ) || detectTizen ( ) || detectGamingHandheld ( ) ) { return true ; } return false ; }

The quick way to detect for a tier of devices. This method detects for devices which can display iPhone-optimized
web content. Includes iPhone, iPod Touch, Android, Windows Phone 7 and 8, BB10, WebOS, Playstation Vita, etc.

@return detection of any device in the iPhone/Android/Windows Phone/BlackBerry/WebOS Tier

The quick way to detect for a tier of devices . This method detects for devices which can display iPhone - optimized web content . Includes iPhone iPod Touch Android Windows Phone 7 and 8 BB10 WebOS Playstation Vita etc .


public boolean detectTierOtherPhones()
   {
      if ((this.initCompleted == true) ||
               (this.isTierGenericMobile == true))
         return this.isTierGenericMobile;

      // Exclude devices in the other 2 categories
      if (detectMobileLong()
               && !detectTierIphone()
               && !detectTierRichCss())
         return true;

      return false;
   }

The quick way to detect for a tier of devices. This method detects for all other types of phones, but excludes the
iPhone and RichCSS Tier devices.

@return detection of a mobile device in the less capable tier

The quick way to detect for a tier of devices . This method detects for all other types of phones but excludes the iPhone and RichCSS Tier devices .


public static boolean isEL(final String value)
   {
      if (value == null)
      {
         return false;
      }
      return elPattern.matcher(value).matches();
   }

public static boolean isEL ( final String value ) { if ( value == null ) { return false ; } return elPattern . matcher ( value ) . matches ( ) ; }

Return true if the value is an EL expression.

Return true if the value is an EL expression .


public static boolean containsEL(final String value)
   {
      if (value == null)
      {
         return false;
      }

      return elPattern.matcher(value).find();
   }

public static boolean containsEL ( final String value ) { if ( value == null ) { return false ; } return elPattern . matcher ( value ) . find ( ) ; }

Return true if the value contains an EL expression.

Return true if the value contains an EL expression .


private String buildScriptInternal(final String url)
   {
      StringBuilder builder = new StringBuilder();
      builder.append("window.location.href = '");
      builder.append(url);
      builder.append("'; return false;");
      return builder.toString();
   }

private
String
buildScriptInternal
(
final
String
url
)
{
StringBuilder
builder
=
new
StringBuilder
(
)
;
builder
.
append
(
"window.location.href = '"
)
;
builder
.
append
(
url
)
;
builder
.
append
(
"'; return false;"
)
;
return
builder
.
toString
(
)
;
}

Creates the required script for the supplied URL

@param url The URL
@return The script


public static El method(final String retrieve, final String submit)
   {
      return new ElMethod(new ConstantExpression(retrieve), new ConstantExpression(submit));
   }

public static El method ( final String retrieve , final String submit ) { return new ElMethod ( new ConstantExpression ( retrieve ) , new ConstantExpression ( submit ) ) ; }

Create a new EL Method binding using distinct expressions to submit and retrieve values. The method intended for
use in submission must accept a single parameter of the expected type.

Create a new EL Method binding using distinct expressions to submit and retrieve values . The method intended for use in submission must accept a single parameter of the expected type .


private boolean containsFieldDescriptor(String str)
   {
      for (String descriptor : fieldDescriptors) {
         if (str.contains(descriptor)) {
            return true;
         }
      }
      return false;
   }

private boolean containsFieldDescriptor ( String str ) { for ( String descriptor : fieldDescriptors ) { if ( str . contains ( descriptor ) ) { return true ; } } return false ; }

Returns true if the given string contains a field descriptor of one of the annotations we are looking for.

Returns true if the given string contains a field descriptor of one of the annotations we are looking for .


protected void copyResponseHeaders(HttpResponse proxyResponse, HttpServletResponse servletResponse)
   {
      for (Header header : proxyResponse.getAllHeaders())
      {
         if (hopByHopHeaders.containsHeader(header.getName()))
            continue;
         servletResponse.addHeader(header.getName(), header.getValue());
      }
   }

protected void copyResponseHeaders ( HttpResponse proxyResponse , HttpServletResponse servletResponse ) { for ( Header header : proxyResponse . getAllHeaders ( ) ) { if ( hopByHopHeaders . containsHeader ( header . getName ( ) ) ) continue ; servletResponse . addHeader ( header . getName ( ) , header . getValue ( ) ) ; } }

Copy proxied response headers back to the servlet client.

Copy proxied response headers back to the servlet client .


protected static CharSequence encodeUriQuery(CharSequence in)
   {
      /*
       * Note that I can't simply use URI.java to encode because it will escape pre-existing escaped things. TODO:
       * replace/compare to with Rewrite Encoding
       */
      StringBuilder outBuf = null;
      Formatter formatter = null;
      for (int i = 0; i < in.length(); i++)
      {
         char c = in.charAt(i);
         boolean escape = true;
         if (c < 128)
         {
            if (asciiQueryChars.get(c))
            {
               escape = false;
            }
         }
         else if (!Character.isISOControl(c) && !Character.isSpaceChar(c))
         {
            /*
             * not-ascii
             */
            escape = false;
         }
         if (!escape)
         {
            if (outBuf != null)
               outBuf.append(c);
         }
         else
         {
            /*
             * escape
             */
            if (outBuf == null)
            {
               outBuf = new StringBuilder(in.length() + 5 * 3);
               outBuf.append(in, 0, i);
               formatter = new Formatter(outBuf);
            }
            /*
             * leading %, 0 padded, width 2, capital hex
             */
            formatter.format("%%%02X", (int) c);// TODO
         }
      }
      return outBuf != null ? outBuf : in;
   }

/*
             * not-ascii
             */

/*
             * escape
             */

Encodes characters in the query or fragment part of the URI.

<p>
Unfortunately, an incoming URI sometimes has characters disallowed by the spec. HttpClient insists that the
outgoing proxied request has a valid URI because it uses Java's {@link URI}. To be more forgiving, we must escape
the problematic characters. See the URI class for the spec.

@param in example: name=value&foo=bar#fragment

Encodes characters in the query or fragment part of the URI .


public URI toURI()
   {
      try {
         URI uri = new URI(toURL());
         return uri;
      }
      catch (URISyntaxException e) {
         throw new IllegalStateException("URL cannot be parsed.", e);
      }
   }

public
URI
toURI
(
)
{
try
{
URI
uri
=
new
URI
(
toURL
(
)
)
;
return
uri
;
}
catch
(
URISyntaxException
e
)
{
throw
new
IllegalStateException
(
"URL cannot be parsed."
,
e
)
;
}
}

Return a URI representation of this URL including path and query string


public static QueryString build(final String url)
   {
      QueryString queryString = new QueryString();
      queryString.addParameters(url);
      return queryString;
   }

public static QueryString build ( final String url ) { QueryString queryString = new QueryString ( ) ; queryString . addParameters ( url ) ; return queryString ; }

Build a query string from the given URL. If a '?' character is encountered in the URL, the any characters up to
and including the first '?' will be ignored.

Build a query string from the given URL . If a ? character is encountered in the URL the any characters up to and including the first ? will be ignored .


public String getParameter(final String name)
   {
      List<String> values = parameters.get(name);
      if (values == null)
      {
         return null;
      }

      if (values.size() == 0)
      {
         return "";
      }

      return values.get(0);
   }

public String getParameter ( final String name ) { List < String > values = parameters . get ( name ) ; if ( values == null ) { return null ; } if ( values . size ( ) == 0 ) { return "" ; } return values . get ( 0 ) ; }

Get the first value of given parameter name.

@return The value of the parameter, null if the parameter does not exist, or "" if the parameter exists but has no
values.

Get the first value of given parameter name .


public String[] getParameterValues(final String name)
   {
      List<String> values = parameters.get(name);
      if (values == null)
      {
         return null;
      }

      return values.toArray(new String[values.size()]);
   }

public String [ ] getParameterValues ( final String name ) { List < String > values = parameters . get ( name ) ; if ( values == null ) { return null ; } return values . toArray ( new String [ values . size ( ) ] ) ; }

Get the array of values for a given parameter name.

@return The values of the parameter, null if the parameter does not exist.

Get the array of values for a given parameter name .


public void addParameters(String url)
   {
      if ((url != null) && !"".equals(url))
      {
         url = url.trim();
         if (url.length() > 1)
         {
            if (url.contains("?"))
            {
               url = url.substring(url.indexOf('?') + 1);
            }

            String pairs[] = url.split("&(amp;)?");
            for (String pair : pairs)
            {
               String name;
               String value;
               int pos = pair.indexOf('=');
               // for "n=", the value is "", for "n", the value is null
               if (pos == -1)
               {
                  name = pair;
                  value = null;
               }
               else
               {
                  try
                  {
                     // FIXME This probably shouldn't be happening here.
                     name = URLDecoder.decode(pair.substring(0, pos), "UTF-8");
                     value = URLDecoder.decode(pair.substring(pos + 1, pair.length()), "UTF-8");
                  }
                  catch (IllegalArgumentException e)
                  {
                     // thrown by URLDecoder if character decoding fails
                     log.warn("Ignoring invalid query parameter: " + pair);
                     continue;
                  }
                  catch (UnsupportedEncodingException e)
                  {
                     throw new PrettyException(
                              "UTF-8 encoding not supported. Something is seriously wrong with your environment.");
                  }
               }
               List<String> list = parameters.get(name);
               if (list == null)
               {
                  list = new ArrayList<String>();
                  parameters.put(name, list);
               }
               list.add(value);
            }
         }
      }
      return;
   }

Add parameters from the given URL. If a '?' character is encountered in the URL, the any characters up to and
including the first '?' will be ignored. If a parameter already exists, append new values to the existing list of
values for that parameter.

Add parameters from the given URL . If a ? character is encountered in the URL the any characters up to and including the first ? will be ignored . If a parameter already exists append new values to the existing list of values for that parameter .


@Override
   public String deriveViewId(final FacesContext context, final String rawViewId)
   {
      String canonicalViewId = new URLDuplicatePathCanonicalizer().canonicalize(rawViewId);
      return parent.deriveViewId(context, canonicalViewId);
   }

@ Override public String deriveViewId ( final FacesContext context , final String rawViewId ) { String canonicalViewId = new URLDuplicatePathCanonicalizer ( ) . canonicalize ( rawViewId ) ; return parent . deriveViewId ( context , canonicalViewId ) ; }

Canonicalize the given viewId, then pass that viewId to the next ViewHandler in the chain.

Canonicalize the given viewId then pass that viewId to the next ViewHandler in the chain .


public URLPatternParser getPatternParser()
   {
      if ((parser == null) && (pattern != null))
      {
         this.parser = new URLPatternParser(pattern);
      }
      return parser;
   }

public URLPatternParser getPatternParser ( ) { if ( ( parser == null ) && ( pattern != null ) ) { this . parser = new URLPatternParser ( pattern ) ; } return parser ; }

Get this patterns pattern parser instance.

Get this patterns pattern parser instance .


public List<PathValidator> getValidatorsForPathParam(final PathParameter param)
   {
      List<PathValidator> result = new ArrayList<PathValidator>();
      for (PathValidator pv : pathValidators)
      {
         if (pv.getIndex() == param.getPosition())
         {
            result.add(pv);
         }
      }
      return result;
   }

public List < PathValidator > getValidatorsForPathParam ( final PathParameter param ) { List < PathValidator > result = new ArrayList < PathValidator > ( ) ; for ( PathValidator pv : pathValidators ) { if ( pv . getIndex ( ) == param . getPosition ( ) ) { result . add ( pv ) ; } } return result ; }

Return a list of validators that belong to the given parameter.

Return a list of validators that belong to the given parameter .


public static QueryStringBuilder createFromEncoded(final String parameters)
   {
      QueryStringBuilder queryString = new QueryStringBuilder();
      queryString.addParameters(parameters);
      return queryString;
   }

public static QueryStringBuilder createFromEncoded ( final String parameters ) { QueryStringBuilder queryString = new QueryStringBuilder ( ) ; queryString . addParameters ( parameters ) ; return queryString ; }

Build a query string from the given URL. If a '?' character is encountered in the URL, the any characters up to
and including the first '?' will be ignored. This method assumes that the given parameters have already been URL
encoded.

Build a query string from the given URL . If a ? character is encountered in the URL the any characters up to and including the first ? will be ignored . This method assumes that the given parameters have already been URL encoded .


public static String extractQuery(String url)
   {
      if (url != null)
      {
         int index = url.indexOf('?');
         if (index >= 0)
         {
            url = url.substring(index + 1);
         }
      }
      return url;
   }

public static String extractQuery ( String url ) { if ( url != null ) { int index = url . indexOf ( ' ' ) ; if ( index >= 0 ) { url = url . substring ( index + 1 ) ; } } return url ; }

Get the query string portion of the given URL. If no query string separator character '?' can be found, return the
string unchanged.

Get the query string portion of the given URL . If no query string separator character ? can be found return the string unchanged .


public void addParameter(final String name, final String... values)
   {
      Map<String, String[]> parameter = new LinkedHashMap<String, String[]>();
      parameter.put(name, values);
      addParameterArrays(parameter);
   }

public void addParameter ( final String name , final String ... values ) { Map < String , String [ ] > parameter = new LinkedHashMap < String , String [ ] > ( ) ; parameter . put ( name , values ) ; addParameterArrays ( parameter ) ; }

Add a single parameter with the given values.

Add a single parameter with the given values .


@SuppressWarnings("unchecked")
   private List<DispatcherTypeProvider> getDispatcherTypeProviders(HttpServletRewrite event)
   {
      List<DispatcherTypeProvider> providers = (List<DispatcherTypeProvider>)
               event.getRequest().getAttribute(PROVIDER_KEY);
      if (providers == null) {
         providers = Iterators.asList(ServiceLoader.loadTypesafe(DispatcherTypeProvider.class).iterator());
         Collections.sort(providers, new WeightedComparator());
         event.getRequest().setAttribute(PROVIDER_KEY, providers);
      }
      return providers;
   }

@ SuppressWarnings ( "unchecked" ) private List < DispatcherTypeProvider > getDispatcherTypeProviders ( HttpServletRewrite event ) { List < DispatcherTypeProvider > providers = ( List < DispatcherTypeProvider > ) event . getRequest ( ) . getAttribute ( PROVIDER_KEY ) ; if ( providers == null ) { providers = Iterators . asList ( ServiceLoader . loadTypesafe ( DispatcherTypeProvider . class ) . iterator ( ) ) ; Collections . sort ( providers , new WeightedComparator ( ) ) ; event . getRequest ( ) . setAttribute ( PROVIDER_KEY , providers ) ; } return providers ; }

Simple caching mechanism for the providers on a per request basis


public static int getNegationCount(final EvaluationContext context)
   {
      if (context == null)
         return 0;

      Integer count = (Integer)context.get(NEGATION_COUNT_KEY);
      return count == null ? 0 : count;
   }

public static int getNegationCount ( final EvaluationContext context ) { if ( context == null ) return 0 ; Integer count = ( Integer ) context . get ( NEGATION_COUNT_KEY ) ; return count == null ? 0 : count ; }

Returns the number of "Not"s that have been evaluated in the current evaluation process.

For example, when(Not.any(MyCondition)) would have a "NotCount" of "1" during the evaluation of "MyCondition".

when(Not.any(Not.any(MyCondition))) would have a "NotCount" of "2" during the evaluation of "MyCondition".

This is useful for conditions that may have side effects, as they will know whether or not their condition is being
negated.

Returns the number of Not s that have been evaluated in the current evaluation process .


public Navigate with(CharSequence name, Object value)
   {
      Assert.notNull(name, "name must not be null");
      if (value != null) {
         parameters.put(name.toString(), value.toString());
      }
      return this;
   }

public
Navigate
with
(
CharSequence
name
,
Object
value
)
{
Assert
.
notNull
(
name
,
"name must not be null"
)
;
if
(
value
!=
)
{
parameters
.
put
(
name
.
toString
(
)
,
value
.
toString
(
)
)
;
}
return
this
;
}

Set a query parameter to be passed to the specified View Id.

@param The query parameter name.
@param The query parameter value.

Set a query parameter to be passed to the specified View Id .


private String buildStandardOutcome()
   {
      StringBuilder outcome = new StringBuilder();
      outcome.append(viewId);

      boolean first = true;
      for (Entry<String, List<String>> param : parameters.entrySet()) {

         for (String value : param.getValue()) {

            outcome.append(first ? '?' : '&');

            outcome.append(param.getKey());
            outcome.append('=');
            outcome.append(value);

            first = false;

         }

      }

      return outcome.toString();
   }

private String buildStandardOutcome ( ) { StringBuilder outcome = new StringBuilder ( ) ; outcome . append ( viewId ) ; boolean first = true ; for ( Entry < String , List < String > > param : parameters . entrySet ( ) ) { for ( String value : param . getValue ( ) ) { outcome . append ( first ? ' ' : ' ' ) ; outcome . append ( param . getKey ( ) ) ; outcome . append ( ' ' ) ; outcome . append ( value ) ; first = false ; } } return outcome . toString ( ) ; }

Builds a standard JSF 2.0 implicit navigation outcome

Builds a standard JSF 2 . 0 implicit navigation outcome


private void handleClassEntry(String entryName, ClassVisitor visitor)
   {

      // build class name from relative name
      String className = getClassName(entryName.substring(CLASSES_FOLDER.length()));

      // check filter
      if (mustProcessClass(className) && !processedClasses.contains(className))
      {

         // mark this class as processed
         processedClasses.add(className);

         // the class file stream
         InputStream classFileStream = null;

         // close the stream in finally block
         try
         {

            /*
             * Try to open the .class file. if this isn't possible, we will scan it anyway.
             */
            classFileStream = servletContext.getResourceAsStream(entryName);

            if (classFileStream == null)
            {
               if (log.isDebugEnabled())
               {
                  log.debug("Could not obtain InputStream for class file: " + entryName);
               }
            }

            // analyze the class (with or without classFileStream)
            processClass(className, classFileStream, visitor);

         }
         finally
         {
            try
            {
               if (classFileStream != null)
               {
                  classFileStream.close();
               }
            }
            catch (IOException e)
            {
               if (log.isDebugEnabled())
               {
                  log.debug("Failed to close input stream: " + e.getMessage());
               }
            }
         }
      }

   }


AddressBuilderQuery queryLiteral(String query)
   {
      if (query != null)
      {
         if (query.startsWith("?"))
            query = query.substring(1);

         /*
          * Linked hash map is important here in order to retain the order of query parameters.
          */
         Map<CharSequence, List<CharSequence>> params = new LinkedHashMap<CharSequence, List<CharSequence>>();
         query = decodeHTMLAmpersands(query);
         int index = 0;

         while ((index = query.indexOf('&')) >= 0 || !query.isEmpty())
         {
            String pair = query;
            if (index >= 0)
            {
               pair = query.substring(0, index);
               query = query.substring(index);
               if (!query.isEmpty())
                  query = query.substring(1);
            }
            else
               query = "";

            String name;
            String value;
            int pos = pair.indexOf('=');
            // for "n=", the value is "", for "n", the value is null
            if (pos == -1)
            {
               name = pair;
               value = null;
            }
            else
            {
               name = pair.substring(0, pos);
               value = pair.substring(pos + 1, pair.length());
            }

            List<CharSequence> list = params.get(name);
            if (list == null)
            {
               list = new ArrayList<CharSequence>();
               params.put(name, list);
            }
            list.add(value);
         }

         for (Entry<CharSequence, List<CharSequence>> entry : params.entrySet()) {
            query(entry.getKey(), entry.getValue().toArray());
         }
      }
      return new AddressBuilderQuery(this);
   }

Set a literal query string without additional encoding or decoding. A leading '?' character is optional; the
builder will add one if necessary.

Set a literal query string without additional encoding or decoding . A leading ? character is optional ; the builder will add one if necessary .


public EncodeQuery excluding(final String... params)
   {
      if ((params != null) && (params.length > 0))
         this.excludedParams.addAll(Arrays.asList(params));
      return this;
   }

public EncodeQuery excluding ( final String ... params ) { if ( ( params != null ) && ( params . length > 0 ) ) this . excludedParams . addAll ( Arrays . asList ( params ) ) ; return this ; }

Exclude the given query-parameter names from encoding.

Exclude the given query - parameter names from encoding .


public URL buildURL(final UrlMapping mapping)
   {
      URL result = null;

      String expression = "";
      Object value = null;
      try
      {
         FacesContext context = FacesContext.getCurrentInstance();

         URLPatternParser parser = mapping.getPatternParser();
         List<PathParameter> parameters = parser.getPathParameters();
         List<String> parameterValues = new ArrayList<String>();
         for (PathParameter injection : parameters)
         {
            // read value of the path parameter
            expression = injection.getExpression().getELExpression();
            value = elUtils.getValue(context, expression);
            if (value == null)
            {
               throw new PrettyException("PrettyFaces: Exception occurred while building URL for MappingId < "
                        + mapping.getId() + " >, Required value " + " < " + expression + " > was null");
            }

            // convert the value to a string using the correct converter
            Converter converter = context.getApplication().createConverter(value.getClass());
            if (converter != null)
            {
               String convertedValue = converter.getAsString(context, new NullComponent(), value);
               if (convertedValue == null)
               {
                  throw new PrettyException("PrettyFaces: The converter <" + converter.getClass().getName()
                           + "> returned null while converting the object <" + value.toString() + ">!");
               }
               value = convertedValue;
            }

            parameterValues.add(value.toString());
         }

         result = parser.getMappedURL(parameterValues).encode();
      }
      catch (ELException e)
      {
         throw new PrettyException("PrettyFaces: Exception occurred while building URL for MappingId < "
                  + mapping.getId() + " >, Error occurred while extracting values from backing bean" + " < "
                  + expression + ":" + value + " >", e);
      }

      return result;
   }

For all required values of the given PrettyUrlMapping, extract values from their mapped backing beans and create a
URL based on the url-pattern.

@param mapping Mapping for which to extract values and generate URL
@return The fully constructed URL

For all required values of the given PrettyUrlMapping extract values from their mapped backing beans and create a URL based on the url - pattern .


public void sendError(int code, String message, HttpServletResponse response)
   {
      Assert.notNull(response, "HttpServletResponse argument was null");
      try
      {
         if (message != null)
         {
            response.sendError(code, message);
         }
         else
         {
            response.sendError(code);
         }
      }
      catch (IOException e)
      {
         throw new IllegalStateException("Failed to send error code: " + code, e);
      }
   }

public
void
sendError
(
int
code
,
String
message
,
HttpServletResponse
response
)
{
Assert
.
notNull
(
response
,
"HttpServletResponse argument was null"
)
;
try
{
if
(
message
!=
)
{
response
.
sendError
(
code
,
message
)
;
}
else
{
response
.
sendError
(
code
)
;
}
}
catch
(
IOException
e
)
{
throw
new
IllegalStateException
(
"Failed to send error code: "
+
code
,
e
)
;
}
}

Sends an error response to the client using the specified HTTP status
code.

@param code the error status code
@param message the descriptive message
@param response
@see HttpServletResponse#sendError(int, String)

Sends an error response to the client using the specified HTTP status code .