docs: protected TypeCodec<?> createCodec(
        DataType cqlType, GenericType<?> javaType, boolean isJavaCovariant) {
      LOG.trace("[{}] Cache miss, creating codec", logPrefix);
      // Either type can be null, but not both.
      if (javaType == null) {
        assert cqlType != null;
        return createCodec(cqlType);
      } else if (cqlType == null) {
        return createCodec(javaType, isJavaCovariant);
      } else { // Both non-null
        TypeToken<?> token = javaType.__getToken();
        if (cqlType instanceof ListType && List.class.isAssignableFrom(token.getRawType())) {
          DataType elementCqlType = ((ListType) cqlType).getElementType();
          TypeCodec<Object> elementCodec;
          if (token.getType() instanceof ParameterizedType) {
            Type[] typeArguments = ((ParameterizedType) token.getType()).getActualTypeArguments();
            GenericType<?> elementJavaType = GenericType.of(typeArguments[0]);
            elementCodec = uncheckedCast(codecFor(elementCqlType, elementJavaType, isJavaCovariant));
          } else {
            elementCodec = codecFor(elementCqlType);
          }
          return TypeCodecs.listOf(elementCodec);
        } else if (cqlType instanceof SetType && Set.class.isAssignableFrom(token.getRawType())) {
          DataType elementCqlType = ((SetType) cqlType).getElementType();
          TypeCodec<Object> elementCodec;
          if (token.getType() instanceof ParameterizedType) {
            Type[] typeArguments = ((ParameterizedType) token.getType()).getActualTypeArguments();
            GenericType<?> elementJavaType = GenericType.of(typeArguments[0]);
            elementCodec = uncheckedCast(codecFor(elementCqlType, elementJavaType, isJavaCovariant));
          } else {
            elementCodec = codecFor(elementCqlType);
          }
          return TypeCodecs.setOf(elementCodec);
        } else if (cqlType instanceof MapType && Map.class.isAssignableFrom(token.getRawType())) {
          DataType keyCqlType = ((MapType) cqlType).getKeyType();
          DataType valueCqlType = ((MapType) cqlType).getValueType();
          TypeCodec<Object> keyCodec;
          TypeCodec<Object> valueCodec;
          if (token.getType() instanceof ParameterizedType) {
            Type[] typeArguments = ((ParameterizedType) token.getType()).getActualTypeArguments();
            GenericType<?> keyJavaType = GenericType.of(typeArguments[0]);
            GenericType<?> valueJavaType = GenericType.of(typeArguments[1]);
            keyCodec = uncheckedCast(codecFor(keyCqlType, keyJavaType, isJavaCovariant));
            valueCodec = uncheckedCast(codecFor(valueCqlType, valueJavaType, isJavaCovariant));
          } else {
            keyCodec = codecFor(keyCqlType);
            valueCodec = codecFor(valueCqlType);
          }
          return TypeCodecs.mapOf(keyCodec, valueCodec);
        } else if (cqlType instanceof TupleType
            && TupleValue.class.isAssignableFrom(token.getRawType())) {
          return TypeCodecs.tupleOf((TupleType) cqlType);
        } else if (cqlType instanceof UserDefinedType
            && UdtValue.class.isAssignableFrom(token.getRawType())) {
          return TypeCodecs.udtOf((UserDefinedType) cqlType);
        } else if (cqlType instanceof CustomType
            && ByteBuffer.class.isAssignableFrom(token.getRawType())) {
          return TypeCodecs.custom(cqlType);
        }
        throw new CodecNotFoundException(cqlType, javaType);
      }
    }