@Nonnull
    @Override
    public Optional<? extends Algorithm> parse(
            @Nullable final String str, @Nonnull DetectionLocation detectionLocation) {
        if (str == null) {
            return Optional.empty();
        }

        // check if it is pbe
        JcaPasswordBasedEncryptionMapper pbeMapper = new JcaPasswordBasedEncryptionMapper();
        Optional<PasswordBasedEncryption> pbeOptional = pbeMapper.parse(str, detectionLocation);
        if (pbeOptional.isPresent()) {
            // pbe
            return pbeOptional;
        }

        if (str.toLowerCase().contains("with") || !str.toLowerCase().contains("hmac")) {
            return Optional.empty();
        }

        final String messageDigestStr =
                str.substring(str.toLowerCase().trim().indexOf("Hmac".toLowerCase()) + 4);

        return switch (messageDigestStr.toUpperCase().trim()) {
            case "MD2" -> Optional.of(new MD2(Mac.class, detectionLocation));
            case "MD5" -> Optional.of(new MD5(Mac.class, detectionLocation));
            case "SHA", "SHA1", "SHA-1" -> Optional.of(new SHA(Mac.class, detectionLocation));
            case "SHA-224", "SHA224" ->
                    Optional.of(new SHA2(Mac.class, new SHA2(224, detectionLocation)));
            case "SHA-256", "SHA256" ->
                    Optional.of(new SHA2(Mac.class, new SHA2(256, detectionLocation)));
            case "SHA-384", "SHA384" ->
                    Optional.of(new SHA2(Mac.class, new SHA2(384, detectionLocation)));
            case "SHA-512", "SHA512" ->
                    Optional.of(new SHA2(Mac.class, new SHA2(512, detectionLocation)));
            case "SHA-512/224", "SHA512/224" ->
                    Optional.of(
                            new SHA2(
                                    Mac.class,
                                    new SHA2(
                                            224,
                                            new SHA2(512, detectionLocation),
                                            detectionLocation)));
            case "SHA-512/256", "SHA512/256" ->
                    Optional.of(
                            new SHA2(
                                    Mac.class,
                                    new SHA2(
                                            256,
                                            new SHA2(512, detectionLocation),
                                            detectionLocation)));
            case "SHA3-224" -> Optional.of(new SHA3(Mac.class, new SHA3(224, detectionLocation)));
            case "SHA3-256" -> Optional.of(new SHA3(Mac.class, new SHA3(256, detectionLocation)));
            case "SHA3-384" -> Optional.of(new SHA3(Mac.class, new SHA3(384, detectionLocation)));
            case "SHA3-512" -> Optional.of(new SHA3(Mac.class, new SHA3(512, detectionLocation)));
            default -> Optional.empty();
        };
    }
@Test
    void pbe() {
        DetectionLocation testDetectionLocation =
                new DetectionLocation("testfile", 1, 1, List.of("test"), () -> "SSL");

        JcaMacMapper jcaMacMapper = new JcaMacMapper();
        Optional<? extends Algorithm> macOptional =
                jcaMacMapper.parse("PBEWithHmacSHA256", testDetectionLocation);

        assertThat(macOptional).isPresent();
        assertThat(macOptional.get().is(PasswordBasedEncryption.class)).isTrue();
        PasswordBasedEncryption pbe = (PasswordBasedEncryption) macOptional.get();

        assertThat(pbe.getDigest()).isEmpty();
        assertThat(pbe.getCipher()).isEmpty();
        assertThat(pbe.getMac()).isPresent();

        Optional<Mac> mac = pbe.getMac();
        assertThat(mac).isPresent();
        assertThat(mac.get().getName()).isEqualTo("HmacSHA256");
        assertThat(mac.get().hasChildren()).isTrue();

        Map<Class<? extends INode>, INode> children = mac.get().getChildren();
        assertThat(children).hasSize(1);
        INode child = children.get(MessageDigest.class);

        assertThat(child.is(MessageDigest.class)).isTrue();
        MessageDigest messageDigest = (MessageDigest) child;
        assertThat(messageDigest).isInstanceOf(SHA2.class);
        assertThat(messageDigest.getName()).isEqualTo("SHA256");
        assertThat(messageDigest.getDigestSize()).isPresent();
        assertThat(messageDigest.getDigestSize().get().getValue()).isEqualTo(256);
    }