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

        Optional<JsonCipherSuite> possibleJsonCipherSuite = findCipherSuite(str);
        if (possibleJsonCipherSuite.isEmpty()) {
            // return a 'simple' cipher object
            return Optional.empty(); // TODO
        }
        final JsonCipherSuite jsonCipherSuite = possibleJsonCipherSuite.get();

        List<INode> assets = new ArrayList<>();
        // key agreement
        jsonCipherSuite
                .getKexAlgorithm()
                .flatMap(
                        algoStr -> {
                            final KeyExchangeAlgorithmMapper keyExchangeAlgorithmMapper =
                                    new KeyExchangeAlgorithmMapper();
                            return keyExchangeAlgorithmMapper.parse(algoStr, detectionLocation);
                        })
                .ifPresent(assets::add);
        // authentication agreement
        jsonCipherSuite
                .getAuthAlgorithm()
                .flatMap(
                        algoStr -> {
                            final AuthenticationAlgorithmMapper authenticationAlgorithmMapper =
                                    new AuthenticationAlgorithmMapper();
                            return authenticationAlgorithmMapper.parse(algoStr, detectionLocation);
                        })
                .ifPresent(assets::add);
        // encryption algorithm
        jsonCipherSuite
                .getEncAlgorithm()
                .flatMap(
                        algoStr -> {
                            final EncryptionAlgorithmMapper encryptionAlgorithmMapper =
                                    new EncryptionAlgorithmMapper();
                            return encryptionAlgorithmMapper.parse(algoStr, detectionLocation);
                        })
                .ifPresent(assets::add);
        // hash algorithm
        jsonCipherSuite
                .getHashAlgorithm()
                .flatMap(
                        algoStr -> {
                            final HashAlgorithmMapper hashAlgorithmMapper =
                                    new HashAlgorithmMapper();
                            return hashAlgorithmMapper.parse(algoStr, detectionLocation);
                        })
                .ifPresent(assets::add);

        final CipherSuite cipherSuite =
                new CipherSuite(
                        jsonCipherSuite.getIanaName(),
                        new AssetCollection(assets),
                        detectionLocation);
        jsonCipherSuite
                .getIdentifiers()
                .flatMap(
                        ids -> {
                            final List<Identifier> identifiers =
                                    Arrays.stream(ids)
                                            .map(idStr -> new Identifier(idStr, detectionLocation))
                                            .toList();
                            return Optional.of(identifiers.stream());
                        })
                .map(identifierStream -> new IdentifierCollection(identifierStream.toList()))
                .ifPresent(cipherSuite::put);

        return Optional.of(cipherSuite);
    }
@Test
    public void test1() {
        DetectionLocation testDetectionLocation =
                new DetectionLocation("testfile", 1, 1, List.of("test"), () -> "SSL");

        final CipherSuiteMapper mapper = new CipherSuiteMapper();
        final Optional<? extends INode> node =
                mapper.parse("TLS_DHE_DSS_WITH_AES_256_CBC_SHA256", testDetectionLocation);
        assertThat(node).isPresent();
        assertThat(node.get().is(CipherSuite.class)).isTrue();
        final CipherSuite cipherSuite = (CipherSuite) node.get();

        assertThat(cipherSuite.getAssetCollection()).isPresent();
        assertThat(cipherSuite.getIdentifierCollection()).isPresent();

        final List<INode> assetCollection = cipherSuite.getAssetCollection().get().getCollection();
        final List<Identifier> identifierCollection =
                cipherSuite.getIdentifierCollection().get().getCollection();
        assertThat(assetCollection).isNotEmpty();
        assertThat(identifierCollection).isNotEmpty();

        assertThat(identifierCollection.stream().map(Identifier::asString))
                .contains("0x00", "0x6A");

        assertThat(assetCollection)
                .contains(
                        new AES(testDetectionLocation),
                        new DSA(testDetectionLocation),
                        new SHA2(256, testDetectionLocation),
                        new DH(KeyAgreement.class, testDetectionLocation));
    }