@Override
	public ReValue unaryOperation(@Nonnull AbstractInsnNode insn, @Nonnull ReValue value) throws AnalyzerException {
		switch (insn.getOpcode()) {
			case IINC: {
				int incr = ((IincInsnNode) insn).incr;
				if (value instanceof IntValue iv) return iv.add(incr);
				return IntValue.UNKNOWN;
			}
			case INEG:
				if (value instanceof IntValue iv) return iv.negate();
				return IntValue.UNKNOWN;
			case L2I:
				if (value instanceof LongValue lv) return lv.castInt();
				return IntValue.UNKNOWN;
			case F2I:
				if (value instanceof FloatValue fv) return fv.castInt();
				return IntValue.UNKNOWN;
			case D2I:
				if (value instanceof DoubleValue dv) return dv.castInt();
				return IntValue.UNKNOWN;
			case I2B:
				if (value instanceof IntValue iv) return iv.castByte();
				return IntValue.UNKNOWN;
			case I2C:
				if (value instanceof IntValue iv) return iv.castChar();
				return IntValue.UNKNOWN;
			case I2S:
				if (value instanceof IntValue iv) return iv.castShort();
				return IntValue.UNKNOWN;
			case FNEG:
				if (value instanceof FloatValue fv) return fv.negate();
				return FloatValue.UNKNOWN;
			case I2F:
				if (value instanceof IntValue iv) return iv.castFloat();
				return FloatValue.UNKNOWN;
			case L2F:
				if (value instanceof LongValue lv) return lv.castFloat();
				return FloatValue.UNKNOWN;
			case D2F:
				if (value instanceof DoubleValue dv) return dv.castFloat();
				return FloatValue.UNKNOWN;
			case LNEG:
				if (value instanceof LongValue lv) return lv.negate();
				return LongValue.UNKNOWN;
			case I2L:
				if (value instanceof IntValue iv) return iv.castLong();
				return LongValue.UNKNOWN;
			case F2L:
				if (value instanceof FloatValue fv) return fv.castLong();
				return LongValue.UNKNOWN;
			case D2L:
				if (value instanceof DoubleValue dv) return dv.castLong();
				return LongValue.UNKNOWN;
			case DNEG:
				if (value instanceof DoubleValue dv) return dv.negate();
				return DoubleValue.UNKNOWN;
			case I2D:
				if (value instanceof IntValue iv) return iv.castDouble();
				return DoubleValue.UNKNOWN;
			case L2D:
				if (value instanceof LongValue lv) return lv.castDouble();
				return DoubleValue.UNKNOWN;
			case F2D:
				if (value instanceof FloatValue fv) return fv.castDouble();
				return DoubleValue.UNKNOWN;
			case IFEQ:
			case IFNE:
			case IFLT:
			case IFGE:
			case IFGT:
			case IFLE:
			case TABLESWITCH:
			case LOOKUPSWITCH:
			case IRETURN:
			case LRETURN:
			case FRETURN:
			case DRETURN:
			case ARETURN:
			case PUTSTATIC:
				return null;
			case MONITORENTER:
			case MONITOREXIT:
			case IFNULL:
			case IFNONNULL:
				return null;
			case ATHROW:
				return null;
			case GETFIELD: {
				FieldInsnNode field = (FieldInsnNode) insn;
				if (getFieldLookup != null && value.hasKnownValue())
					return getFieldLookup.get(field, value);
				Type fieldType = Type.getType(field.desc);
				return newValue(fieldType);
			}
			case NEWARRAY:
				int arrayKind = ((IntInsnNode) insn).operand;
				if (value instanceof IntValue length) {
					OptionalInt lengthValue = length.value();
					if (lengthValue.isPresent()) {
						Type type = switch (arrayKind) {
							case T_BOOLEAN -> Types.ARRAY_1D_BOOLEAN;
							case T_CHAR -> Types.ARRAY_1D_CHAR;
							case T_BYTE -> Types.ARRAY_1D_BYTE;
							case T_SHORT -> Types.ARRAY_1D_SHORT;
							case T_INT -> Types.ARRAY_1D_INT;
							case T_FLOAT -> Types.ARRAY_1D_FLOAT;
							case T_DOUBLE -> Types.ARRAY_1D_DOUBLE;
							case T_LONG -> Types.ARRAY_1D_LONG;
							default -> throw new AnalyzerException(insn, "Invalid array type");
						};
						return ArrayValue.of(type, Nullness.NOT_NULL, lengthValue.getAsInt());
					}
				}
				return switch (arrayKind) {
					case T_BOOLEAN -> ArrayValue.VAL_BOOLEANS;
					case T_CHAR -> ArrayValue.VAL_CHARS;
					case T_BYTE -> ArrayValue.VAL_BYTES;
					case T_SHORT -> ArrayValue.VAL_SHORTS;
					case T_INT -> ArrayValue.VAL_INTS;
					case T_FLOAT -> ArrayValue.VAL_FLOATS;
					case T_DOUBLE -> ArrayValue.VAL_DOUBLES;
					case T_LONG -> ArrayValue.VAL_LONGS;
					default -> throw new AnalyzerException(insn, "Invalid array type");
				};
			case ANEWARRAY: {
				Type arrayType = Type.getType("[" + Type.getObjectType(((TypeInsnNode) insn).desc));
				return newValue(arrayType, Nullness.NOT_NULL);
			}
			case ARRAYLENGTH:
				if (value instanceof ArrayValue array) {
					OptionalInt firstDimensionLength = array.getFirstDimensionLength();
					if (firstDimensionLength.isPresent())
						return IntValue.of(firstDimensionLength.getAsInt());
				}
				return IntValue.UNKNOWN;
			case CHECKCAST:
				Type targetType = Type.getObjectType(((TypeInsnNode) insn).desc);
				return newValue(targetType);
			case INSTANCEOF:
				return IntValue.UNKNOWN;
			default:
				throw new AnalyzerException(insn, "Unknown unary op: " + insn.getOpcode());
		}
	}
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