private static @Nullable JdiValueInfo from(@NotNull Value value,
                                             @NotNull Predicate<? super ClassLoaderReference> classLoaderFilter,
                                             boolean fillSpecial) {
    DfConstantType<?> constant = primitiveConstant(value);
    if (constant != null) {
      return new PrimitiveConstant(constant);
    }
    if (value instanceof StringReference stringReference) {
      return new StringConstant(stringReference.value());
    }
    if (value instanceof ObjectReference ref) {
      ReferenceType type = ref.referenceType();
      if (!classLoaderFilter.test(type.classLoader())) return null;
      String name = type.name();
      String enumConstantName = getEnumConstantName(ref);
      if (enumConstantName != null) {
        return new EnumConstant(type, enumConstantName);
      }
      if (fillSpecial) {
        if (value instanceof ArrayReference) {
          PrimitiveConstant length = new PrimitiveConstant(DfTypes.intValue(((ArrayReference)value).length()));
          return new ObjectWithSpecialField(type, SpecialField.ARRAY_LENGTH, length);
        }
        else if (name.startsWith("java.util.Collections$Empty")) {
          return collectionWithSize(type, 0);
        }
        else if (name.startsWith("java.util.Collections$Singleton")) {
          return collectionWithSize(type, 1);
        }
        else if (COLLECTIONS_WITH_SIZE_FIELD.contains(name)) {
          Value size = getField(ref, "size");
          if (size instanceof IntegerValue) {
            return collectionWithSize(type, ((IntegerValue)size).value());
          }
        }
        else if ("java.util.ImmutableCollections$ListN".equals(name)) {
          Value elements = getField(ref, "elements");
          if (elements instanceof ArrayReference) {
            return collectionWithSize(type, ((ArrayReference)elements).length());
          }
        }
        else if ("java.util.Arrays$ArrayList".equals(name)) {
          Value elements = getField(ref, "a");
          if (elements instanceof ArrayReference) {
            return collectionWithSize(type, ((ArrayReference)elements).length());
          }
        }
        else if (CommonClassNames.JAVA_UTIL_HASH_SET.equals(name) ||
                 "java.util.TreeSet".equals(name)) {
          Value map = getField(ref, CommonClassNames.JAVA_UTIL_HASH_SET.equals(name) ? "map" : "m");
          if (map instanceof ObjectReference) {
            Value size = getField((ObjectReference)map, "size");
            if (size instanceof IntegerValue) {
              return collectionWithSize(type, ((IntegerValue)size).value());
            }
          }
        }
        else if (TypeConversionUtil.isPrimitiveWrapper(name)) {
          DfConstantType<?> wrappedConstant = primitiveConstant(getField(ref, "value"));
          if (wrappedConstant != null) {
            return new ObjectWithSpecialField(type, SpecialField.UNBOX, new PrimitiveConstant(wrappedConstant));
          }
        }
        else if (CommonClassNames.JAVA_UTIL_OPTIONAL.equals(name)) {
          Value wrappedValue = getField(ref, "value");
          if (wrappedValue != null) {
            JdiValueInfo wrappedInfo = from(wrappedValue, classLoaderFilter, false);
            if (wrappedInfo != null) {
              return new ObjectWithSpecialField(type, SpecialField.OPTIONAL_VALUE, wrappedInfo);
            }
          }
        }
      }
      return new ObjectRef(type);
    }
    return null;
  }
private static @Nullable JdiValueInfo from(@NotNull Value value,
                                             @NotNull Predicate<? super ClassLoaderReference> classLoaderFilter,
                                             boolean fillSpecial)