Extract the first expression segment, that is the substring up to the first '.' or '['

@param expression
@return first segment of the expression
962809
private String getFirstSegment(String expression)
    {
        int indexDot = expression.indexOf('.');
        int indexBracket = expression.indexOf('[');

        if (indexBracket < 0)
        {

            return indexDot < 0 ? expression : expression.substring(0, indexDot);

        }

        if (indexDot < 0)
        {
            return expression.substring(0, indexBracket);
        }

        return expression.substring(0, Math.min(indexDot, indexBracket));

    }
494806
public String remove(String expression) {
    if (expression == null || expression.length() == 0) { return null; }
    String property = next(expression);
    if (expression.length() == property.length()) { return null; }
    int start = property.length();
    if (expression.charAt(start) == Nested) start++;
    return expression.substring(start);
  }
806641
public static Expression substr(Expression expression, int position, int length) {
        return x("SUBSTR(" + expression.toString() + ", " + position + ", " + length + ")");
    }
89088
@SuppressWarnings("unchecked")
    public static <T> Expression<T> extract(Expression<T> expr) {
        if (expr != null) {
            final Class<?> clazz = expr.getClass();
            if (clazz == PathImpl.class || clazz == PredicateOperation.class || clazz == ConstantImpl.class) {
                return expr;
            } else {
                return (Expression<T>) expr.accept(ExtractorVisitor.DEFAULT, null);
            }
        } else {
            return null;
        }
    }
404586
protected Object getParsedExpression(final String expression) {
		try {
			return Ognl.parseExpression(expression);
		} catch (OgnlException ex) {
			throw new OgnlRuntimeException("Failed to parse the expression.[" + expression + "]", ex);
		}
	}
1294768
public static Expression regexpContains(Expression expression, String pattern) {
        return x("REGEXP_CONTAINS(" + expression.toString() + ", \"" + pattern + "\")");
    }
1298669
public boolean isIndexed(String expression) {
    if (expression == null || expression.length() == 0) { return false; }
    for (int i = 0; i < expression.length(); i++) {
      char c = expression.charAt(i);
      if (c == Nested || c == MappedStart) {
        return false;
      } else if (c == IndexedStart) { return true; }
    }
    return false;
  }
1283304
public static Expression regexpPosition(String expression, String pattern) {
        return regexpPosition(x(expression), pattern);
    }
776359
public Node getNode(String expression) {
		return (Node) evalXPath(expression, null, XPathConstants.NODE);
	}
169370
public static String print(Expression expression) {
        return expression.match(new Expression.MatchBlock<String>() {

            @Override
            public String _case(LiteralExpression x) {
                return print(x.literal);
            }

            @Override
            public String _case(VariableExpression x) {
                return x.selector.match(new Optional.MatchBlock<Expression, String>() {
                    @Override
                    public String _case(Some<Expression> x) {
                        return print(x.value) + ".";
                    }

                    @Override
                    public String _case(None<Expression> x) {
                        return "";
                    }
                }) + x.identifier;
            }

            @Override
            public String _case(NestedExpression x) {
                return "( " + print(x.expression) + " )";
            }

            @Override
            public String _case(ClassReference x) {
                return print(x.type) + ".class";
            }

            @Override
            public String _case(TernaryExpression x) {
                return print(x.cond) + " ? " + print(x.trueExpression) + " : " + print (x.falseExpression);
            }

            @Override
            public String _case(BinaryExpression x) {
                return print(x.left) + " " + print(x.op) + " " +  print(x.right);
            }
        });
    }
18712
private List<String> split(String expression, int offset) {
        List<String> encodedSpecs = new ArrayList<String>();
        int parenthesisLevel = 0;  // number of open '('
        int bracketLevel = 0;      // number of open '['
        int quoteLevel = 0;        // number of open '\''
        int length = expression.length();
        int specStart = 0;
        char c;
        boolean lead = true;
        for (int i = 0; i < length; i++) {
            c = expression.charAt(i);
            if (lead && Character.isWhitespace(c)) {
                specStart++;
                continue;
            }
            lead = false;
            if (c == ',' && parenthesisLevel == 0 && bracketLevel == 0 && quoteLevel == 0) {
                String token = expression.substring(specStart, i);
                addSpec(encodedSpecs, token, offset + specStart);
                specStart = i + 1;
                lead = true;
            } else if (c == '(') {
                if (bracketLevel > 0) {
                    fail(offset + i, "illegal '(' in [...]");
                }
                parenthesisLevel++;
            } else if (c == ')') {
                if (bracketLevel > 0) {
                    fail(offset + i, "illegal ')' in [...]");
                }
                parenthesisLevel--;
                if (parenthesisLevel < 0) {
                    fail(offset + i, "missing '('");
                }
            } else if (c == '[') {
                if (bracketLevel > 0) {
                    fail(offset + i, "too many '['");
                }
                bracketLevel++;
            } else if (c == ']') {
                bracketLevel--;
                if (bracketLevel < 0) {
                    fail(offset + i, "missing '['");
                }
            } else if (c == '\'') {
                if (quoteLevel == 0) {
                    quoteLevel++;
                } else if (quoteLevel == 1) {
                    quoteLevel--;
                }
            }
        }
        if (parenthesisLevel > 0) {
            fail(offset + length, "missing ')'");
        }
        if (bracketLevel > 0) {
            fail(offset + length, "missing ']");
        }
        if (specStart < length) {
            String token = expression.substring(specStart);
            addSpec(encodedSpecs, token, offset + specStart);
        }
        return encodedSpecs;
    }
900027
public static QueryLexer lexer(String expression) {
        QueryLexer lexer = new QueryLexer(input(expression));
        lexer.removeErrorListeners();
        lexer.addErrorListener(ERROR_LISTENER);
        return lexer;
    }
696347
public StringExpression substring(int beginIndex) {
        return Expressions.stringOperation(Ops.SUBSTR_1ARG, mixin, ConstantImpl.create(beginIndex));
    }
1167460
public static boolean isExpressionContainsFunction(String expression) {
		
		// Si la chaine est vide : false
		if(expression == null || expression.trim().length() == 0) {
			
			// On retourne false
			return false;
		}
		
		// On split
		return isExpressionContainPattern(expression, FUNC_CHAIN_PATTERN);
	}
1144354
private String getFirstPartOfString(final String source) {

		final int pos = source.indexOf(".");
		if (pos > -1) {

			return source.substring(0, pos);
		}

		return source;
	}
598543
public Object resolveExpression(String expression) {
    if (StringUtils.isBlank(expression)) {
      return null;
    }

    interpreter.getContext().addResolvedExpression(expression.trim());

    try {
      String elExpression = EXPRESSION_START_TOKEN + expression.trim() + EXPRESSION_END_TOKEN;
      ValueExpression valueExp = expressionFactory.createValueExpression(elContext, elExpression, Object.class);
      Object result = valueExp.getValue(elContext);

      validateResult(result);

      return result;

    } catch (PropertyNotFoundException e) {
      interpreter.addError(new TemplateError(ErrorType.WARNING, ErrorReason.UNKNOWN, ErrorItem.PROPERTY, e.getMessage(), "", interpreter.getLineNumber(), interpreter.getPosition(), e,
          BasicTemplateErrorCategory.UNKNOWN, ImmutableMap.of("exception", e.getMessage())));
    } catch (TreeBuilderException e) {
      int position = interpreter.getPosition() + e.getPosition();
      // replacing the position in the string like this isn't great, but JUEL's parser does not allow passing in a starting position
      String errorMessage = StringUtils.substringAfter(e.getMessage(), "': ").replaceFirst("position [0-9]+", "position " + position);
      interpreter.addError(TemplateError.fromException(new TemplateSyntaxException(expression.substring(e.getPosition() - EXPRESSION_START_TOKEN.length()),
          "Error parsing '" + expression + "': " + errorMessage, interpreter.getLineNumber(), position, e)));
    }
    catch (ELException e) {
      if (e.getCause() != null && e.getCause() instanceof DeferredValueException) {
        throw (DeferredValueException) e.getCause();
      }
      if (e.getCause() != null && e.getCause() instanceof TemplateSyntaxException) {
        interpreter.addError(TemplateError.fromException((TemplateSyntaxException) e.getCause()));
      }
      else if (e.getCause() != null && e.getCause() instanceof InvalidInputException) {
        interpreter.addError(TemplateError.fromInvalidInputException((InvalidInputException) e.getCause()));
      }
      else if (e.getCause() != null && e.getCause() instanceof InvalidArgumentException) {
        interpreter.addError(TemplateError.fromInvalidArgumentException((InvalidArgumentException) e.getCause()));
      }
      else {
        interpreter.addError(TemplateError.fromException(new TemplateSyntaxException(expression, e.getMessage(), interpreter.getLineNumber(), e)));
      }
    }
    catch (DisabledException e) {
      interpreter.addError(new TemplateError(ErrorType.FATAL, ErrorReason.DISABLED, ErrorItem.FUNCTION, e.getMessage(), expression, interpreter.getLineNumber(), interpreter.getPosition(), e));
    } catch (UnknownTokenException e) {
      // Re-throw the exception because you only get this when the config failOnUnknownTokens is enabled.
      throw e;
    } catch (DeferredValueException e) {
      // Re-throw so that it can be handled in JinjavaInterpreter
      throw e;
    } catch (InvalidInputException e) {
      interpreter.addError(TemplateError.fromInvalidInputException(e));
    } catch (InvalidArgumentException e) {
      interpreter.addError(TemplateError.fromInvalidArgumentException(e));
    } catch (Exception e) {
      interpreter.addError(TemplateError.fromException(new InterpretException(
          String.format("Error resolving expression [%s]: " + getRootCauseMessage(e), expression), e, interpreter.getLineNumber(), interpreter.getPosition())));
    }

    return null;
  }
708123
public StringExpression substring(Expression<Integer> beginIndex, Expression<Integer> endIndex) {
        return Expressions.stringOperation(Ops.SUBSTR_2ARGS, mixin, beginIndex, endIndex);
    }