Returns the directionality of the first strong character, or digit, in the epilogue, if any.
Requires epilogue!=null.
969637
private byte firstL_R_AL_EN_AN() {
        for (int i = 0; i < epilogue.length(); ) {
            int uchar = epilogue.codePointAt(i);
            i += Character.charCount(uchar);
            byte dirProp = (byte)getCustomizedClass(uchar);
            if (dirProp == L) {
                return _L;
            }
            if (dirProp == R || dirProp == AL) {
                return _R;
            }
            if (dirProp == EN) {
                return _EN;
            }
            if (dirProp == AN) {
                return _AN;
            }
        }
        return _ON;
    }
189873
public static String parseRevIDSuffix(String rev) {
        String result = null;
        int dashPos = rev.indexOf('-');
        if (dashPos >= 0) {
            result = rev.substring(dashPos + 1);
        }
        return result;
    }
333754
public static Character checkNull(Character value, Character elseValue) {
        return isNull(value) ? elseValue : value;
    }
1042249
private void getDirProps()
    {
        int i = 0, i0, i1;
        flags = 0;          /* collect all directionalities in the text */
        int uchar;
        byte dirProp;
        byte defaultParaLevel = 0;   /* initialize to avoid compiler warnings */
        boolean isDefaultLevel = IsDefaultLevel(paraLevel);
        /* for inverse Bidi, the default para level is set to RTL if there is a
           strong R or AL character at either end of the text                */
        boolean isDefaultLevelInverse=isDefaultLevel &&
                (reorderingMode == REORDER_INVERSE_LIKE_DIRECT ||
                 reorderingMode == REORDER_INVERSE_FOR_NUMBERS_SPECIAL);
        lastArabicPos = -1;
        int controlCount = 0;
        boolean removeBidiControls = (reorderingOptions & OPTION_REMOVE_CONTROLS) != 0;

        byte state;
        byte lastStrong = ON;           /* for default level & inverse Bidi */
    /* The following stacks are used to manage isolate sequences. Those
       sequences may be nested, but obviously never more deeply than the
       maximum explicit embedding level.
       lastStack is the index of the last used entry in the stack. A value of -1
       means that there is no open isolate sequence.
       lastStack is reset to -1 on paragraph boundaries. */
    /* The following stack contains the position of the initiator of
       each open isolate sequence */
        int[] isolateStartStack= new int[MAX_EXPLICIT_LEVEL+1];
    /* The following stack contains the last known state before
       encountering the initiator of an isolate sequence */
        byte[] previousStateStack = new byte[MAX_EXPLICIT_LEVEL+1];
        int  stackLast=-1;

        if ((reorderingOptions & OPTION_STREAMING) != 0)
            length = 0;
        defaultParaLevel = (byte)(paraLevel & 1);

        if (isDefaultLevel) {
            paras_level[0] = defaultParaLevel;
            lastStrong = defaultParaLevel;
            if (prologue != null &&                        /* there is a prologue */
                (dirProp = firstL_R_AL()) != ON) {     /* with a strong character */
                if (dirProp == L)
                    paras_level[0] = 0;             /* set the default para level */
                else
                    paras_level[0] = 1;             /* set the default para level */
                state = NOT_SEEKING_STRONG;
            } else {
                state = SEEKING_STRONG_FOR_PARA;
            }
        } else {
            paras_level[0] = paraLevel;
            state = NOT_SEEKING_STRONG;
        }
        /* count paragraphs and determine the paragraph level (P2..P3) */
        /*
         * see comment on constant fields:
         * the LEVEL_DEFAULT_XXX values are designed so that
         * their low-order bit alone yields the intended default
         */

        for (i = 0; i < originalLength; /* i is incremented in the loop */) {
            i0 = i;                     /* index of first code unit */
            uchar = UTF16.charAt(text, 0, originalLength, i);
            i += UTF16.getCharCount(uchar);
            i1 = i - 1; /* index of last code unit, gets the directional property */

            dirProp = (byte)getCustomizedClass(uchar);
            flags |= DirPropFlag(dirProp);
            dirProps[i1] = dirProp;
            if (i1 > i0) {     /* set previous code units' properties to BN */
                flags |= DirPropFlag(BN);
                do {
                    dirProps[--i1] = BN;
                } while (i1 > i0);
            }
            if (removeBidiControls && IsBidiControlChar(uchar)) {
                controlCount++;
            }
            if (dirProp == L) {
                if (state == SEEKING_STRONG_FOR_PARA) {
                    paras_level[paraCount - 1] = 0;
                    state = NOT_SEEKING_STRONG;
                }
                else if (state == SEEKING_STRONG_FOR_FSI) {
                    if (stackLast <= MAX_EXPLICIT_LEVEL) {
                        /* no need for next statement, already set by default */
                        /* dirProps[isolateStartStack[stackLast]] = LRI; */
                        flags |= DirPropFlag(LRI);
                    }
                    state = LOOKING_FOR_PDI;
                }
                lastStrong = L;
                continue;
            }
            if (dirProp == R || dirProp == AL) {
                if (state == SEEKING_STRONG_FOR_PARA) {
                    paras_level[paraCount - 1] = 1;
                    state = NOT_SEEKING_STRONG;
                }
                else if (state == SEEKING_STRONG_FOR_FSI) {
                    if (stackLast <= MAX_EXPLICIT_LEVEL) {
                        dirProps[isolateStartStack[stackLast]] = RLI;
                        flags |= DirPropFlag(RLI);
                    }
                    state = LOOKING_FOR_PDI;
                }
                lastStrong = R;
                if (dirProp == AL)
                    lastArabicPos = i - 1;
                continue;
            }
            if (dirProp >= FSI && dirProp <= RLI) { /* FSI, LRI or RLI */
                stackLast++;
                if (stackLast <= MAX_EXPLICIT_LEVEL) {
                    isolateStartStack[stackLast] = i - 1;
                    previousStateStack[stackLast] = state;
                }
                if (dirProp == FSI) {
                    dirProps[i-1] = LRI;    /* default if no strong char */
                    state = SEEKING_STRONG_FOR_FSI;
                }
                else
                    state = LOOKING_FOR_PDI;
                continue;
            }
            if (dirProp == PDI) {
                if (state == SEEKING_STRONG_FOR_FSI) {
                    if (stackLast <= MAX_EXPLICIT_LEVEL) {
                        /* no need for next statement, already set by default */
                        /* dirProps[isolateStartStack[stackLast]] = LRI; */
                        flags |= DirPropFlag(LRI);
                    }
                }
                if (stackLast >= 0) {
                    if (stackLast <= MAX_EXPLICIT_LEVEL)
                        state = previousStateStack[stackLast];
                    stackLast--;
                }
                continue;
            }
            if (dirProp == B) {
                if (i < originalLength && uchar == CR && text[i] == LF) /* do nothing on the CR */
                    continue;
                paras_limit[paraCount - 1] = i;
                if (isDefaultLevelInverse && lastStrong == R)
                    paras_level[paraCount - 1] = 1;
                if ((reorderingOptions & OPTION_STREAMING) != 0) {
                /* When streaming, we only process whole paragraphs
                   thus some updates are only done on paragraph boundaries */
                   length = i;          /* i is index to next character */
                   this.controlCount = controlCount;
                }
                if (i < originalLength) {       /* B not last char in text */
                    paraCount++;
                    checkParaCount();   /* check that there is enough memory for a new para entry */
                    if (isDefaultLevel) {
                        paras_level[paraCount - 1] = defaultParaLevel;
                        state = SEEKING_STRONG_FOR_PARA;
                        lastStrong = defaultParaLevel;
                    } else {
                        paras_level[paraCount - 1] = paraLevel;
                        state = NOT_SEEKING_STRONG;
                    }
                    stackLast = -1;
                }
                continue;
            }
        }
        /* +Ignore still open isolate sequences with overflow */
        if (stackLast > MAX_EXPLICIT_LEVEL) {
            stackLast = MAX_EXPLICIT_LEVEL;
            state=SEEKING_STRONG_FOR_FSI;   /* to be on the safe side */
        }
        /* Resolve direction of still unresolved open FSI sequences */
        while (stackLast >= 0) {
            if (state == SEEKING_STRONG_FOR_FSI) {
                /* no need for next statement, already set by default */
                /* dirProps[isolateStartStack[stackLast]] = LRI; */
                flags |= DirPropFlag(LRI);
                break;
            }
            state = previousStateStack[stackLast];
            stackLast--;
        }
        /* When streaming, ignore text after the last paragraph separator */
        if ((reorderingOptions & OPTION_STREAMING) != 0) {
            if (length < originalLength)
                paraCount--;
        } else {
            paras_limit[paraCount - 1] = originalLength;
            this.controlCount = controlCount;
        }
        /* For inverse bidi, default para direction is RTL if there is
           a strong R or AL at either end of the paragraph */
        if (isDefaultLevelInverse && lastStrong == R) {
            paras_level[paraCount - 1] = 1;
        }
        if (isDefaultLevel) {
            paraLevel = paras_level[0];
        }
        /* The following is needed to resolve the text direction for default level
           paragraphs containing no strong character */
        for (i = 0; i < paraCount; i++)
            flags |= DirPropFlagLR(paras_level[i]);

        if (orderParagraphsLTR && (flags & DirPropFlag(B)) != 0) {
            flags |= DirPropFlag(L);
        }
    }
1210896
private byte bracketProcessClosing(BracketData bd, int openIdx, int position) {
        IsoRun pLastIsoRun = bd.isoRuns[bd.isoRunLast];
        Opening pOpening, qOpening;
        byte direction;
        boolean stable;
        byte newProp;
        pOpening = bd.openings[openIdx];
        direction = (byte)(pLastIsoRun.level & 1);
        stable = true;          /* assume stable until proved otherwise */

        /* The stable flag is set when brackets are paired and their
           level is resolved and cannot be changed by what will be
           found later in the source string.
           An unstable match can occur only when applying N0c, where
           the resolved level depends on the preceding context, and
           this context may be affected by text occurring later.
           Example: RTL paragraph containing:  abc[(latin) HEBREW]
           When the closing parenthesis is encountered, it appears
           that N0c1 must be applied since 'abc' sets an opposite
           direction context and both parentheses receive level 2.
           However, when the closing square bracket is processed,
           N0b applies because of 'HEBREW' being included within the
           brackets, thus the square brackets are treated like R and
           receive level 1. However, this changes the preceding
           context of the opening parenthesis, and it now appears
           that N0c2 must be applied to the parentheses rather than
           N0c1. */

            if ((direction == 0 && (pOpening.flags & FOUND_L) > 0) ||
                (direction == 1 && (pOpening.flags & FOUND_R) > 0)) {   /* N0b */
                newProp = direction;
            }
            else if ((pOpening.flags & (FOUND_L | FOUND_R)) != 0) {     /* N0c */
                    /* it is stable if there is no preceding text or in
                       conditions too complicated and not worth checking */
                    stable = (openIdx == pLastIsoRun.start);
                if (direction != pOpening.contextDir)
                    newProp = pOpening.contextDir;                      /* N0c1 */
                else
                    newProp = direction;                                /* N0c2 */
            } else {
            /* forget this and any brackets nested within this pair */
            pLastIsoRun.limit = (short)openIdx;
            return ON;                                                  /* N0d */
        }
        dirProps[pOpening.position] = newProp;
        dirProps[position] = newProp;
        /* Update nested N0c pairs that may be affected */
        fixN0c(bd, openIdx, pOpening.position, newProp);
        if (stable) {
            pLastIsoRun.limit = (short)openIdx; /* forget any brackets nested within this pair */
            /* remove lower located synonyms if any */
            while (pLastIsoRun.limit > pLastIsoRun.start &&
                   bd.openings[pLastIsoRun.limit - 1].position == pOpening.position)
                pLastIsoRun.limit--;
        } else {
            int k;
            pOpening.match = -position;
            /* neutralize lower located synonyms if any */
            k = openIdx - 1;
            while (k >= pLastIsoRun.start &&
                   bd.openings[k].position == pOpening.position)
                bd.openings[k--].match = 0;
            /* neutralize any unmatched opening between the current pair;
               this will also neutralize higher located synonyms if any */
            for (k = openIdx + 1; k < pLastIsoRun.limit; k++) {
                qOpening =bd.openings[k];
                if (qOpening.position >= position)
                    break;
                if (qOpening.match > 0)
                    qOpening.match = 0;
            }
        }
        return newProp;
    }
146255
public Token scanNumericLiteral() {
		int start = pos;
		int next = pos + 1;
		// Decide whether it's an integer, binary or hexadecimal literal
		if (next < input.length() && input.charAt(pos) == '0' && input.charAt(next) == 'x') {
			// Hexadecimal literal
			return scanHexLiteral();
		} else if (next < input.length() && input.charAt(pos) == '0' && input.charAt(next) == 'b') {
			// Binary literal
			return scanBinaryLiteral();
		} else {
			return scanIntegerLiteral();
		}
	}
697167
private static int isTashkeelOnTatweelChar(char ch){
        if (ch >= 0xfe70 && ch <= 0xfe7f && ch != NEW_TAIL_CHAR && ch != 0xFE75 && ch != SHADDA_TATWEEL_CHAR)
        {
            return tashkeelMedial [ch - 0xFE70];
        } else if( (ch >= 0xfcf2 && ch <= 0xfcf4) || (ch == SHADDA_TATWEEL_CHAR)) {
            return 2;
        } else {
            return 0;
        }
    }
228506
function getNextWhile(tokens, index, direction, matcher) {
		var count = 1, 
			token;
		
		direction = direction || 1;
		while (token = tokens[index + (direction * count++)]) {
			if (!matcher(token)) {
				return token;
			}
		}
		
		return undefined;
	}
1338283
function firstStrongChar(str: string): ?string {
  const match = REGEX_STRONG.exec(str);
  return match == null ? null : match[0];
}
1289796
public static int getFirstNonWhitespace(String strText)
    {
        if (strText != null)
        {
            for (int i = 0; i < strText.length(); i++)
            {
                if (!Character.isWhitespace(strText.charAt(i)))
                    return i;
            }
        }
        return -1;
    }
753562
private String digits() {
    StringBuilder sb = new StringBuilder();
    do {
      sb.append(consumeNextCharacter(CharType.DIGIT));
    } while (chars.positiveLookahead(CharType.DIGIT));
    return sb.toString();
  }
1262588
public final int getSurrogateValue(char lead, char trail)
    {
        if (!UTF16.isLeadSurrogate(lead) || !UTF16.isTrailSurrogate(trail)) {
            throw new IllegalArgumentException(
                "Argument characters do not form a supplementary character");
        }
        // get fold position for the next trail surrogate
        int offset = getSurrogateOffset(lead, trail);

        // get the real data from the folded lead/trail units
        if (offset > 0) {
            return m_data_[offset];
        }

        // return m_initialValue_ if there is an error
        return m_initialValue_;
    }
439985
function getFirstCharIndex(glyphs) {
    var minGlyph = _.min(glyphs, function (glyph) {
        return (glyph.unicode === 0) ? 0xFFFF : (glyph.unicode || 0);
    });
    if (minGlyph) {
        return minGlyph.unicode > 0xFFFF ? 0xFFFF : (minGlyph.unicode || 0);
    } else {
        return 0xFFFF;
    }
}
1277268
function () {
    var id = "";
    var index = 0;
    var type, char;

    function isNonAsciiIdentifierStart(code) {
      return nonAsciiIdentifierStartTable.indexOf(code) > -1;
    }

    function isNonAsciiIdentifierPart(code) {
      return isNonAsciiIdentifierStart(code) || nonAsciiIdentifierPartTable.indexOf(code) > -1;
    }

    function isHexDigit(str) {
      return (/^[0-9a-fA-F]$/).test(str);
    }

    var readUnicodeEscapeSequence = function () {
      /*jshint validthis:true */
      index += 1;

      if (this.peek(index) !== "u") {
        return null;
      }

      var ch1 = this.peek(index + 1);
      var ch2 = this.peek(index + 2);
      var ch3 = this.peek(index + 3);
      var ch4 = this.peek(index + 4);
      var code;

      if (isHexDigit(ch1) && isHexDigit(ch2) && isHexDigit(ch3) && isHexDigit(ch4)) {
        code = parseInt(ch1 + ch2 + ch3 + ch4, 16);

        if (asciiIdentifierPartTable[code] || isNonAsciiIdentifierPart(code)) {
          index += 5;
          return "\\u" + ch1 + ch2 + ch3 + ch4;
        }

        return null;
      }

      return null;
    }.bind(this);

    var getIdentifierStart = function () {
      /*jshint validthis:true */
      var chr = this.peek(index);
      var code = chr.charCodeAt(0);

      if (code === 92) {
        return readUnicodeEscapeSequence();
      }

      if (code < 128) {
        if (asciiIdentifierStartTable[code]) {
          index += 1;
          return chr;
        }

        return null;
      }

      if (isNonAsciiIdentifierStart(code)) {
        index += 1;
        return chr;
      }

      return null;
    }.bind(this);

    var getIdentifierPart = function () {
      /*jshint validthis:true */
      var chr = this.peek(index);
      var code = chr.charCodeAt(0);

      if (code === 92) {
        return readUnicodeEscapeSequence();
      }

      if (code < 128) {
        if (asciiIdentifierPartTable[code]) {
          index += 1;
          return chr;
        }

        return null;
      }

      if (isNonAsciiIdentifierPart(code)) {
        index += 1;
        return chr;
      }

      return null;
    }.bind(this);

    char = getIdentifierStart();
    if (char === null) {
      return null;
    }

    id = char;
    for (;;) {
      char = getIdentifierPart();

      if (char === null) {
        break;
      }

      id += char;
    }

    switch (id) {
    case "true":
    case "false":
      type = Token.BooleanLiteral;
      break;
    case "null":
      type = Token.NullLiteral;
      break;
    default:
      type = Token.Identifier;
    }

    return {
      type: type,
      value: id
    };
  }
1214944
private static String wordShapeDan1(String s) {
    boolean digit = true;
    boolean upper = true;
    boolean lower = true;
    boolean mixed = true;
    for (int i = 0; i < s.length(); i++) {
      char c = s.charAt(i);
      if (!Character.isDigit(c)) {
        digit = false;
      }
      if (!Character.isLowerCase(c)) {
        lower = false;
      }
      if (!Character.isUpperCase(c)) {
        upper = false;
      }
      if ((i == 0 && !Character.isUpperCase(c)) || (i >= 1 && !Character.isLowerCase(c))) {
        mixed = false;
      }
    }
    if (digit) {
      return "ALL-DIGITS";
    }
    if (upper) {
      return "ALL-UPPER";
    }
    if (lower) {
      return "ALL-LOWER";
    }
    if (mixed) {
      return "MIXED-CASE";
    }
    return "OTHER";
  }
170811
public String getFirstValue() {
        CharSequence firstValue;

        synchronized (values) {
            if (values.isEmpty()) {
                return null;
            }
            firstValue = values.get(0);
        }

        return firstValue.toString();
    }
336087
function _getFirstGlyph() {
         var keys = Object.keys(this.glyphs);

         for (var i = 0; i < keys.length; i++) {
           if (keys[i] > 32) {
             return this.glyphs[keys[i]];
           }
         }

         return null;
       }