gt: 					if (theChar < 'A')
context: /**
   * Copyright (C) 2010-2015 Gordon Fraser, Andrea Arcuri and EvoSuite
   * contributors
   *
   * This file is part of EvoSuite.
   *
   * EvoSuite is free software: you can redistribute it and/or modify it
   * under the terms of the GNU Lesser Public License as published by the
   * Free Software Foundation, either version 3.0 of the License, or (at your
   * option) any later version.
   *
   * EvoSuite is distributed in the hope that it will be useful, but
   * WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
   * Lesser Public License for more details.
   *
   * You should have received a copy of the GNU Lesser Public License along
   * with EvoSuite. If not, see <http://www.gnu.org/licenses/>.
   */
  package org.evosuite.symbolic.expr;
  
  import java.util.StringTokenizer;
  import java.util.Vector;
  
  import org.evosuite.symbolic.expr.bv.IntegerConstant;
  import org.evosuite.symbolic.expr.bv.IntegerUnaryExpression;
  import org.evosuite.symbolic.expr.bv.StringBinaryComparison;
  import org.evosuite.symbolic.expr.bv.StringBinaryToIntegerExpression;
  import org.evosuite.symbolic.expr.bv.StringMultipleComparison;
  import org.evosuite.symbolic.expr.bv.StringMultipleToIntegerExpression;
  import org.evosuite.symbolic.expr.bv.StringUnaryToIntegerExpression;
  import org.evosuite.symbolic.expr.reader.StringReaderExpr;
  import org.evosuite.symbolic.expr.str.StringValue;
  import org.evosuite.symbolic.expr.token.HasMoreTokensExpr;
  import org.evosuite.symbolic.expr.token.TokenizerExpr;
  import org.evosuite.utils.RegexDistanceUtils;
  import org.slf4j.Logger;
  import org.slf4j.LoggerFactory;
  
  public class DistanceCalculator implements ConstraintVisitor<Object, Void> {
  
  	static Logger log = LoggerFactory.getLogger(DistanceCalculator.class);
  
  	@Override
  	public Object visit(IntegerConstraint n, Void arg) {
  
  		ExpressionExecutor visitor = new ExpressionExecutor();
  		long leftVal = (Long) n.getLeftOperand().accept(visitor, null);
  		long rightVal = (Long) n.getRightOperand().accept(visitor, null);
  
  		// special integer constraint: string indexOf char != -1
  		long distance = getDistanceIndexOfCFound(n, leftVal, rightVal);
  		if (distance != -1)
  			return distance;
  
  		// special integer constraint: string indexOfCI char index != -1
  		distance = getDistanceIndexOfCIFound(n, leftVal, rightVal);
  		if (distance != -1)
  			return distance;
  
  		// special integer constraint: string indexOf char == k (k>-1)
  		distance = getDistanceIndexOfCEqualsK(n, leftVal, rightVal);
  		if (distance != -1)
  			return distance;
  
  		// special integer constraint: string indexOf char int == k (k>-1)
  		distance = getDistanceIndexOfCIEqualsK(n, leftVal, rightVal);
  		if (distance != -1)
  			return distance;
  
  		// special case: regex
  		distance = getDistanceRegex(n, leftVal, rightVal);
  		if (distance != -1)
  			return distance;
  
  		// special cases: reader.read()==-1
  		// special cases: reader.read()!=-1
  		distance = getDistanceStringReaderLength(n, leftVal, rightVal);
  		if (distance != -1)
  			return distance;
  
  		distance = getDistanceStringIsInteger(n, leftVal, rightVal);
  		if (distance != -1)
  			return distance;
  
  		Comparator cmpr = n.getComparator();
  		log.debug("Calculating distance for " + leftVal + " " + cmpr + " "
  				+ rightVal);
  
  		switch (cmpr) {
  
  		case EQ:
  
  			return Math.abs(leftVal - rightVal);
  		case NE:
  
  			return (leftVal - rightVal) != 0 ? (long) 0 : (long) 1;
  		case LT:
  
  			return leftVal - rightVal < 0 ? 0 : leftVal - rightVal + 1;
  		case LE:
  
  			return leftVal - rightVal <= 0 ? 0 : leftVal - rightVal;
  		case GT:
  
  			return leftVal - rightVal > 0 ? 0 : rightVal - leftVal + 1;
  		case GE:
  
  			return leftVal - rightVal >= 0 ? 0 : rightVal - leftVal;
  
  		default:
  			log.warn("getIntegerDist: unimplemented comparator");
  			return Long.MAX_VALUE;
  		}
  	}
  
  	private static long getDistanceStringIsInteger(IntegerConstraint n,
  			long leftVal, long rightVal) {
  
  		if (n.getLeftOperand() instanceof StringUnaryToIntegerExpression
  				&& n.getComparator() == Comparator.NE
  				&& n.getRightOperand() instanceof IntegerConstant) {
  			IntegerConstant right_constant = (IntegerConstant) n
  					.getRightOperand();
  			StringUnaryToIntegerExpression left_string_expr = (StringUnaryToIntegerExpression) n
  					.getLeftOperand();
  
  			if (right_constant.getConcreteValue().longValue() != 0L) {
  				return -1;
  			}
  
  			if (left_string_expr.getOperator() != Operator.IS_INTEGER) {
  				return -1;
  			}
  
  			String string = left_string_expr.getOperand().getConcreteValue();
  			if (string.length() > 0) {
  				char[] charArray = string.toCharArray();
  				int maxDistance = 0;
  				for (int i = 0; i < charArray.length; i++) {
  					char c = charArray[i];
  					int distance;
  					if (!Character.isDigit(c)) {
  						if (c < '0') {
  							distance = '0' - c;
  						} else if (c > '9') {
  							distance = c - '9';
  						} else {
  							throw new RuntimeException(
  									"This branch is unreachable!");
  						}
  						if (maxDistance < distance) {
  							maxDistance = distance;
  						}
  					}
  				}
  				return maxDistance;
  			} else {
  				return Long.MAX_VALUE;
  			}
  
  		}
  		return -1;
  	}
  
  	@Override
  	public Object visit(RealConstraint n, Void arg) {
  		ExpressionExecutor visitor = new ExpressionExecutor();
  		double left = (Double) n.getLeftOperand().accept(visitor, null);
  		double right = (Double) n.getRightOperand().accept(visitor, null);
  
  		Comparator cmpr = n.getComparator();
  
  		switch (cmpr) {
  
  		case EQ:
  
  			return Math.abs(left - right);
  		case NE:
  
  			return (left - right) != 0 ? (double) 0 : (double) 1;
  		case LT:
  
  			return left - right < 0 ? 0 : left - right + 1;
  		case LE:
  
  			return left - right <= 0 ? 0 : left - right;
  		case GT:
  
  			return left - right > 0 ? 0 : right - left + 1;
  		case GE:
  
  			return left - right >= 0 ? 0 : right - left;
  
  		default:
  			log.warn("getIntegerDist: unimplemented comparator");
  			return Double.MAX_VALUE;
  		}
  
  	}
  
  	@Override
  	public Object visit(StringConstraint n, Void arg) {
  		Expression<?> exprLeft = n.getLeftOperand();
  		Comparator cmpr = n.getComparator();
  		double distance = 0.0;
  
  		if (exprLeft instanceof StringBinaryComparison) {
  			StringBinaryComparison scTarget = (StringBinaryComparison) exprLeft;
  			distance = getStringDistance(scTarget);
  			log.debug("Calculating distance of constraint " + n);
  		} else if (exprLeft instanceof StringMultipleComparison) {
  			StringMultipleComparison scTarget = (StringMultipleComparison) exprLeft;
  			distance = getStringDistance(scTarget);
  			log.debug("Calculating distance of constraint " + n);
  		} else if (exprLeft instanceof HasMoreTokensExpr) {
  			HasMoreTokensExpr hasMoreTokensExpr = (HasMoreTokensExpr) exprLeft;
  			distance = getStringDistance(hasMoreTokensExpr);
  			log.debug("Calculating distance of constraint " + n);
  		} else {
  			assert (false) : "Invalid string comparison";
  		}
  		assert (((Long) n.getRightOperand().getConcreteValue()).intValue() == 0);
  		if (cmpr == Comparator.NE) {
  			return distance;
  		} else {
  			// if we don't want to satisfy return 0
  			// if not satisfied Long.MAX_VALUE else
  			return distance > 0 ? 0.0 : Double.MAX_VALUE;
  		}
  
  	}
  
  	private static long getDistanceIndexOfCEqualsK(IntegerConstraint n,
  			long leftVal, long rightVal) {
  		if (n.getLeftOperand() instanceof StringBinaryToIntegerExpression
  				&& n.getComparator() == Comparator.EQ
  				&& n.getRightOperand() instanceof IntegerConstant) {
  			IntegerConstant right_constant = (IntegerConstant) n
  					.getRightOperand();
  			StringBinaryToIntegerExpression left_string_expr = (StringBinaryToIntegerExpression) n
  					.getLeftOperand();
  
  			if (left_string_expr.getOperator() == Operator.INDEXOFC) {
  
  				Expression<?> theSymbolicString = left_string_expr
  						.getLeftOperand();
  				Expression<?> theSymbolicChar = left_string_expr
  						.getRightOperand();
  				Expression<?> theSymbolicIndex = right_constant;
  
  				// check theString.lenght>0
  				ExpressionExecutor exprExecutor = new ExpressionExecutor();
  				String theConcreteString = (String) theSymbolicString.accept(
  						exprExecutor, null);
  				Long theConcreteIndex = (Long) theSymbolicIndex.accept(
  						exprExecutor, null);
  				if (theConcreteIndex > theConcreteString.length() - 1) {
  					// there is no char at the index to modify
  					return Long.MAX_VALUE;
  				} else if (theConcreteIndex != -1) {
  					int theIndex = theConcreteIndex.intValue();
  					char theConcreteChar = (char) ((Long) theSymbolicChar
  							.accept(exprExecutor, null)).longValue();
  					char theCurrentChar = theConcreteString.charAt(theIndex);
  					return Math.abs(theCurrentChar - theConcreteChar);
  				}
  			}
  		}
  
  		return -1;
  	}
  
  	private static long getDistanceRegex(IntegerConstraint n, long leftVal,
  			long rightVal) {
  		ExpressionExecutor exprExecutor = new ExpressionExecutor();
  
  		if (n.getLeftOperand() instanceof IntegerUnaryExpression) {
  			if (((IntegerUnaryExpression) n.getLeftOperand()).getOperator() == Operator.ISDIGIT) {
  				Long leftObject = (Long) ((IntegerUnaryExpression) n
  						.getLeftOperand()).getOperand().accept(exprExecutor,
  						null);
  				long left_operand = leftObject.longValue();
  				char theChar = (char) left_operand;
  				if ((n.getComparator() == Comparator.EQ && rightVal == 1L)
  						|| (n.getComparator() == Comparator.NE && rightVal == 0L)) {
  					if (theChar < '0')
  						return '0' - theChar;
  					else if (theChar > '9')
  						return theChar - '9';
  					else
  						return 0;
  				} else if ((n.getComparator() == Comparator.EQ && rightVal == 0L)
  						|| (n.getComparator() == Comparator.NE && rightVal == 1L)) {
  					if (theChar < '0' || theChar > '9')
  						return 0;
  					else
  						return Math.min(Math.abs('9' - theChar),
  								Math.abs(theChar - '0'));
  				}
  
  			} else if (((IntegerUnaryExpression) n.getLeftOperand())
  					.getOperator() == Operator.ISLETTER) {
  				Long leftObject = (Long) ((IntegerUnaryExpression) n
  						.getLeftOperand()).getOperand().accept(exprExecutor,
  						null);
  				long left_operand = leftObject.longValue();
  				char theChar = (char) left_operand;
  				if ((n.getComparator() == Comparator.EQ && rightVal == 1L)
  						|| (n.getComparator() == Comparator.NE && rightVal == 0L)) {
  