/**
   * Try to precompile the arguments to the function. This method is shared by the implementations
   * of the three XPath functions matches(), replace(), and tokenize().
   *
   * @param args the supplied arguments to the function, as an array
   * @param patternArg the position of the argument containing the regular expression
   * @param flagsArg the position of the argument containing the flags
   * @return the compiled regular expression, or null indicating that the information is not
   *     available statically so it cannot be precompiled
   * @throws XPathException if any failure occurs, in particular, if the regular expression is
   *     invalid
   */
  public static RegularExpression tryToCompile(
      Expression[] args, int patternArg, int flagsArg, StaticContext env) throws XPathException {
    if (patternArg > args.length - 1) {
      // too few arguments were supplied; the error will be reported in due course
      return null;
    }
    CharSequence flagstr = null;
    if (args.length - 1 < flagsArg) {
      flagstr = "";
    } else if (args[flagsArg] instanceof StringValue) {
      flagstr = ((StringValue) args[flagsArg]).getStringValueCS();
    }

    if (args[patternArg] instanceof StringValue && flagstr != null) {
      try {
        Platform platform = env.getConfiguration().getPlatform();
        CharSequence in = ((StringValue) args[patternArg]).getStringValueCS();
        RegularExpression regexp = platform.compileRegularExpression(in, true, flagstr);
        return regexp;
      } catch (XPathException err) {
        StaticError e2 = new StaticError(err.getMessage());
        e2.setErrorCode("FORX0002");
        throw e2;
      }
    } else {
      return null;
    }
  }
 public void checkArguments(StaticContext env) throws XPathException {
   if (checked) return;
   checked = true;
   super.checkArguments(env);
   Optimizer opt = env.getConfiguration().getOptimizer();
   argument[1] = ExpressionTool.unsorted(opt, argument[1], false);
   if (argument[0] instanceof StringValue) {
     // common case, key name is supplied as a constant
     try {
       keyFingerprint =
           ((ExpressionContext) env)
               .getFingerprint(((StringValue) argument[0]).getStringValue(), false);
     } catch (XPathException e) {
       StaticError err =
           new StaticError(
               "Error in key name "
                   + ((StringValue) argument[0]).getStringValue()
                   + ": "
                   + e.getMessage());
       err.setLocator(this);
       err.setErrorCode("XTDE1260");
       throw err;
     }
     if (keyFingerprint == -1) {
       StaticError err =
           new StaticError(
               "Key " + ((StringValue) argument[0]).getStringValue() + " has not been defined");
       err.setLocator(this);
       err.setErrorCode("XTDE1260");
       throw err;
     }
   } else {
     // we need to save the namespace context
     nsContext = env.getNamespaceResolver();
   }
 }
  /**
   * Check that any elements and attributes constructed or returned by this expression are
   * acceptable in the content model of a given complex type. It's always OK to say yes, since the
   * check will be repeated at run-time. The process of checking element and attribute constructors
   * against the content model of a complex type also registers the type of content expected of
   * those constructors, so the static validation can continue recursively.
   */
  public void checkPermittedContents(SchemaType parentType, StaticContext env, boolean whole)
      throws XPathException {
    int fp = nameCode & NamePool.FP_MASK;
    if (fp == StandardNames.XSI_TYPE
        || fp == StandardNames.XSI_SCHEMA_LOCATION
        || fp == StandardNames.XSI_NIL
        || fp == StandardNames.XSI_NO_NAMESPACE_SCHEMA_LOCATION) {
      return;
    }
    if (parentType instanceof SimpleType) {
      StaticError err =
          new StaticError(
              "Attribute "
                  + env.getNamePool().getDisplayName(nameCode)
                  + " is not permitted in the content model of the simple type "
                  + parentType.getDescription());
      err.setIsTypeError(true);
      err.setLocator(this);
      if (getHostLanguage() == Configuration.XSLT) {
        err.setErrorCode("XTTE1510");
      } else {
        err.setErrorCode("XQDY0027");
      }
      throw err;
    }
    SchemaType type;
    try {
      type = ((ComplexType) parentType).getAttributeUseType(fp);
    } catch (SchemaException e) {
      throw new StaticError(e);
    }
    if (type == null) {
      StaticError err =
          new StaticError(
              "Attribute "
                  + env.getNamePool().getDisplayName(nameCode)
                  + " is not permitted in the content model of the complex type "
                  + parentType.getDescription());
      err.setIsTypeError(true);
      err.setLocator(this);
      if (getHostLanguage() == Configuration.XSLT) {
        err.setErrorCode("XTTE1510");
      } else {
        err.setErrorCode("XQDY0027");
      }
      throw err;
    }
    if (type instanceof AnyType) {
      return;
    }

    try {
      select.checkPermittedContents(type, env, true);
      // TODO: does this allow for the fact that the content will be atomized?
    } catch (XPathException e) {
      if (e.getLocator() == null || e.getLocator() == e) {
        e.setLocator(this);
      }
      throw e;
    }
  }