@Override
	public ReValue binaryOperation(@Nonnull AbstractInsnNode insn, @Nonnull ReValue value1, @Nonnull ReValue value2) {
		switch (insn.getOpcode()) {
			case IALOAD:
			case BALOAD:
			case CALOAD:
			case SALOAD:
				// We aren't tracking array contents, so nothing to do here.
				return IntValue.UNKNOWN;
			case FALOAD:
				// We aren't tracking array contents, so nothing to do here.
				return FloatValue.UNKNOWN;
			case LALOAD:
				// We aren't tracking array contents, so nothing to do here.
				return LongValue.UNKNOWN;
			case DALOAD:
				// We aren't tracking array contents, so nothing to do here.
				return DoubleValue.UNKNOWN;
			case AALOAD:
				// We aren't tracking array contents, so nothing to do here.
				return ObjectValue.VAL_OBJECT_MAYBE_NULL;
			case IADD:
				if (value1 instanceof IntValue i1 && value2 instanceof IntValue i2) return i1.add(i2);
				return IntValue.UNKNOWN;
			case ISUB:
				if (value1 instanceof IntValue i1 && value2 instanceof IntValue i2) return i1.sub(i2);
				return IntValue.UNKNOWN;
			case IMUL:
				if (value1 instanceof IntValue i1 && value2 instanceof IntValue i2) return i1.mul(i2);
				return IntValue.UNKNOWN;
			case IDIV:
				if (value1 instanceof IntValue i1 && value2 instanceof IntValue i2) return i1.div(i2);
				return IntValue.UNKNOWN;
			case IREM:
				if (value1 instanceof IntValue i1 && value2 instanceof IntValue i2) return i1.rem(i2);
				return IntValue.UNKNOWN;
			case ISHL:
				if (value1 instanceof IntValue i1 && value2 instanceof IntValue i2) return i1.shl(i2);
				return IntValue.UNKNOWN;
			case ISHR:
				if (value1 instanceof IntValue i1 && value2 instanceof IntValue i2) return i1.shr(i2);
				return IntValue.UNKNOWN;
			case IUSHR:
				if (value1 instanceof IntValue i1 && value2 instanceof IntValue i2) return i1.ushr(i2);
				return IntValue.UNKNOWN;
			case IAND:
				if (value1 instanceof IntValue i1 && value2 instanceof IntValue i2) return i1.and(i2);
				return IntValue.UNKNOWN;
			case IOR:
				if (value1 instanceof IntValue i1 && value2 instanceof IntValue i2) return i1.or(i2);
				return IntValue.UNKNOWN;
			case IXOR:
				if (value1 instanceof IntValue i1 && value2 instanceof IntValue i2) return i1.xor(i2);
				return IntValue.UNKNOWN;
			case FADD:
				if (value1 instanceof FloatValue f1 && value2 instanceof FloatValue f2) return f1.add(f2);
				return FloatValue.UNKNOWN;
			case FSUB:
				if (value1 instanceof FloatValue f1 && value2 instanceof FloatValue f2) return f1.sub(f2);
				return FloatValue.UNKNOWN;
			case FMUL:
				if (value1 instanceof FloatValue f1 && value2 instanceof FloatValue f2) return f1.mul(f2);
				return FloatValue.UNKNOWN;
			case FDIV:
				if (value1 instanceof FloatValue f1 && value2 instanceof FloatValue f2) return f1.div(f2);
				return FloatValue.UNKNOWN;
			case FREM:
				if (value1 instanceof FloatValue f1 && value2 instanceof FloatValue f2) return f1.rem(f2);
				return FloatValue.UNKNOWN;
			case LADD:
				if (value1 instanceof LongValue l1 && value2 instanceof LongValue l2) return l1.add(l2);
				return LongValue.UNKNOWN;
			case LSUB:
				if (value1 instanceof LongValue l1 && value2 instanceof LongValue l2) return l1.sub(l2);
				return LongValue.UNKNOWN;
			case LMUL:
				if (value1 instanceof LongValue l1 && value2 instanceof LongValue l2) return l1.mul(l2);
				return LongValue.UNKNOWN;
			case LDIV:
				if (value1 instanceof LongValue l1 && value2 instanceof LongValue l2) return l1.div(l2);
				return LongValue.UNKNOWN;
			case LREM:
				if (value1 instanceof LongValue l1 && value2 instanceof LongValue l2) return l1.rem(l2);
				return LongValue.UNKNOWN;
			case LSHL:
				if (value1 instanceof LongValue l1 && value2 instanceof IntValue l2) return l1.shl(l2);
				if (value1 instanceof LongValue l1 && value2 instanceof LongValue l2) return l1.shl(l2);
				return LongValue.UNKNOWN;
			case LSHR:
				if (value1 instanceof LongValue l1 && value2 instanceof IntValue l2) return l1.shr(l2);
				if (value1 instanceof LongValue l1 && value2 instanceof LongValue l2) return l1.shr(l2);
				return LongValue.UNKNOWN;
			case LUSHR:
				if (value1 instanceof LongValue l1 && value2 instanceof IntValue l2) return l1.ushr(l2);
				if (value1 instanceof LongValue l1 && value2 instanceof LongValue l2) return l1.ushr(l2);
				return LongValue.UNKNOWN;
			case LAND:
				if (value1 instanceof LongValue l1 && value2 instanceof LongValue l2) return l1.and(l2);
				return LongValue.UNKNOWN;
			case LOR:
				if (value1 instanceof LongValue l1 && value2 instanceof LongValue l2) return l1.or(l2);
				return LongValue.UNKNOWN;
			case LXOR:
				if (value1 instanceof LongValue l1 && value2 instanceof LongValue l2) return l1.xor(l2);
				return LongValue.UNKNOWN;
			case DADD:
				if (value1 instanceof DoubleValue d1 && value2 instanceof DoubleValue d2) return d1.add(d2);
				return DoubleValue.UNKNOWN;
			case DSUB:
				if (value1 instanceof DoubleValue d1 && value2 instanceof DoubleValue d2) return d1.sub(d2);
				return DoubleValue.UNKNOWN;
			case DMUL:
				if (value1 instanceof DoubleValue d1 && value2 instanceof DoubleValue d2) return d1.mul(d2);
				return DoubleValue.UNKNOWN;
			case DDIV:
				if (value1 instanceof DoubleValue d1 && value2 instanceof DoubleValue d2) return d1.div(d2);
				return DoubleValue.UNKNOWN;
			case DREM:
				if (value1 instanceof DoubleValue d1 && value2 instanceof DoubleValue d2) return d1.rem(d2);
				return DoubleValue.UNKNOWN;
			case LCMP:
				if (value1 instanceof LongValue l1 && value2 instanceof LongValue l2) return l1.cmp(l2);
				return IntValue.UNKNOWN;
			case FCMPL:
				if (value1 instanceof FloatValue f1 && value2 instanceof FloatValue f2) return f1.cmpl(f2);
				return IntValue.UNKNOWN;
			case FCMPG:
				if (value1 instanceof FloatValue f1 && value2 instanceof FloatValue f2) return f1.cmpg(f2);
				return IntValue.UNKNOWN;
			case DCMPL:
				if (value1 instanceof DoubleValue d1 && value2 instanceof DoubleValue d2) return d1.cmpl(d2);
				return IntValue.UNKNOWN;
			case DCMPG:
				if (value1 instanceof DoubleValue d1 && value2 instanceof DoubleValue d2) return d1.cmpg(d2);
				return IntValue.UNKNOWN;
			case IF_ICMPEQ:
			case IF_ICMPNE:
			case IF_ICMPLT:
			case IF_ICMPGE:
			case IF_ICMPGT:
			case IF_ICMPLE:
			case IF_ACMPEQ:
			case IF_ACMPNE:
			case PUTFIELD:
				// Just popping values, not pushing anything back onto the stack
				return null;
			default:
				throw new AssertionError();
		}
	}
Interpreter implementation for enhanced value tracking.

@author Matt Coley
@see ReValue Base enhanced value type.
recaf-core/src/main/java/software/coley/recaf/util/analysis/ReInterpreter.java