diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
new file mode 100644
index 0000000000000000000000000000000000000000..cff277a189d923b957ea9dd43f6853d414b4aaef
--- /dev/null
+++ b/.gitlab-ci.yml
@@ -0,0 +1,83 @@
+variables:
+  GIT_SUBMODULE_STRATEGY: recursive
+
+stages:
+  - build
+  - test
+  - ragdoc
+  - publish
+
+build:
+  image: openjdk:11
+  stage: build
+  script:
+    - "./gradlew relast"
+    - "./gradlew assemble"
+  artifacts:
+    paths:
+      - "src/gen/java"
+      - "src/gen/jastadd"
+
+test:
+  image: openjdk:11
+  stage: test
+  needs:
+    - build
+  script:
+    - "./gradlew test"
+  artifacts:
+    reports:
+      junit: "*/build/test-results/test/TEST-*.xml"
+    paths:
+      - "src/gen/resources"
+
+ragdoc_build:
+  image:
+    name: "git-st.inf.tu-dresden.de:4567/jastadd/ragdoc-builder"
+    entrypoint: [""]
+  stage: ragdoc
+  needs:
+    - build
+  script:
+    - JAVA_FILES="$(find src/main -name '*.java') $(find src/gen -name '*.java')"
+    - /ragdoc-builder/start-builder.sh -excludeGenerated -d data/ $JAVA_FILES
+  artifacts:
+    paths:
+      - "data/"
+
+ragdoc_view:
+  image:
+    name: "git-st.inf.tu-dresden.de:4567/jastadd/ragdoc-view:relations"
+    entrypoint: [""]
+  stage: ragdoc
+  needs:
+    - ragdoc_build
+  script:
+    - DATA_DIR=$(pwd -P)/data
+    - mkdir -p pages/docs/ragdoc
+    - OUTPUT_DIR=$(pwd -P)/pages/docs/ragdoc
+    - cd /ragdoc-view/src/ && rm -rf data && ln -s $DATA_DIR
+    - /ragdoc-view/build-view.sh --output-path=$OUTPUT_DIR
+  only:
+    - tests/openapi-generator
+    - main
+  artifacts:
+    paths:
+      - "pages/docs/ragdoc"
+
+pages:
+  image: python:3.10.0-bullseye
+  stage: publish
+  needs:
+    - ragdoc_view
+    - test
+  before_script:
+    - pip install -r pages/requirements.txt
+  script:
+    - cd pages && mkdocs build
+  artifacts:
+    paths:
+      - public/
+  only:
+    - tests/openapi-generator
+    - main
diff --git a/build.gradle b/build.gradle
index 372ce4f97e7be6728bfac53d7da818cc9ef36899..20e14f5cc91982f1952861dd75d633be9f46e5c5 100644
--- a/build.gradle
+++ b/build.gradle
@@ -13,28 +13,50 @@ sourceCompatibility = 1.8
 repositories {
     mavenCentral()
     mavenLocal()
+    maven {
+        name 'gitlab-maven'
+        url 'https://git-st.inf.tu-dresden.de/api/v4/groups/jastadd/-/packages/maven'
+    }
 }
 
 dependencies {
-    implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.12.1'
-    implementation group: 'com.fasterxml.jackson.core', name: 'jackson-annotations', version: '2.12.1'
-    implementation group: 'com.fasterxml.jackson.dataformat', name: 'jackson-dataformat-yaml', version: '2.12.1'
-    implementation group: 'net.sf.beaver', name: 'beaver-rt', version: '0.9.11'
-    implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.9.8'
-    implementation group: 'com.fasterxml.jackson.dataformat', name: 'jackson-dataformat-yaml', version: '2.9.8'
-    implementation group: 'org.apache.commons', name: 'commons-collections4', version: '4.4'
-    implementation group: 'com.flipkart.zjsonpatch', name: 'zjsonpatch', version: '0.4.11'
-    implementation group: 'org.openapi4j', name: 'openapi-parser', version: '1.0.7'
-
-    testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: '5.7.0'
-    testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.7.0'
-    testImplementation group: 'com.jayway.jsonpath', name: 'json-path', version: '2.6.0'
+    implementation group: 'com.flipkart.zjsonpatch', name: 'zjsonpatch', version: "${json_patch_version}"
+    implementation group: 'io.swagger.parser.v3', name: 'swagger-parser', version: "${swagger_parser_version}"
+
+    testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: "${junit_jupiter_version}"
+    testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: "${junit_jupiter_version}"
+    testImplementation group: 'com.jayway.jsonpath', name: 'json-path', version: "${json_path_version}"
+}
+
+def versionFile = 'src/main/resources/version.properties'
+def oldProps = new Properties()
+
+try {
+    file(versionFile).withInputStream { stream -> oldProps.load(stream) }
+    version = oldProps['version']
+} catch (e) {
+    // this happens, if either the properties file is not present, or cannot be read from
+    throw new GradleException("File ${versionFile} not found or unreadable. Aborting.", e)
+}
+
+task printVersion() {
+    doLast {
+        println(version)
+    }
+}
+
+task newVersion() {
+    doFirst {
+        def props = new Properties()
+        props['version'] = value
+        props.store(file(versionFile).newWriter(), null)
+    }
 }
 
 buildscript {
     repositories.mavenCentral()
     dependencies {
-        classpath 'org.jastadd:jastaddgradle:1.13.3'
+        classpath "org.jastadd:jastaddgradle:${jastaddgradle_version}"
     }
 }
 
@@ -43,7 +65,7 @@ jar {
   manifest {
     attributes(
       'Class-Path': configurations.compile.collect { it.getName() }.join(' '),
-      'Main-Class': 'de.tudresden.inf.st.openapi'
+      'Main-Class': "${mainClassName}"
     )
   }
 }
@@ -54,6 +76,38 @@ test {
     maxHeapSize = '1G'
 }
 
+// Input and output files for relast
+def relastInputFiles = [
+        "src/main/jastadd/OpenAPISpecification.relast"
+]
+def relastOutputFiles = [
+        "src/gen/jastadd/OpenAPISpecification.ast",
+        "src/gen/jastadd/OpenAPISpecification.jadd"
+]
+
+task relast(type: JavaExec) {
+    classpath = files("libs/relast.jar")
+    group = 'Build'
+
+    doFirst {
+        delete relastOutputFiles
+        mkdir "src/gen/jastadd/"
+    }
+
+    args = [
+            "--listClass=java.util.ArrayList",
+            "--jastAddList=JastAddList",
+            "--useJastAddNames",
+            "--file",
+            "--resolverHelper",
+            "--grammarName=./src/gen/jastadd/RelAst"
+    ] + relastInputFiles
+
+    inputs.files relastInputFiles
+    outputs.files relastOutputFiles
+}
+
+
 File genSrc = file("src/gen/java")
 sourceSets.main.java.srcDir genSrc
 idea.module.generatedSourceDirs += genSrc
@@ -72,20 +126,11 @@ jastadd {
             }
 
             jastadd {
-                basedir "src/main/jastadd/"
-                include "**/*.ast"
-                include "**/*.jadd"
-                include "**/*.jrag"
+                basedir "src/"
+                include "**/**/*.ast"
+                include "**/**/*.jadd"
+                include "**/**/*.jrag"
             }
-
-            scanner {
-                //include "src/main/jastadd/OpenAPISpecification.flex"
-            }
-
-            parser {
-               //include "src/main/jastadd/OpenAPISpecification.parser"
-            }
-
         }
     }
 
@@ -95,10 +140,6 @@ jastadd {
     genDir = 'src/gen/java'
 
     buildInfoDir = 'src/gen-res'
-    parser.name = 'OpenAPIParser'
-
-    scanner.genDir = "src/gen/java/de/tudresden/inf/st/most/jastadd/scanner"
-    parser.genDir = "src/gen/java/de/tudresden/inf/st/most/jastadd/parser"
 
     jastaddOptions = [
             "--lineColumnNumbers",
diff --git a/gradle.properties b/gradle.properties
new file mode 100644
index 0000000000000000000000000000000000000000..7009aabd1bb194a1cc17038702cf1e62b5f8cb75
--- /dev/null
+++ b/gradle.properties
@@ -0,0 +1,5 @@
+json_patch_version = 0.4.11
+swagger_parser_version = 2.0.30
+junit_jupiter_version = 5.7.0
+json_path_version = 2.6.0
+jastaddgradle_version = 1.13.3
\ No newline at end of file
diff --git a/gradlew b/gradlew
old mode 100644
new mode 100755
diff --git a/libs/relast.jar b/libs/relast.jar
new file mode 100644
index 0000000000000000000000000000000000000000..9f1d60c7c99a1e35d9cf5558d5f329c5aa7ba66e
Binary files /dev/null and b/libs/relast.jar differ
diff --git a/pages/custom_theme/footer.html b/pages/custom_theme/footer.html
new file mode 100644
index 0000000000000000000000000000000000000000..2d6c164695b3a1ed19711d3497caf142a8416ebb
--- /dev/null
+++ b/pages/custom_theme/footer.html
@@ -0,0 +1,11 @@
+{% block footer %}
+<p>{% if config.copyright %}
+<small>{{ config.copyright }}<br></small>
+{% endif %}
+<hr>
+Built with <a href="https://www.mkdocs.org/">MkDocs</a> using a <a href="https://github.com/snide/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
+{% if page and page.meta and page.meta.git_revision_date_localized %}
+<small><br><i>Last updated {{ page.meta.git_revision_date_localized }}</i></small>
+{% endif %}
+</p>
+{% endblock %}
diff --git a/pages/docs/fuzzing.md b/pages/docs/fuzzing.md
new file mode 100644
index 0000000000000000000000000000000000000000..c2790638e52ce3198c6631c68a7ff5667c3edc53
--- /dev/null
+++ b/pages/docs/fuzzing.md
@@ -0,0 +1 @@
+fuzzing
\ No newline at end of file
diff --git a/pages/docs/index.md b/pages/docs/index.md
new file mode 100644
index 0000000000000000000000000000000000000000..9f7cda8ed5fcaff95eb3e5566a6609dc61696f6b
--- /dev/null
+++ b/pages/docs/index.md
@@ -0,0 +1 @@
+Index
\ No newline at end of file
diff --git a/pages/mkdocs.yml b/pages/mkdocs.yml
new file mode 100644
index 0000000000000000000000000000000000000000..572435caa3b703e9253452c86f6af7c286d8987a
--- /dev/null
+++ b/pages/mkdocs.yml
@@ -0,0 +1,27 @@
+site_name: RAGO - RAG OpenAPI Framework
+repo_url: https://git-st.inf.tu-dresden.de/jastadd/rago
+site_dir: ../public
+
+nav:
+  - "Overview": index.md
+  - "Fuzzing Example": fuzzing.md
+  - "API documentation": ragdoc/index.html
+
+theme:
+  name: readthedocs
+  custom_dir: custom_theme/
+
+markdown_extensions:
+  - toc:
+      permalink: 
+  - admonition
+  - footnotes
+
+plugins:
+  - search
+  - git-revision-date-localized:
+      type: datetime
+      timezone: Europe/Berlin
+      locale: en
+      fallback_to_build_date: True
+  - macros
diff --git a/pages/requirements.txt b/pages/requirements.txt
new file mode 100644
index 0000000000000000000000000000000000000000..a5b1bbf825def6db5490bd6d87103c08357d879d
--- /dev/null
+++ b/pages/requirements.txt
@@ -0,0 +1,3 @@
+mkdocs==1.2.2
+mkdocs-git-revision-date-localized-plugin==0.10.3
+mkdocs-macros-plugin==0.6.3
diff --git a/src/main/jastadd/Composer.jrag b/src/main/jastadd/Composer.jrag
deleted file mode 100644
index d81b630cbf24e6acaaf427e046155c7f48aeaa1b..0000000000000000000000000000000000000000
--- a/src/main/jastadd/Composer.jrag
+++ /dev/null
@@ -1,998 +0,0 @@
-import org.openapi4j.core.exception.ResolutionException;
-import org.openapi4j.core.validation.ValidationException;
-import org.openapi4j.parser.model.v3.*;
-import org.openapi4j.core.model.reference.Reference;
-import org.openapi4j.core.model.OAIContext;
-
-import java.io.IOException;
-import java.util.*;
-import java.net.URL;
-
-aspect Composer {
-
-  public static OpenApi3 OpenAPIObject.composeOpenAPI (OpenAPIObject openapi){
-    OpenApi3 api3 = new OpenApi3();
-    Map<Object, ASTNode> map = new HashMap<>();
-
-    if (!openapi.getOpenAPI().isEmpty())
-      api3.setOpenapi(openapi.getOpenAPI());
-    if (openapi.hasInfoObject())
-      api3.setInfo(InfoObject.composeInfo(openapi.getInfoObject(), map));
-    if (openapi.getNumServerObject() != 0) {
-      List<org.openapi4j.parser.model.v3.Server> servers = new ArrayList<>();
-      for (ServerObject s : openapi.getServerObjects())
-        servers.add(ServerObject.composeServer(s, map));
-      api3.setServers(servers);
-    }
-    if (openapi.getNumPathsObject() != 0) {
-      Map<String, Path> paths = new HashMap<>();
-      for (PathsObject p : openapi.getPathsObjects())
-        paths.put(p.getRef(), PathItemObject.composePath(p.getPathItemObject(), map));
-      api3.setPaths(paths);
-    }
-    if (openapi.hasComponentsObject())
-      api3.setComponents(ComponentsObject.composeComponents(openapi.getComponentsObject(), map));
-    if (openapi.getNumSecurityRequirementObject() != 0) {
-      List<SecurityRequirement> securityRequirements = new ArrayList<>();
-      for (SecurityRequirementObject s : openapi.getSecurityRequirementObjects())
-        securityRequirements.add(SecurityRequirementObject.composeSecurityRequirement(s, map));
-      api3.setSecurityRequirements(securityRequirements);
-    }
-    if (openapi.getNumTagObject() != 0) {
-      List<org.openapi4j.parser.model.v3.Tag> tags = new ArrayList<>();
-      for (TagObject t : openapi.getTagObjects())
-        tags.add(TagObject.composeTag(t, map));
-      api3.setTags(tags);
-    }
-    if (openapi.hasExternalDocObject())
-      api3.setExternalDocs(ExternalDocObject.composeExternalDocs(openapi.getExternalDocObject(), map));
-    if (openapi.getContext() != null)
-      api3.setContext(openapi.getContext());
-    if (openapi.getNumExtension() != 0) {
-      Map<String, Object> extensionMap = new HashMap<>();
-      for (Extension e : openapi.getExtensions())
-        extensionMap.put(e.getKey(), e.getValue());
-      api3.setExtensions(extensionMap);
-    }
-
-    return api3;
-  }
-
-  public static Info InfoObject.composeInfo (InfoObject infoObject, Map<Object, ASTNode> map){
-    Info info = new Info();
-
-    if (!infoObject.getTitle().isEmpty())
-      info.setTitle(infoObject.getTitle());
-    if (!infoObject.getVersion().isEmpty())
-      info.setVersion(infoObject.getVersion());
-    if (!infoObject.getDescription().isEmpty())
-      info.setDescription(infoObject.getDescription());
-    if (!infoObject.getTermsOfService().isEmpty())
-      info.setTermsOfService(infoObject.getTermsOfService());
-    if (infoObject.hasContactObject())
-      info.setContact(ContactObject.composeContact(infoObject.getContactObject(), map));
-    if (infoObject.hasLicenseObject())
-      info.setLicense(LicenseObject.composeLicense(infoObject.getLicenseObject(), map));
-    if (infoObject.getNumExtension() != 0) {
-      Map<String, Object> extension = new HashMap<>();
-      for (Extension e : infoObject.getExtensions())
-        extension.put(e.getKey(), e.getValue());
-      info.setExtensions(extension);
-    }
-
-    map.put(info, infoObject);
-    return info;
-  }
-
-  public static Contact ContactObject.composeContact (ContactObject contactObject, Map<Object, ASTNode> map){
-    Contact contact = new Contact();
-
-    if (!contactObject.getName().isEmpty())
-      contact.setName(contactObject.getName());
-    if (!contactObject.getUrl().isEmpty())
-      contact.setUrl(contactObject.getUrl());
-    if (!contactObject.getEmail().isEmpty())
-      contact.setEmail(contactObject.getEmail());
-    if (contactObject.getNumExtension() != 0) {
-      Map<String, Object> extensions = new HashMap<>();
-      for (Extension e : contactObject.getExtensions())
-        extensions.put(e.getKey(), e.getValue());
-      contact.setExtensions(extensions);
-    }
-
-    map.put(contact, contactObject);
-    return contact;
-  }
-
-  public static License LicenseObject.composeLicense (LicenseObject licenseObject, Map<Object, ASTNode> map){
-    License license = new License();
-
-    if (!licenseObject.getName().isEmpty())
-      license.setName(licenseObject.getName());
-    if (!licenseObject.getUrl().isEmpty())
-      license.setUrl(licenseObject.getUrl());
-    if (licenseObject.getNumExtension() != 0) {
-      Map<String, Object> extensions = new HashMap<>();
-      for (Extension e : licenseObject.getExtensions())
-        extensions.put(e.getKey(), e.getValue());
-      license.setExtensions(extensions);
-    }
-
-    map.put(license, licenseObject);
-    return license;
-  }
-
-  public static Server ServerObject.composeServer (ServerObject serverObject, Map<Object, ASTNode> map){
-    Server server = new Server();
-
-    if (!serverObject.getUrl().isEmpty())
-      server.setUrl(serverObject.getUrl());
-    if (!serverObject.getDescription().isEmpty())
-      server.setDescription(serverObject.getDescription());
-    if (serverObject.hasServerVariablesTuple()) {
-      Map<String, ServerVariable> serverVariables = new HashMap<>();
-      for (ServerVariablesTuple s : serverObject.getServerVariablesTuples())
-        serverVariables.put(s.getName(), ServerVariableObject.composeServerVariable(s.getServerVariableObject(), map));
-      server.setVariables(serverVariables);
-    }
-    if (serverObject.getNumExtension() != 0) {
-      Map<String, Object> extensions = new HashMap<>();
-      for (Extension e : serverObject.getExtensions())
-        extensions.put(e.getKey(), e.getValue());
-      server.setExtensions(extensions);
-    }
-
-    map.put(server, serverObject);
-    return server;
-  }
-
-  public static ServerVariable ServerVariableObject.composeServerVariable (ServerVariableObject serverVariableObject, Map<Object, ASTNode> map){
-    ServerVariable serverVariable = new ServerVariable();
-
-    if (!serverVariableObject.getDefault().isEmpty())
-      serverVariable.setDefault(serverVariableObject.getDefault());
-    if (!serverVariableObject.getDescription().isEmpty())
-      serverVariable.setDescription(serverVariableObject.getDescription());
-    if (serverVariableObject.getNumEnum() != 0) {
-      List<String> enums = new ArrayList<>();
-      for (Enum e : serverVariableObject.getEnums())
-        enums.add(e.getEnumValue());
-      serverVariable.setEnums(enums);
-    }
-    if (serverVariableObject.getNumExtension() != 0) {
-      Map<String, Object> extensions = new HashMap<>();
-      for (Extension e : serverVariableObject.getExtensions())
-        extensions.put(e.getKey(), e.getValue());
-      serverVariable.setExtensions(extensions);
-    }
-
-    map.put(serverVariable, serverVariableObject);
-    return serverVariable;
-  }
-
-  public static Components ComponentsObject.composeComponents (ComponentsObject componentsObject, Map<Object, ASTNode> map){
-    Components components = new Components();
-
-    if (componentsObject.getNumSchemaTuple() != 0) {
-      Map<String, org.openapi4j.parser.model.v3.Schema> schemaMap = new HashMap<>();
-      SchemaOb s;
-      for (SchemaTuple t : componentsObject.getSchemaTuples()) {
-        s = t.getSchemaOb();
-        if (s instanceof SchemaObject)
-          schemaMap.put(t.getKey(), ((SchemaObject) s).composeSchema(s, map));
-        else
-          schemaMap.put(t.getKey(), ((SchemaReference) s).composeSchema(s, map));
-      }
-      components.setSchemas(schemaMap);
-    }
-    if (componentsObject.getNumResponseTuple() != 0) {
-      Map<String, Response> responseMap = new HashMap<>();
-      ResponseOb r;
-      for (ResponseTuple t : componentsObject.getResponseTuples()) {
-        r = t.getResponseOb();
-        responseMap.put(t.getKey(), r.composeResponse(r, map));
-      }
-      components.setResponses(responseMap);
-    }
-    if (componentsObject.getNumParameterTuple() != 0) {
-      Map<String, Parameter> parameterMap = new HashMap<>();
-      ParameterOb p;
-      for (ParameterTuple t : componentsObject.getParameterTuples()) {
-        p = t.getParameterOb();
-        parameterMap.put(t.getKey(), p.composeParameter(p, map));
-      }
-      components.setParameters(parameterMap);
-    }
-    if (componentsObject.getNumExampleTuple() != 0) {
-      Map<String, Example> exampleMap = new HashMap<>();
-      for (ExampleTuple t : componentsObject.getExampleTuples())
-        exampleMap.put(t.getKey(), ExampleObject.composeExample(t.getExampleObject(), map));
-      components.setExamples(exampleMap);
-    }
-    if (componentsObject.getNumRequestBodyTuple() != 0) {
-      Map<String, RequestBody> requestBodyMap = new HashMap<>();
-      RequestBodyOb r;
-      for (RequestBodyTuple t : componentsObject.getRequestBodyTuples()) {
-        r = t.getRequestBodyOb();
-        requestBodyMap.put(t.getKey(), r.composeRequestBody(r, map));
-      }
-      components.setRequestBodies(requestBodyMap);
-    }
-    if (componentsObject.getNumHeaderTuple() != 0) {
-      Map<String, Header> headerMap = new HashMap<>();
-      HeaderOb h;
-      for (HeaderTuple t : componentsObject.getHeaderTuples()) {
-        h = t.getHeaderOb();
-        headerMap.put(t.getKey(), h.composeHeader(h, map));
-      }
-      components.setHeaders(headerMap);
-    }
-    if (componentsObject.getNumSecuritySchemeTuple() != 0) {
-      Map<String, SecurityScheme> securitySchemeMap = new HashMap<>();
-      SecuritySchemeOb s;
-      for (SecuritySchemeTuple t : componentsObject.getSecuritySchemeTuples()) {
-        s = t.getSecuritySchemeOb();
-        securitySchemeMap.put(t.getKey(), s.composeSecurityScheme(s, map));
-      }
-      components.setSecuritySchemes(securitySchemeMap);
-    }
-    if (componentsObject.getNumLinkTuple() != 0) {
-      Map<String, Link> linkMap = new HashMap<>();
-      LinkOb l;
-      for (LinkTuple t : componentsObject.getLinkTuples()) {
-        l = t.getLinkOb();
-        linkMap.put(t.getKey(), l.composeLink(l, map));
-      }
-      components.setLinks(linkMap);
-    }
-    if (componentsObject.getNumCallbackTuple() != 0) {
-      Map<String, Callback> callbackMap = new HashMap<>();
-      CallbackOb c;
-      for (CallbackTuple t : componentsObject.getCallbackTuples()) {
-        c = t.getCallbackOb();
-        callbackMap.put(t.getKey(), c.composeCallback(c, map));
-      }
-      components.setCallbacks(callbackMap);
-    }
-    if (componentsObject.getNumExtension() != 0) {
-      Map<String, Object> extensions = new HashMap<>();
-      for (Extension e : componentsObject.getExtensions())
-        extensions.put(e.getKey(), e.getValue());
-      components.setExtensions(extensions);
-    }
-
-    return components;
-  }
-
-  public static Path PathItemObject.composePath (PathItemObject pathItem, Map<Object, ASTNode> map){
-    Path path = new Path();
-    PathItemObject p = (PathItemObject) pathItem;
-
-    if (!p.getSummary().isEmpty())
-      path.setSummary(p.getSummary());
-    if (!p.getDescription().isEmpty())
-      path.setDescription(p.getDescription());
-    if (p.hasGet())
-      path.setGet(OperationObject.composeOperation(p.getGet().getOperationObject(), map));
-    if (p.hasPut())
-      path.setPut(OperationObject.composeOperation(p.getPut().getOperationObject(), map));
-    if (p.hasPost())
-      path.setPost(OperationObject.composeOperation(p.getPost().getOperationObject(), map));
-    if (p.hasDelete())
-      path.setDelete(OperationObject.composeOperation(p.getDelete().getOperationObject(), map));
-    if (p.hasOptions())
-      path.setOptions(OperationObject.composeOperation(p.getOptions().getOperationObject(), map));
-    if (p.hasHead())
-      path.setHead(OperationObject.composeOperation(p.getHead().getOperationObject(), map));
-    if (p.hasPatch())
-      path.setPatch(OperationObject.composeOperation(p.getPatch().getOperationObject(), map));
-    if (p.getNumServerObject() != 0) {
-      for (ServerObject s : p.getServerObjects())
-        path.addServer(ServerObject.composeServer(s, map));
-    }
-    if (p.getNumParameterOb() != 0) {
-      for (ParameterOb e : p.getParameterObs())
-        path.addParameter(e.composeParameter(e, map));
-    }
-    if (p.getNumExtension() != 0) {
-      Map<String, Object> extensionMap = new HashMap<>();
-      for (Extension e : p.getExtensions())
-        extensionMap.put(e.getKey(), e.getValue());
-      path.setExtensions(extensionMap);
-    }
-
-    return path;
-  }
-
-  public static Operation OperationObject.composeOperation (OperationObject operationObject, Map<Object, ASTNode> map){
-    Operation operation = new Operation();
-
-    if (operationObject.getNumTag() != 0) {
-      for (de.tudresden.inf.st.openapi.ast.Tag t : operationObject.getTags())
-        operation.addTag(t.getTag());
-    }
-    if (!operationObject.getSummary().isEmpty())
-      operation.setSummary(operationObject.getSummary());
-    if (!operationObject.getDescription().isEmpty())
-      operation.setDescription(operationObject.getDescription());
-    if (operationObject.hasExternalDocObject())
-      operation.setExternalDocs(ExternalDocObject.composeExternalDocs(operationObject.getExternalDocObject(), map));
-    if (!operationObject.getOperationID().isEmpty())
-      operation.setOperationId(operationObject.getOperationID());
-    if (operationObject.getNumParameterOb() != 0) {
-      for (ParameterOb p : operationObject.getParameterObs())
-        operation.addParameter(p.composeParameter(p, map));
-    }
-    if (operationObject.hasRequestBodyOb())
-      operation.setRequestBody(operationObject.getRequestBodyOb().composeRequestBody(operationObject.getRequestBodyOb(), map));
-    if (operationObject.getNumResponseTuple() != 0) {
-      Map<String, Response> responseMap = new HashMap<>();
-      for (ResponseTuple t : operationObject.getResponseTuples())
-        responseMap.put(t.getKey(), t.getResponseOb().composeResponse(t.getResponseOb(), map));
-      operation.setResponses(responseMap);
-    }
-    if (operationObject.getNumCallbackTuple() != 0) {
-      Map<String, Callback> callbacks = new HashMap<>();
-      for (CallbackTuple t : operationObject.getCallbackTuples())
-        callbacks.put(t.getKey(), t.getCallbackOb().composeCallback(t.getCallbackOb(), map));
-      operation.setCallbacks(callbacks);
-    }
-    if (operationObject.getDeprecatedBoolean() != null)
-      operation.setDeprecated(operationObject.getDeprecatedBoolean());
-    if (operationObject.getSecurityRequirementObjects() != null) {
-      for (SecurityRequirementObject s : operationObject.getSecurityRequirementObjects())
-        operation.addSecurityRequirement(SecurityRequirementObject.composeSecurityRequirement(s, map));
-    }
-    if (operationObject.getNumServerObject() != 0) {
-      for (ServerObject s : operationObject.getServerObjects())
-        operation.addServer(ServerObject.composeServer(s, map));
-    }
-    if (operationObject.getNumExtension() != 0) {
-      Map<String, Object> extensionMap = new HashMap<>();
-      for (Extension e : operationObject.getExtensions())
-        extensionMap.put(e.getKey(), e.getValue());
-      operation.setExtensions(extensionMap);
-    }
-
-    return operation;
-  }
-
-  public static ExternalDocs ExternalDocObject.composeExternalDocs (ExternalDocObject externalDocObject, Map<Object, ASTNode> map){
-    ExternalDocs externalDocs = new ExternalDocs();
-
-    if (!externalDocObject.getDescription().isEmpty())
-      externalDocs.setDescription(externalDocObject.getDescription());
-    if (!externalDocObject.getUrl().isEmpty())
-      externalDocs.setUrl(externalDocObject.getUrl());
-    if (externalDocObject.getNumExtension() != 0) {
-      Map<String, Object> extensionMap = new HashMap<>();
-      for (Extension e : externalDocObject.getExtensions())
-        extensionMap.put(e.getKey(), e.getValue());
-      externalDocs.setExtensions(extensionMap);
-    }
-
-    return externalDocs;
-  }
-
-  syn Parameter ParameterOb.composeParameter (ParameterOb parameterOb, Map<Object, ASTNode> map);
-  eq ParameterReference.composeParameter (ParameterOb parameterOb, Map<Object, ASTNode> map) {
-    Parameter parameter = new Parameter();
-    ParameterReference p = (ParameterReference) parameterOb;
-
-    if (!p.getRef().isEmpty()) {
-      try {
-        parameter.setReference(new org.openapi4j.core.model.v3.OAI3Context(new URL("")), new URL(""), p.getRef());
-      } catch (Exception e) {
-        e.printStackTrace();
-      }
-    }
-
-    return parameter;
-  }
-  eq ParameterObject.composeParameter (ParameterOb parameterOb, Map<Object, ASTNode> map) {
-    Parameter parameter = new Parameter();
-    ParameterObject p = (ParameterObject) parameterOb;
-
-    if (!p.getName().isEmpty())
-      parameter.setName(p.getName());
-    if (!p.getIn().isEmpty())
-      parameter.setIn(p.getIn());
-    if (p.getRequired() != null)
-      parameter.setRequired(p.getRequired());
-    if (!p.getDescription().isEmpty())
-      parameter.setDescription(p.getDescription());
-    if (p.getDeprecatedBoolean() != null)
-      parameter.setDeprecated(p.getDeprecatedBoolean());
-    if (!p.getStyle().isEmpty())
-      parameter.setStyle(p.getStyle());
-    if (p.getAllowReserved() != null)
-      parameter.setAllowReserved(p.getAllowReserved());
-    if (p.getExplode() != null)
-      parameter.setExplode(p.getExplode());
-    if (p.getSchemaOb() != null)
-      parameter.setSchema(p.getSchemaOb().composeSchema(p.getSchemaOb(), map));
-    if (p.getExample() != null)
-      parameter.setExample(p.getExample());
-    if (p.getNumExampleTuple() != 0) {
-      Map<String, Example> exampleMap = new HashMap<>();
-      for (ExampleTuple t : p.getExampleTuples())
-        exampleMap.put(t.getKey(), ExampleObject.composeExample(t.getExampleObject(), map));
-      parameter.setExamples(exampleMap);
-    }
-    if (p.getNumContentTuple() != 0) {
-      Map<String, MediaType> contentMap = new HashMap<>();
-      for (ContentTuple t : p.getContentTuples())
-        contentMap.put(t.getKey(), MediaTypeObject.composeMediaType(t.getMediaTypeObject(), map));
-      parameter.setContentMediaTypes(contentMap);
-    }
-    if (p.getRequired() != null)
-      parameter.setRequired(p.getRequired());
-    if (p.getNumExtension() != 0) {
-      Map<String, Object> extensionMap = new HashMap<>();
-      for (Extension e : p.getExtensions())
-        extensionMap.put(e.getKey(), e.getValue());
-      parameter.setExtensions(extensionMap);
-    }
-
-    return parameter;
-  }
-
-  syn RequestBody RequestBodyOb.composeRequestBody (RequestBodyOb requestBodyOb, Map<Object, ASTNode> map);
-  eq RequestBodyReference.composeRequestBody (RequestBodyOb requestBodyOb, Map<Object, ASTNode> map) {
-    RequestBody requestBody = new RequestBody();
-    RequestBodyReference r = (RequestBodyReference) requestBodyOb;
-
-    if (!r.getRef().isEmpty()) {
-      try {
-        requestBody.setReference(new org.openapi4j.core.model.v3.OAI3Context(new URL("")), new URL(""), r.getRef());
-      } catch (Exception e) {
-        e.printStackTrace();
-      }
-    }
-
-    return requestBody;
-  }
-  eq RequestBodyObject.composeRequestBody (RequestBodyOb requestBodyOb, Map<Object, ASTNode> map) {
-    RequestBody requestBody = new RequestBody();
-    RequestBodyObject r = (RequestBodyObject) requestBodyOb;
-
-    if (r.getNumContentTuple() != 0) {
-      Map<String, MediaType> contents = new HashMap<>();
-      for (ContentTuple t : r.getContentTuples())
-        contents.put(t.getKey(), MediaTypeObject.composeMediaType(t.getMediaTypeObject(), map));
-      requestBody.setContentMediaTypes(contents);
-    }
-    if (!r.getDescription().isEmpty())
-      requestBody.setDescription(r.getDescription());
-    if (r.getRequired() != null)
-      requestBody.setRequired(r.getRequired());
-
-    return requestBody;
-  }
-
-  public static MediaType MediaTypeObject.composeMediaType (MediaTypeObject mediaTypeObject, Map<Object, ASTNode> map){
-    MediaType mediaType = new MediaType();
-    SchemaOb s;
-
-    if (mediaTypeObject.getSchemaOb() != null) {
-      s = mediaTypeObject.getSchemaOb();
-      mediaType.setSchema(s.composeSchema(s, map));
-    }
-    if (mediaTypeObject.getExample() != null)
-      mediaType.setExample(mediaTypeObject.getExample());
-    if (mediaTypeObject.getNumExampleTuple() != 0) {
-      Map<String, Example> exampleMap = new HashMap<>();
-      for (ExampleTuple t : mediaTypeObject.getExampleTuples())
-        exampleMap.put(t.getKey(), ExampleObject.composeExample(t.getExampleObject(), map));
-      mediaType.setExamples(exampleMap);
-    }
-    if (mediaTypeObject.getNumEncodingTuple() != 0) {
-      Map<String, EncodingProperty> encodingMap = new HashMap<>();
-      for (EncodingTuple t : mediaTypeObject.getEncodingTuples())
-        encodingMap.put(t.getKey(), EncodingObject.composeEncodingProperty(t.getEncodingObject(), map));
-      mediaType.setEncodings(encodingMap);
-    }
-
-    return mediaType;
-  }
-
-  public static EncodingProperty EncodingObject.composeEncodingProperty (EncodingObject encodingObject, Map<Object, ASTNode> map){
-    EncodingProperty encodingProperty = new EncodingProperty();
-    HeaderOb h;
-
-    if (!encodingObject.getContentType().isEmpty())
-      encodingProperty.setContentType(encodingObject.getContentType());
-    if (encodingObject.getNumHeaderTuple() != 0) {
-      Map<String, Header> headers = new HashMap<>();
-      for (HeaderTuple t : encodingObject.getHeaderTuples()) {
-        h = t.getHeaderOb();
-        headers.put(t.getKey(), h.composeHeader(h, map));
-      }
-      encodingProperty.setHeaders(headers);
-    }
-    if (!encodingObject.getStyle().isEmpty())
-      encodingProperty.setStyle(encodingObject.getStyle());
-    if (encodingObject.getExplode() != null)
-      encodingProperty.setExplode(encodingObject.getExplode());
-    if (encodingObject.getNumExtension() != 0) {
-      Map<String, Object> extensionMap = new HashMap<>();
-      for (Extension e : encodingObject.getExtensions())
-        extensionMap.put(e.getKey(), e.getValue());
-      encodingProperty.setExtensions(extensionMap);
-    }
-
-    return encodingProperty;
-  }
-
-  syn Response ResponseOb.composeResponse (ResponseOb responseOb, Map<Object, ASTNode> map);
-  eq ResponseReference.composeResponse (ResponseOb responseOb, Map<Object, ASTNode> map){
-    Response response = new Response();
-    ResponseReference r = (ResponseReference) responseOb;
-
-    if (!r.getRef().isEmpty()) {
-      try {
-        response.setReference(new org.openapi4j.core.model.v3.OAI3Context(new URL("")), new URL(""), r.getRef());
-      } catch (Exception e) {
-        e.printStackTrace();
-      }
-    }
-
-    return response;
-  }
-  eq ResponseObject.composeResponse (ResponseOb responseOb, Map<Object, ASTNode> map){
-    Response response = new Response();
-    ResponseObject r = (ResponseObject) responseOb;
-
-    if (!r.getDescription().isEmpty())
-      response.setDescription(r.getDescription());
-    if (r.getNumHeaderTuple() != 0) {
-      Map<String, Header> headers = new HashMap<>();
-      for (HeaderTuple t : r.getHeaderTuples())
-        headers.put(t.getKey(), t.getHeaderOb().composeHeader(t.getHeaderOb(), map));
-      response.setHeaders(headers);
-    }
-    if (r.getNumContentTuple() != 0) {
-      Map<String, MediaType> contents = new HashMap<>();
-      for (ContentTuple t : r.getContentTuples())
-        contents.put(t.getKey(), MediaTypeObject.composeMediaType(t.getMediaTypeObject(), map));
-      response.setContentMediaTypes(contents);
-    }
-    if (r.getNumLinkTuple() != 0) {
-      Map<String, Link> links = new HashMap<>();
-      for (LinkTuple t : r.getLinkTuples())
-        links.put(t.getKey(), t.getLinkOb().composeLink(t.getLinkOb(), map));
-      response.setLinks(links);
-    }
-
-    return response;
-  }
-
-  syn Callback CallbackOb.composeCallback (CallbackOb callbackOb, Map<Object, ASTNode> map);
-  eq CallbackReference.composeCallback (CallbackOb callbackOb, Map<Object, ASTNode> map) {
-    Callback callback = new Callback();
-    CallbackReference c = (CallbackReference) callbackOb;
-
-    if (!c.getRef().isEmpty()) {
-      try {
-        callback.setReference(new org.openapi4j.core.model.v3.OAI3Context(new URL("")), new URL(""), c.getRef());
-      } catch (Exception e) {
-        e.printStackTrace();
-      }
-    }
-
-    return callback;
-  }
-  eq CallbackObject.composeCallback (CallbackOb callbackOb, Map<Object, ASTNode> map) {
-    Callback callback = new Callback();
-    CallbackObject c = (CallbackObject) callbackOb;
-
-    if (c.getNumExpression() != 0) {
-      Map<String, Path> paths = new HashMap<>();
-      PathItemObject p;
-      for (Expression e : c.getExpressions()) {
-        p = e.getPathItemObject();
-        paths.put(e.getName(), p.composePath(p, map));
-      }
-      callback.setCallbackPaths(paths);
-    }
-
-    return callback;
-  }
-
-  public static Example ExampleObject.composeExample (ExampleObject exampleObject, Map<Object, ASTNode> map){
-    Example example = new Example();
-
-    if (!exampleObject.getSummary().isEmpty())
-      example.setSummary(exampleObject.getSummary());
-    if (!exampleObject.getDescription().isEmpty())
-      example.setDescription(exampleObject.getDescription());
-    if (exampleObject.getValue() != null)
-      example.setValue(exampleObject.getValue());
-    if (!exampleObject.getExternalValue().isEmpty())
-      example.setExternalValue(exampleObject.getExternalValue());
-    if (exampleObject.getNumExtension() != 0) {
-      Map<String, Object> extension = new HashMap<>();
-      for (Extension e : exampleObject.getExtensions())
-        extension.put(e.getKey(), e.getValue());
-      example.setExtensions(extension);
-    }
-
-    return example;
-  }
-
-  syn Link LinkOb.composeLink (LinkOb linkOb, Map<Object, ASTNode> map);
-  eq LinkReference.composeLink (LinkOb linkOb, Map<Object, ASTNode> map){
-    Link link = new Link();
-    LinkReference l = (LinkReference) linkOb;
-
-    if (!l.getRef().isEmpty()) {
-      try {
-        link.setReference(new org.openapi4j.core.model.v3.OAI3Context(new URL("")), new URL(""), l.getRef());
-      } catch (Exception e) {
-        e.printStackTrace();
-      }
-    }
-
-    return link;
-  }
-  eq LinkObject.composeLink (LinkOb linkOb, Map<Object, ASTNode> map){
-    Link link = new Link();
-    LinkObject l = (LinkObject) linkOb;
-
-    if (!l.getOperationRef().isEmpty())
-      link.setOperationRef(l.getOperationRef());
-    if (!l.getOperationID().isEmpty())
-      link.setOperationId(l.getOperationID());
-    if (l.getNumLinkParameterTuple() != 0) {
-      Map<String, String> parameters = new HashMap<>();
-      for (LinkParameterTuple t : l.getLinkParameterTuples())
-        parameters.put(t.getLinkParameterKey(), t.getLinkParameterValue());
-      link.setParameters(parameters);
-    }
-    if (!l.getDescription().isEmpty())
-      link.setDescription(l.getDescription());
-    if (l.hasServerObject())
-      link.setServer(ServerObject.composeServer(l.getServerObject(), map));
-
-    return link;
-  }
-
-  syn Header HeaderOb.composeHeader (HeaderOb headerOb, Map<Object, ASTNode> map);
-  eq HeaderReference.composeHeader (HeaderOb headerOb, Map<Object, ASTNode> map) {
-    Header header = new Header();
-    HeaderReference h = new HeaderReference();
-
-    if (!h.getRef().isEmpty()) {
-      try {
-        header.setReference(new org.openapi4j.core.model.v3.OAI3Context(new URL("")), new URL(""), h.getRef());
-      } catch (Exception e) {
-        e.printStackTrace();
-      }
-    }
-
-    return header;
-  }
-  eq HeaderObject.composeHeader (HeaderOb headerOb, Map<Object, ASTNode> map) {
-    Header header = new Header();
-    HeaderObject h = (HeaderObject) headerOb;
-
-    if (h.getRequired() != null)
-      header.setRequired(h.getRequired());
-    if (!h.getDescription().isEmpty())
-      header.setDescription(h.getDescription());
-    if (!h.getStyle().isEmpty())
-      header.setStyle(h.getStyle());
-    if (h.getExplode() != null)
-      header.setExplode(h.getExplode());
-    if (h.getAllowReserved() != null)
-      header.setAllowReserved(h.getAllowReserved());
-    if (h.getExample() != null)
-      header.setExample(h.getExample());
-    if (h.getNumExampleTuple() != 0) {
-      Map<String, Example> examples = new HashMap<>();
-      for (ExampleTuple t : h.getExampleTuples())
-        examples.put(t.getKey(), ExampleObject.composeExample(t.getExampleObject(), map));
-      header.setExample(examples);
-    }
-    if (h.getNumContentTuple() != 0) {
-      Map<String, MediaType> contents = new HashMap<>();
-      for (ContentTuple t : h.getContentTuples())
-        contents.put(t.getKey(), MediaTypeObject.composeMediaType(t.getMediaTypeObject(), map));
-      header.setContentMediaTypes(contents);
-    }
-    if (h.hasSchemaOb())
-      header.setSchema(h.getSchemaOb().composeSchema(h.getSchemaOb(), map));
-
-    return header;
-  }
-
-  public static org.openapi4j.parser.model.v3.Tag TagObject.composeTag (TagObject tagObject, Map<Object, ASTNode> map){
-    org.openapi4j.parser.model.v3.Tag tag = new org.openapi4j.parser.model.v3.Tag();
-
-    tag.setName(tagObject.getName());
-
-    if (!tagObject.getDescription().isEmpty())
-      tag.setDescription(tagObject.getDescription());
-    if (tagObject.hasExternalDocObject())
-      tag.setExternalDocs(ExternalDocObject.composeExternalDocs(tagObject.getExternalDocObject(), map));
-    if (tagObject.getNumExtension() != 0) {
-      Map<String, Object> extensionMap = new HashMap<>();
-      for (Extension e : tagObject.getExtensions())
-        extensionMap.put(e.getKey(), e.getValue());
-      tag.setExtensions(extensionMap);
-    }
-
-    return tag;
-  }
-
-  syn org.openapi4j.parser.model.v3.Schema SchemaOb.composeSchema (SchemaOb schemaOb, Map<Object, ASTNode> map);
-  eq SchemaReference.composeSchema (SchemaOb schemaOb, Map<Object, ASTNode> map){
-    org.openapi4j.parser.model.v3.Schema schema = new org.openapi4j.parser.model.v3.Schema();
-    SchemaReference s = (SchemaReference) schemaOb;
-
-    if (!s.getRef().isEmpty()) {
-      try {
-        schema.setReference(new org.openapi4j.core.model.v3.OAI3Context(new URL("")), new URL(""), s.getRef());
-      } catch (Exception e) {
-        e.printStackTrace();
-      }
-    }
-
-    return schema;
-  }
-  eq SchemaObject.composeSchema (SchemaOb schemaOb, Map<Object, ASTNode> map){
-    org.openapi4j.parser.model.v3.Schema schema = new org.openapi4j.parser.model.v3.Schema();
-    SchemaObject s = (SchemaObject) schemaOb;
-
-    if (s.hasAdditionalProperties()) {
-      SchemaOb o = s.getAdditionalProperties().getSchemaOb();
-      if (o instanceof SchemaObject)
-        schema.setAdditionalProperties(((SchemaObject) o).composeSchema(o, map));
-      else
-        schema.setAdditionalProperties(((SchemaReference) o).composeSchema(o, map));
-    }
-    if (s.getAdditionalPropertiesAllowed() != null)
-      schema.setAdditionalPropertiesAllowed(s.getAdditionalPropertiesAllowed());
-    if (s.getDefaultValue() != null)
-      schema.setDefault(s.getDefaultValue());
-    if (!s.getDescription().isEmpty())
-      schema.setDescription(s.getDescription());
-    if (s.getDeprecatedBoolean() != null)
-      schema.setDeprecated(s.getDeprecatedBoolean());
-    if (s.hasDiscriminatorObject())
-      schema.setDiscriminator(DiscriminatorObject.composeDiscriminator(s.getDiscriminatorObject(), map));
-    if (s.getNumEnumObj() != 0) {
-      for (EnumObj e : s.getEnumObjs())
-        schema.addEnum(e.getEnumOb());
-    }
-    if (s.getExample() != null)
-      schema.setExample(s.getExample());
-    if (s.getExclusiveMaximum() != null)
-      schema.setExclusiveMaximum(s.getExclusiveMaximum());
-    if (s.getExclusiveMinimum() != null)
-      schema.setExclusiveMinimum(s.getExclusiveMinimum());
-    if (s.hasExternalDocObject())
-      schema.setExternalDocs(ExternalDocObject.composeExternalDocs(s.getExternalDocObject(), map));
-    if (!s.getFormat().isEmpty())
-      schema.setFormat(s.getFormat());
-    if (s.hasItemsSchema()) {
-      if (s.getItemsSchema().getSchemaOb() instanceof SchemaObject)
-        schema.setItemsSchema(((SchemaObject) s.getItemsSchema().getSchemaOb()).composeSchema(s.getItemsSchema().getSchemaOb(), map));
-      else
-        schema.setItemsSchema(((SchemaReference) s.getItemsSchema().getSchemaOb()).composeSchema(s.getItemsSchema().getSchemaOb(), map));
-    }
-    if (s.getMaximum() != null)
-      schema.setMaximum(s.getMaximum());
-    if (s.getMinimum() != null)
-      schema.setMinimum(s.getMinimum());
-    if (s.getMaxItems() != null)
-      schema.setMaxItems(s.getMaxItems());
-    if (s.getMinItems() != null)
-      schema.setMinItems(s.getMinItems());
-    if (s.getMaxLength() != null)
-      schema.setMaxLength(s.getMaxLength());
-    if (s.getMinLength() != null)
-      schema.setMinLength(s.getMinLength());
-    if (s.getMaxProperties() != null)
-      schema.setMaxProperties(s.getMaxProperties());
-    if (s.getMinProperties() != null)
-      schema.setMinProperties(s.getMinProperties());
-    if (s.getMultipleOf() != null)
-      schema.setMultipleOf(s.getMultipleOf());
-    if (s.hasNotSchema()) {
-      if (s.getNotSchema().getSchemaOb() instanceof SchemaObject)
-        schema.setNotSchema(((SchemaObject) s.getNotSchema().getSchemaOb()).composeSchema(s.getNotSchema().getSchemaOb(), map));
-      else
-        schema.setNotSchema(((SchemaReference) s.getNotSchema().getSchemaOb()).composeSchema(s.getNotSchema().getSchemaOb(), map));
-    }
-    if (s.getNullable() != null)
-      schema.setNullable(s.getNullable());
-    if (!s.getPattern().isEmpty())
-      schema.setPattern(s.getPattern());
-    if (s.getNumPropertyItem() != 0) {
-      Map<String, org.openapi4j.parser.model.v3.Schema> properties = new HashMap<>();
-      for (PropertyItem p : s.getPropertyItemList()) {
-        if (p.getSchemaOb() instanceof SchemaObject)
-          properties.put(p.getName(), ((SchemaObject) p.getSchemaOb()).composeSchema(p.getSchemaOb(), map));
-        else
-          properties.put(p.getName(), ((SchemaReference) p.getSchemaOb()).composeSchema(p.getSchemaOb(), map));
-      }
-      schema.setProperties(properties);
-    }
-    if (s.getNumRequiredField() != 0) {
-      for (RequiredField r : s.getRequiredFields())
-        schema.addRequiredField(r.getValue());
-    }
-    if (s.getNumAllOfSchema() != 0) {
-      for (AllOfSchema a : s.getAllOfSchemas()) {
-        if (a.getSchemaOb() instanceof SchemaObject)
-          schema.addAllOfSchema(((SchemaObject) a.getSchemaOb()).composeSchema(a.getSchemaOb(), map));
-        else
-          schema.addAllOfSchema(((SchemaReference) a.getSchemaOb()).composeSchema(a.getSchemaOb(), map));
-      }
-    }
-    if (s.getNumAnyOfSchema() != 0) {
-      for (AnyOfSchema a : s.getAnyOfSchemas()) {
-        if (a.getSchemaOb() instanceof SchemaObject)
-          schema.addAnyOfSchema(((SchemaObject) a.getSchemaOb()).composeSchema(a.getSchemaOb(), map));
-        else
-          schema.addAnyOfSchema(((SchemaReference) a.getSchemaOb()).composeSchema(a.getSchemaOb(), map));
-      }
-    }
-    if (s.getNumOneOfSchema() != 0) {
-      for (OneOfSchema o : s.getOneOfSchemas()) {
-        if (o.getSchemaOb() instanceof SchemaObject)
-          schema.addOneOfSchema(((SchemaObject) o.getSchemaOb()).composeSchema(o.getSchemaOb(), map));
-        else
-          schema.addOneOfSchema(((SchemaReference) o.getSchemaOb()).composeSchema(o.getSchemaOb(), map));
-      }
-    }
-    if (s.getReadOnly() != null)
-      schema.setReadOnly(s.getReadOnly());
-    if (s.getWriteOnly() != null)
-      schema.setWriteOnly(s.getWriteOnly());
-    if (!s.getType().isEmpty())
-      schema.setType(s.getType());
-    if (!s.getTitle().isEmpty())
-      schema.setTitle(s.getTitle());
-    if (s.getUniqueItems() != null)
-      schema.setUniqueItems(s.getUniqueItems());
-    if (s.hasXmlObject())
-      schema.setXml(XmlObject.composeXml(s.getXmlObject(), map));
-    if (s.getNumExtension() != 0) {
-      Map<String, Object> extensionMap = new HashMap<>();
-      for (Extension e : s.getExtensions())
-        extensionMap.put(e.getKey(), e.getValue());
-      schema.setExtensions(extensionMap);
-    }
-
-    return schema;
-  }
-
-  public static Discriminator DiscriminatorObject.composeDiscriminator (DiscriminatorObject discriminatorObject, Map<Object, ASTNode> map) {
-    Discriminator discriminator = new Discriminator();
-
-    if (!discriminatorObject.getPropertyName().isEmpty())
-      discriminator.setPropertyName(discriminatorObject.getPropertyName());
-    if (discriminatorObject.getNumMappingTuple() != 0) {
-      Map<String, String> mapping = new HashMap<>();
-      for (MappingTuple m : discriminatorObject.getMappingTuples())
-        mapping.put(m.getKey(), m.getValue());
-      discriminator.setMapping(mapping);
-    }
-
-    return discriminator;
-  }
-
-  public static Xml XmlObject.composeXml (XmlObject xmlObject, Map<Object, ASTNode> map) {
-    Xml xml = new Xml();
-
-    if (!xmlObject.getName().isEmpty())
-      xml.setName(xmlObject.getName());
-    if (!xmlObject.getNamespace().isEmpty())
-      xml.setNamespace(xmlObject.getNamespace());
-    if (!xmlObject.getPrefix().isEmpty())
-      xml.setPrefix(xmlObject.getPrefix());
-    if (xmlObject.getAttribute() != null)
-      xml.setAttribute((boolean) xmlObject.getAttribute());
-    if (xmlObject.getWrapped() != null)
-      xml.setWrapped((boolean) xmlObject.getWrapped());
-
-    return xml;
-  }
-
-  syn SecurityScheme SecuritySchemeOb.composeSecurityScheme (SecuritySchemeOb securitySchemeOb, Map<Object, ASTNode> map);
-  eq SecuritySchemeReference.composeSecurityScheme (SecuritySchemeOb securitySchemeOb, Map<Object, ASTNode> map){
-    SecurityScheme securityScheme = new SecurityScheme();
-    SecuritySchemeReference s = (SecuritySchemeReference) securitySchemeOb;
-
-    if (!s.getRef().isEmpty()) {
-      try {
-        securityScheme.setReference(new org.openapi4j.core.model.v3.OAI3Context(new URL("")), new URL(""), s.getRef());
-      } catch (Exception e) {
-        e.printStackTrace();
-      }
-    }
-
-    return securityScheme;
-  }
-  eq SecuritySchemeObject.composeSecurityScheme (SecuritySchemeOb securitySchemeOb, Map<Object, ASTNode> map){
-    SecurityScheme securityScheme = new SecurityScheme();
-    SecuritySchemeObject s = (SecuritySchemeObject) securitySchemeOb;
-
-    if (!s.getType().isEmpty())
-      securityScheme.setType(s.getType());
-    if (!s.getName().isEmpty())
-      securityScheme.setName(s.getName());
-    if (!s.getIn().isEmpty())
-      securityScheme.setIn(s.getIn());
-    if (!s.getScheme().isEmpty())
-      securityScheme.setScheme(s.getScheme());
-    if (!s.getOpenIdConnectUrl().isEmpty())
-      securityScheme.setOpenIdConnectUrl(s.getOpenIdConnectUrl());
-    if (s.getOAuthFlowsObject() != null)
-      securityScheme.setFlows(OAuthFlowsObject.composeOAuthFlows(s.getOAuthFlowsObject(), map));
-    if (!s.getDescription().isEmpty())
-      securityScheme.setDescription(s.getDescription());
-    if (!s.getBearerFormat().isEmpty())
-      securityScheme.setBearerFormat(s.getBearerFormat());
-    if (s.getNumExtension() != 0) {
-      Map<String, Object> extensionMap = new HashMap<>();
-      for (Extension e : s.getExtensions())
-        extensionMap.put(e.getKey(), e.getValue());
-      securityScheme.setExtensions(extensionMap);
-    }
-
-    return securityScheme;
-  }
-
-  public static OAuthFlows OAuthFlowsObject.composeOAuthFlows (OAuthFlowsObject oAuthFlowsObject, Map<Object, ASTNode> map){
-    OAuthFlows oAuthFlows = new OAuthFlows();
-
-    if (oAuthFlowsObject.hasImplicit())
-      oAuthFlows.setImplicit(OAuthFlowObject.composeOAuthFlow(oAuthFlowsObject.getImplicit().getOAuthFlowObject(), map));
-    if (oAuthFlowsObject.hasPassword())
-      oAuthFlows.setPassword(OAuthFlowObject.composeOAuthFlow(oAuthFlowsObject.getPassword().getOAuthFlowObject(), map));
-    if (oAuthFlowsObject.hasClientCredentials())
-      oAuthFlows.setClientCredentials(OAuthFlowObject.composeOAuthFlow(oAuthFlowsObject.getClientCredentials().getOAuthFlowObject(), map));
-    if (oAuthFlowsObject.hasAuthorizationCode())
-      oAuthFlows.setAuthorizationCode(OAuthFlowObject.composeOAuthFlow(oAuthFlowsObject.getAuthorizationCode().getOAuthFlowObject(), map));
-
-    return oAuthFlows;
-  }
-
-  public static OAuthFlow OAuthFlowObject.composeOAuthFlow (OAuthFlowObject oAuthFlowObject, Map<Object, ASTNode> map){
-    OAuthFlow oAuthFlow = new OAuthFlow();
-    Map<String, String> scopes = new HashMap<>();
-
-    if (oAuthFlowObject.getAuthorizationUrl() != null)
-      oAuthFlow.setAuthorizationUrl(oAuthFlowObject.getAuthorizationUrl());
-    if (oAuthFlowObject.getTokenUrl() != null)
-      oAuthFlow.setTokenUrl(oAuthFlowObject.getTokenUrl());
-    for (ScopesTuple t : oAuthFlowObject.getScopesTuples())
-      scopes.put(t.getScopesKey(), t.getScopesValue());
-    oAuthFlow.setScopes(scopes);
-
-    if (oAuthFlowObject.getRefreshUrl() != null)
-      oAuthFlow.setRefreshUrl(oAuthFlowObject.getRefreshUrl());
-
-    return oAuthFlow;
-  }
-
-  public static SecurityRequirement SecurityRequirementObject.composeSecurityRequirement (SecurityRequirementObject securityRequirementObject, Map<Object, ASTNode> map){
-    SecurityRequirement securityRequirement = new SecurityRequirement();
-
-    if (securityRequirementObject.getNumSecurityRequirementTuple() != 0) {
-      Map<String, List<String>> requirements = new HashMap<>();
-      for (SecurityRequirementTuple t : securityRequirementObject.getSecurityRequirementTuples()) {
-        List<String> values = new ArrayList<>();
-        for (SecurityRequirementValue v : t.getSecurityRequirementValues())
-          values.add(v.getValue());
-        requirements.put(t.getName(), values);
-      }
-      securityRequirement.setRequirements(requirements);
-    }
-
-    return securityRequirement;
-  }
-}
\ No newline at end of file
diff --git a/src/main/jastadd/InferParameter.jrag b/src/main/jastadd/InferParameter.jrag
index ba577cb88d446d460cd5441fb0d22a5a999ea370..aa271cb10685d033ce04f2b3957d8df75f0adaa3 100644
--- a/src/main/jastadd/InferParameter.jrag
+++ b/src/main/jastadd/InferParameter.jrag
@@ -1,4 +1,4 @@
-import com.fasterxml.jackson.databind.JsonNode;
+/*import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.node.ArrayNode;
 
@@ -198,4 +198,6 @@ aspect InferParameter{
       System.out.println(e.toString());
     }
   }
-}
\ No newline at end of file
+}
+
+ */
\ No newline at end of file
diff --git a/src/main/jastadd/OpenAPISpecification.ast b/src/main/jastadd/OpenAPISpecification.ast
deleted file mode 100644
index 9ae3e3ee3856a862639b30a3e3c95ec289d00a84..0000000000000000000000000000000000000000
--- a/src/main/jastadd/OpenAPISpecification.ast
+++ /dev/null
@@ -1,143 +0,0 @@
-//OpenAPI Object
-OpenAPIObject ::= <OpenAPI> [InfoObject] ServerObject* PathsObject* [ComponentsObject] SecurityRequirementObject* TagObject* [ExternalDocObject] <Context:OAIContext> Extension* InferredParameter*;
-InferredParameter ::= <Parameter>;
-
-//Info Object
-InfoObject ::= <Title> <Description> <TermsOfService> [ContactObject] [LicenseObject] <Version> Extension*;
-
-//Contact Object
-ContactObject ::= <Name> <Url> <Email> Extension*;
-
-//License Object
-LicenseObject ::= <Name> <Url> Extension*;
-
-//Server Object
-ServerObject ::= <Url> <Description> ServerVariablesTuple* Extension*;
-ServerVariablesTuple ::= <Name> ServerVariableObject;
-
-//Server Variable Object
-ServerVariableObject ::= Enum* <Default> <Description> Extension*;
-Enum ::= <EnumValue>;
-
-//Components Object
-ComponentsObject ::= SchemaTuple* ResponseTuple* ParameterTuple* ExampleTuple* RequestBodyTuple* HeaderTuple* SecuritySchemeTuple* LinkTuple* CallbackTuple* Extension*;
-SchemaTuple ::= <Key> SchemaOb;
-ResponseTuple ::= <Key> ResponseOb;
-ParameterTuple ::= <Key> ParameterOb;
-ExampleTuple ::= <Key> ExampleObject;
-RequestBodyTuple ::= <Key> RequestBodyOb;
-HeaderTuple ::= <Key> HeaderOb;
-SecuritySchemeTuple ::= <Key> SecuritySchemeOb;
-LinkTuple ::= <Key> LinkOb;
-CallbackTuple ::= <Key> CallbackOb;
-
-
-//Paths Object
-PathsObject ::= <Ref> PathItemObject;
-
-//Path Item Object
-PathItemObject ::= <Summary> <Description> [Get] [Put] [Post] [Delete] [Options] [Head] [Patch] [Trace] ServerObject* ParameterOb* Extension*;
-
-//Operation Object
-OperationObject ::= Tag* <Summary> <Description> [ExternalDocObject] <OperationID> ParameterOb* [RequestBodyOb] ResponseTuple* CallbackTuple* <DeprecatedBoolean:Boolean> SecurityRequirementObject* ServerObject* <Required:Boolean> Extension*;
-Get ::= OperationObject;
-Put ::= OperationObject;
-Post ::= OperationObject;
-Delete ::= OperationObject;
-Options ::= OperationObject;
-Head ::= OperationObject;
-Patch ::= OperationObject;
-Trace ::= OperationObject;
-Tag ::= <Tag:String>;
-
-//External Documentation Object
-ExternalDocObject ::= <Description> <Url> Extension*;
-
-//Parameter Object
-abstract ParameterOb;
-ParameterReference : ParameterOb ::= <Ref>;
-ParameterObject : ParameterOb ::= <Name> <In> <Description> <Required:Boolean> <DeprecatedBoolean:Boolean> <AllowEmptyValue:Boolean> <Style> <Explode:Boolean> <AllowReserved:Boolean> [SchemaOb] <Example:Object> ExampleTuple* ContentTuple* Extension*;
-ContentTuple ::= <Key> MediaTypeObject;
-
-//Request Body Object
-abstract RequestBodyOb;
-RequestBodyReference : RequestBodyOb ::= <Ref>;
-RequestBodyObject : RequestBodyOb ::= <Description> ContentTuple* <Required:Boolean> Extension*;
-
-//Media Type Object
-MediaTypeObject ::= [SchemaOb] <Example:Object> ExampleTuple* EncodingTuple* Extension*;
-EncodingTuple ::= <Key> EncodingObject;
-
-//Encoding Object
-EncodingObject ::= <ContentType> HeaderTuple* <Style> <Explode:Boolean> <AllowReserved:Boolean> Extension*;
-
-//Response Object
-abstract ResponseOb;
-ResponseReference : ResponseOb ::= <Ref>;
-ResponseObject : ResponseOb ::= <Description> HeaderTuple* ContentTuple* LinkTuple* Extension*;
-
-//Callback Object
-abstract CallbackOb;
-CallbackReference : CallbackOb ::= <Ref>;
-CallbackObject : CallbackOb ::= Expression* Extension*;
-Expression ::= <Name> PathItemObject;
-Extension ::= <Key> <Value:Object>;
-
-//Example Object
-ExampleObject ::= <Summary> <Description> <Value:Object> <ExternalValue> Extension*;
-
-//Link Object
-abstract LinkOb;
-LinkReference : LinkOb ::= <Ref>;
-LinkObject : LinkOb ::= <OperationRef> <OperationID> LinkParameterTuple* HeaderTuple* <Description> [ServerObject] Extension*;
-LinkParameterTuple ::= <LinkParameterKey> <LinkParameterValue>;
-
-//Header Object
-abstract HeaderOb;
-HeaderReference : HeaderOb ::= <Ref>;
-HeaderObject : HeaderOb ::= <Description> <Required:Boolean> <DeprecatedBoolean:Boolean> <AllowEmptyValue:Boolean> <Style> <Explode:Boolean> <AllowReserved:Boolean> [SchemaOb] <Example:Object> ExampleTuple* ContentTuple* Extension*;
-
-//Tag Object
-TagObject ::= <Name> <Description> [ExternalDocObject] Extension*;
-
-//Schema Object
-abstract SchemaOb;
-SchemaReference : SchemaOb ::= <Ref>;
-SchemaObject : SchemaOb ::= [AdditionalProperties] <AdditionalPropertiesAllowed:Boolean> <DefaultValue:Object> <Description> <DeprecatedBoolean:Boolean> [DiscriminatorObject] EnumObj* <Example:Object> <ExclusiveMaximum:Boolean> <ExclusiveMinimum:Boolean> [ExternalDocObject] <Format> [ItemsSchema] <Maximum:Number> <Minimum:Number> <MaxItems:Integer> <MinItems:Integer> <MaxLength:Integer> <MinLength:Integer> <MaxProperties:Integer> <MinProperties:Integer> <MultipleOf:Number> [NotSchema] <Nullable:Boolean> <Pattern> PropertyItem* RequiredField* AllOfSchema* AnyOfSchema* OneOfSchema* <ReadOnly:Boolean> <WriteOnly:Boolean> <Type> <Title> <UniqueItems:Boolean> [XmlObject] Extension*;
-AdditionalProperties ::= SchemaOb;
-EnumObj ::= <EnumOb:Object>;
-ItemsSchema ::= SchemaOb;
-NotSchema ::= SchemaOb;
-PropertyItem ::= <Name> SchemaOb;
-RequiredField ::= <Value>;
-AllOfSchema ::= SchemaOb;
-AnyOfSchema ::= SchemaOb;
-OneOfSchema ::= SchemaOb;
-
-//Discriminator Object
-DiscriminatorObject ::= <PropertyName> MappingTuple*;
-MappingTuple ::= <Key> <Value>;
-
-//XML Object
-XmlObject ::= <Name> <Namespace> <Prefix> <Attribute:Boolean> <Wrapped:Boolean> Extension*;
-
-//Security Scheme Object
-abstract SecuritySchemeOb;
-SecuritySchemeReference : SecuritySchemeOb ::= <Ref>;
-SecuritySchemeObject : SecuritySchemeOb ::= <Type> <Description> <Name> <In> <Scheme> <BearerFormat> [OAuthFlowsObject] <OpenIdConnectUrl> Extension*;
-
-//OAuth Flows Object
-OAuthFlowsObject ::= [Implicit] [Password] [ClientCredentials] [AuthorizationCode] Extension*;
-Implicit ::= OAuthFlowObject;
-Password ::= OAuthFlowObject;
-ClientCredentials ::= OAuthFlowObject;
-AuthorizationCode ::= OAuthFlowObject;
-
-//OAuth Flow Object
-OAuthFlowObject ::= <AuthorizationUrl> <TokenUrl> <RefreshUrl> ScopesTuple* <Configuration> Extension*;
-ScopesTuple ::= <ScopesKey> <ScopesValue>;
-
-//Security Requirement Object
-SecurityRequirementObject ::= SecurityRequirementTuple*;
-SecurityRequirementTuple ::= <Name> SecurityRequirementValue*;
-SecurityRequirementValue ::= <Value>;
\ No newline at end of file
diff --git a/src/main/jastadd/OpenAPISpecification.relast b/src/main/jastadd/OpenAPISpecification.relast
new file mode 100644
index 0000000000000000000000000000000000000000..92e97569b733cf9db396f88722bdbf2d47792b5a
--- /dev/null
+++ b/src/main/jastadd/OpenAPISpecification.relast
@@ -0,0 +1,168 @@
+//OpenAPI Object
+OpenAPIObject ::= <OpenAPI> <JsonSchemaDialect> I:InfoObject Serv:ServerObject* P:PathsObject* W:Webhook* C:ComponentsObject Sr:SecurityRequirementObject* T:TagObject* [E:ExternalDocObject] Ex:Extension* ;
+Webhook ::= <Key> p:PathItemOb;
+
+//Info Object
+InfoObject ::= <Title> <Summary> <Description> <TermsOfService> <Version> [C:ContactObject] [L:LicenseObject] Ex:Extension*;
+
+//Contact Object
+ContactObject ::= <Name> <Url> <Email> Ex:Extension*;
+
+//License Object
+LicenseObject ::= <Name> <Identifier> <Url> Ex:Extension*;
+
+//Server Object
+ServerObject ::= <Url> <Description> St:ServerVariablesTuple* Ex:Extension*;
+ServerVariablesTuple ::= <Name> S:ServerVariableObject;
+
+//Server Variable Object
+ServerVariableObject ::= <Default> <Description> E:Enum* Ex:Extension*;
+Enum ::= <EnumValue>;
+
+//Components Object
+ComponentsObject ::= S:SchemaTuple* R:ResponseTuple* P:ParameterTuple* E:ExampleTuple* Rb:RequestBodyTuple* H:HeaderTuple* Sc:SecuritySchemeTuple* L:LinkTuple* C:CallbackTuple* Pi:PathItemTuple* Ex:Extension*;
+
+SchemaTuple ::= <Key> O:SchemaOb;
+ResponseTuple ::= <Key> O:ResponseOb;
+ParameterTuple ::= <Key> O:ParameterOb;
+ExampleTuple ::= <Key> O:ExampleOb;
+RequestBodyTuple ::= <Key> O:RequestBodyOb;
+HeaderTuple ::= <Key> O:HeaderOb;
+SecuritySchemeTuple ::= <Key> O:SecuritySchemeOb;
+LinkTuple ::= <Key> O:LinkOb;
+CallbackTuple ::= <Key> O:CallbackOb;
+PathItemTuple ::= <Key> O:PathItemOb;
+
+//Paths Object
+PathsObject ::= <Ref> P:PathItemOb Ex:Extension*;
+
+//Path Item Object
+abstract PathItemOb;
+PathItemReference : PathItemOb ::= <Ref> <Summary> <Description>;
+rel PathItemReference.r -> PathItemObject;
+PathItemObject : PathItemOb ::= <Ref> <Summary> <Description> [G:Get] [PutOb:Put] [PostOb:Post] [D:Delete] [O:Options] [H:Head] [PatchOb:Patch] [T:Trace] S:ServerObject* Po:ParameterOb* Ex:Extension*;
+
+//Operation Object
+OperationObject ::= <Summary> <Description> <OperationID> <DeprecatedBoolean:Boolean> T:Tag* [Ed:ExternalDocObject] P:ParameterOb* [Rb:RequestBodyOb] R:ResponsesObject C:CallbackTuple* Sr:SecurityRequirementObject* S:ServerObject* Ex:Extension*;
+
+Get ::= O:OperationObject;
+Put ::= O:OperationObject;
+Post ::= O:OperationObject;
+Delete ::= O:OperationObject;
+Options ::= O:OperationObject;
+Head ::= O:OperationObject;
+Patch ::= O:OperationObject;
+Trace ::= O:OperationObject;
+Tag ::= <Tag>;
+
+//External Documentation Object
+ExternalDocObject ::= <Description> <Url> Ex:Extension*;
+
+//Parameter Object
+abstract ParameterOb;
+ParameterReference : ParameterOb ::= <Ref> <Summary> <Description>;
+rel ParameterReference.p -> ParameterObject;
+ParameterObject : ParameterOb ::= <Name> <In> <Description> <Required:Boolean> <DeprecatedBoolean:Boolean> <AllowEmptyValue:Boolean> <Style> <Explode:Boolean> <AllowReserved:Boolean> <Example:Object> [Schema:SchemaOb] E:ExampleTuple* C:ContentTuple* Ex:Extension*;
+ContentTuple ::= <Key> M:MediaTypeObject;
+
+//Request Body Object
+abstract RequestBodyOb;
+RequestBodyReference : RequestBodyOb ::= <Ref> <Summary> <Description>;
+rel RequestBodyReference.r -> RequestBodyObject;
+RequestBodyObject : RequestBodyOb ::= <Description> <Required:Boolean> C:ContentTuple* Ex:Extension*;
+
+//Media Type Object
+MediaTypeObject ::= <Example:Object> [S:SchemaOb] E:ExampleTuple* En:EncodingTuple* Ex:Extension*;
+EncodingTuple ::= <Key> E:EncodingObject;
+
+//Encoding Object
+EncodingObject ::= <ContentType> <Style> <Explode:Boolean> <AllowReserved:Boolean> H:HeaderTuple* Ex:Extension*;
+
+//Responses Object (ResponseTuple is used for HTTPStatusCode)
+ResponsesObject ::= R:ResponseTuple*;
+
+//Response Object
+abstract ResponseOb;
+ResponseReference : ResponseOb ::= <Ref> <Summary> <Description>;
+rel ResponseReference.r -> ResponseObject;
+ResponseObject : ResponseOb ::= <Description> H:HeaderTuple* C:ContentTuple* L:LinkTuple* Ex:Extension*;
+
+//Callback Object
+abstract CallbackOb;
+CallbackReference : CallbackOb ::= <Ref> <Summary> <Description>;
+rel CallbackReference.r -> CallbackObject;
+CallbackObject : CallbackOb ::= E:Expression* Ex:Extension*;
+
+Extension ::= <Key> <Value:Object>;
+Expression ::= <Name> P:PathItemOb;
+
+//Example Object
+abstract ExampleOb;
+ExampleReference : ExampleOb ::= <Ref> <Summary> <Description>;
+rel ExampleReference.r -> ExampleObject;
+ExampleObject : ExampleOb ::= <Summary> <Description> <Value:Object> <ExternalValue> Ex:Extension*;
+
+//Link Object
+abstract LinkOb;
+LinkReference : LinkOb ::= <Ref> <Summary> <Description>;
+rel LinkReference.r -> LinkObject;
+LinkObject : LinkOb ::= <OperationRef> <OperationID> <LinkRequestBody:Object> <Description> L:LinkParameterTuple* [S:ServerObject] Ex:Extension*;
+
+LinkParameterTuple ::= <Key> <Value>;
+
+//Header Object
+abstract HeaderOb;
+HeaderReference : HeaderOb ::= <Ref> <Summary> <Description>;
+rel HeaderReference.r -> HeaderObject;
+HeaderObject : HeaderOb ::= <Description> <Required:Boolean> <DeprecatedBoolean:Boolean> <AllowEmptyValue:Boolean> <Style> <Explode:Boolean> <AllowReserved:Boolean> <Example:Object> [S:SchemaOb] E:ExampleTuple* C:ContentTuple* Ex:Extension*;
+
+//Tag Object
+TagObject ::= <Name> <Description> [E:ExternalDocObject] Ex:Extension*;
+
+//Schema Object ()
+abstract SchemaOb;
+SchemaReference : SchemaOb ::= <Ref> <Summary> <Description>;
+rel SchemaReference.r -> SchemaObject;
+SchemaObject : SchemaOb ::= <Name> <AdditionalProperties:Object> <DefaultValue:Object> <Description> <DeprecatedBoolean:Boolean> <ExclusiveMaximum:Boolean> <ExclusiveMinimum:Boolean> <Format> <Maximum:BigDecimal> <Minimum:BigDecimal> <MaxItems:Integer> <MinItems:Integer> <MaxLength:Integer> <MinLength:Integer> <MaxProperties:Integer> <MinProperties:Integer> <MultipleOf:BigDecimal> <Pattern> <ReadOnly:Boolean> <WriteOnly:Boolean> <Type> <Title> <UniqueItems:Boolean> <Nullable:Boolean> <MaxContains:Integer> <MinContains:Integer> <DependentRequired:Object> <DependentSchema:SchemaOb> <Const:Object> [D:DiscriminatorObject] E:EnumObj* El:ExampleElement* [Ext:ExternalDocObject] [I:ItemsSchema] [N:NotSchema] P:PropertyItem* R:RequiredField* All:AllOfSchema* Any:AnyOfSchema* One:OneOfSchema* T:TypeArray* [X:XmlObject] Ex:Extension*;
+
+ItemsSchema ::= Schema:SchemaOb;
+NotSchema ::= Schema:SchemaOb;
+PropertyItem ::= <Name> Schema:SchemaOb;
+AllOfSchema ::= Schema:SchemaOb;
+AnyOfSchema ::= Schema:SchemaOb;
+OneOfSchema ::= Schema:SchemaOb;
+ExampleElement ::= <Example:Object>;
+TypeArray ::= <TypeElements:Object>;
+EnumObj ::= <EnumOb:Object>;
+RequiredField ::= <Value>;
+
+//Discriminator Object
+DiscriminatorObject ::= <PropertyName> M:MappingTuple* Ex:Extension*;
+MappingTuple ::= <Key> <Value>;
+
+//XML Object
+XmlObject ::= <Name> <Namespace> <Prefix> <Attribute:Boolean> <Wrapped:Boolean> Ex:Extension*;
+
+//Security Scheme Object
+abstract SecuritySchemeOb;
+SecuritySchemeReference : SecuritySchemeOb ::= <Ref> <Summary> <Description>;
+rel SecuritySchemeReference.r -> SecuritySchemeObject;
+SecuritySchemeObject : SecuritySchemeOb ::= <Type> <Description> <Name> <In> <Scheme> <BearerFormat> <OpenIdConnectUrl> [O:OAuthFlowsObject] Ex:Extension*;
+
+//OAuth Flows Object
+OAuthFlowsObject ::= [I:Implicit] [P:Password] [C:ClientCredentials] [A:AuthorizationCode] Ex:Extension*;
+
+Implicit ::= O:OAuthFlowObject;
+Password ::= O:OAuthFlowObject;
+ClientCredentials ::= O:OAuthFlowObject;
+AuthorizationCode ::= O:OAuthFlowObject;
+
+//OAuth Flow Object
+OAuthFlowObject ::= <AuthorizationUrl> <TokenUrl> <RefreshUrl> S:ScopesTuple* Ex:Extension*;
+ScopesTuple ::= <ScopesKey> <ScopesValue>;
+
+//Security Requirement Object
+SecurityRequirementObject ::= Tuple:SecurityRequirementTuple*;
+
+SecurityRequirementTuple ::= <Name> Value:SecurityRequirementValue*;
+SecurityRequirementValue ::= <Value>;
\ No newline at end of file
diff --git a/src/main/jastadd/Parser.jrag b/src/main/jastadd/Parser.jrag
index cdfdd590c42af6011148c524a0810016f2b484d5..29f9d8fb558b95e28ed99aed1367aefd519facf0 100644
--- a/src/main/jastadd/Parser.jrag
+++ b/src/main/jastadd/Parser.jrag
@@ -1,908 +1,952 @@
-import org.openapi4j.core.exception.DecodeException;
+import io.swagger.models.*;
+import io.swagger.v3.oas.models.OpenAPI;
+import io.swagger.v3.oas.models.*;
+import io.swagger.v3.oas.models.callbacks.*;
+import io.swagger.v3.oas.models.examples.*;
+import io.swagger.v3.oas.models.headers.*;
+import io.swagger.v3.oas.models.info.*;
+import io.swagger.v3.oas.models.links.*;
+import io.swagger.v3.oas.models.media.*;
+import io.swagger.v3.oas.models.parameters.*;
+import io.swagger.v3.oas.models.responses.*;
+import io.swagger.v3.oas.models.security.*;
+import io.swagger.v3.oas.models.servers.*;
+import io.swagger.v3.oas.models.tags.*;
 
-aspect Parser {
-
-  inh OpenAPIObject ASTNode.root();
-  eq OpenAPIObject.getChild().root() = this;
 
-  coll List<SchemaTuple> OpenAPIObject.schemaTuples() [new ArrayList<>()] root OpenAPIObject;
-  SchemaTuple contributes this
-    to OpenAPIObject.schemaTuples();
-
-  coll List<ResponseTuple> OpenAPIObject.responseTuples() [new ArrayList<>()] root OpenAPIObject;
-  ResponseTuple contributes this
-    to OpenAPIObject.responseTuples();
+aspect Parser {
 
-  coll List<ParameterTuple> OpenAPIObject.parameterTuples() [new ArrayList<>()] root OpenAPIObject;
-  ParameterTuple contributes this
-    to OpenAPIObject.parameterTuples();
+public static OpenAPIObject OpenAPIObject.parseOpenAPI(OpenAPI api) {
+        OpenAPIObject openapi = new OpenAPIObject();
 
-  coll List<RequestBodyTuple> OpenAPIObject.requestBodyTuples() [new ArrayList<>()] root OpenAPIObject;
-  RequestBodyTuple contributes this
-    to OpenAPIObject.requestBodyTuples();
+        if (api.getOpenapi() != null)
+        openapi.setOpenAPI(api.getOpenapi());
+        if (api.getInfo() != null)
+        openapi.setI(InfoObject.parseInfo(api.getInfo()));
+    if (api.getPaths() != null) {
+        for (String key : api.getPaths().keySet()) {
+            PathsObject path = new PathsObject();
+            path.setRef(key);
+            path.setP(PathItemObject.parsePath(api.getPaths().get(key)));
+            if (api.getPaths().getExtensions() != null) {
+                for (String pKey : api.getPaths().getExtensions().keySet())
+                    path.addEx(new Extension(pKey, api.getPaths().getExtensions().get(pKey)));
+            }
+            openapi.addP(path);
+        }
+    }
+        if (api.getServers() != null) {
+        for (io.swagger.v3.oas.models.servers.Server s : api.getServers())
+        openapi.addServ(ServerObject.parseServer(s));
+        }
+        if (api.getComponents() != null)
+        openapi.setC(ComponentsObject.parseComponents(api.getComponents()));
+        if (api.getSecurity() != null) {
+        for (io.swagger.v3.oas.models.security.SecurityRequirement s : api.getSecurity())
+        openapi.addSr(SecurityRequirementObject.parseSecurityRequirement(s));
+        }
+        if (api.getTags() != null) {
+        for (io.swagger.v3.oas.models.tags.Tag t : api.getTags())
+        openapi.addT(TagObject.parseTag(t));
+        }
+        if (api.getExternalDocs() != null)
+        openapi.setE(ExternalDocObject.parseExternalDocs(api.getExternalDocs()));
+        if (api.getExtensions() != null) {
+        for (String key : api.getExtensions().keySet())
+        openapi.addEx(new Extension(key, api.getExtensions().get(key)));
+        }
+    /* 3.1.0 features
+    if (api.getWebhook != null) ...
+    if (api.getJsonSchemaDialect != null) ...
+     */
 
-  coll List<HeaderTuple> OpenAPIObject.headerTuples() [new ArrayList<>()] root OpenAPIObject;
-  HeaderTuple contributes this
-    to OpenAPIObject.headerTuples();
+        return openapi;
+        }
 
-  coll List<SecuritySchemeTuple> OpenAPIObject.securitySchemeTuples() [new ArrayList<>()] root OpenAPIObject;
-  SecuritySchemeTuple contributes this
-    to OpenAPIObject.securitySchemeTuples();
+public static InfoObject InfoObject.parseInfo(io.swagger.v3.oas.models.info.Info info) {
+        InfoObject infoObject = new InfoObject();
+
+        if (info.getTitle() != null)
+        infoObject.setTitle(info.getTitle());
+        if (info.getVersion() != null)
+        infoObject.setVersion(info.getVersion());
+        if (info.getDescription() != null)
+        infoObject.setDescription(info.getDescription());
+        if (info.getTermsOfService() != null)
+        infoObject.setTermsOfService(info.getTermsOfService());
+        if (info.getContact() != null)
+        infoObject.setC(ContactObject.parseContact(info.getContact()));
+        if (info.getLicense() != null)
+        infoObject.setL(LicenseObject.parseLicense(info.getLicense()));
+        if (info.getExtensions() != null) {
+        for (String key : info.getExtensions().keySet())
+        infoObject.addEx(new Extension(key, info.getExtensions().get(key)));
+        }
 
-  coll List<LinkTuple> OpenAPIObject.linkTuples() [new ArrayList<>()] root OpenAPIObject;
-  LinkTuple contributes this
-    to OpenAPIObject.linkTuples();
+        /* 3.1.0 features
+        if (info.getSummary != null) ...
+        */
 
-  coll List<CallbackTuple> OpenAPIObject.callbackTuples() [new ArrayList<>()] root OpenAPIObject;
-  CallbackTuple contributes this
-    to OpenAPIObject.callbackTuples();
+        return infoObject;
+        }
 
-  public static OpenAPIObject OpenAPIObject.parseOpenAPI(OpenApi3 api) throws IOException, ResolutionException, ValidationException, DecodeException {
-    OpenAPIObject openapi = new OpenAPIObject();
-    Map<Object, ASTNode> map = new HashMap<>();
+public static ContactObject ContactObject.parseContact(io.swagger.v3.oas.models.info.Contact contact){
+        ContactObject contactObject = new ContactObject();
+
+        if (contact.getName() != null)
+        contactObject.setName(contact.getName());
+        if (contact.getUrl() != null)
+        contactObject.setUrl(contact.getUrl());
+        if (contact.getEmail() != null)
+        contactObject.setEmail(contact.getEmail());
+        if (contact.getExtensions() != null) {
+        for (String key : contact.getExtensions().keySet())
+        contactObject.addEx(new Extension(key, contact.getExtensions().get(key)));
+        }
 
-    if (api.getContext() != null)
-      openapi.setContext(api.getContext());
-    if (api.getOpenapi() != null)
-      openapi.setOpenAPI(api.getOpenapi());
-    if (api.getInfo() != null)
-      openapi.setInfoObject(InfoObject.parseInfo(api.getInfo(), map));
-    if (api.getPaths() != null) {
-      for (String key : api.getPaths().keySet())
-        openapi.addPathsObject(new PathsObject(key, PathItemObject.parsePath(api.getPath(key), api.getContext(), map)));
-    }
-    if (api.getServers() != null) {
-      for (Server s : api.getServers())
-        openapi.addServerObject(ServerObject.parseServer(s, map));
-    }
-    if (api.getComponents() != null)
-      openapi.setComponentsObject(ComponentsObject.parseComponents(api.getComponents(), api.getContext(), map));
-    if (api.getSecurityRequirements() != null) {
-      for (SecurityRequirement s : api.getSecurityRequirements())
-        openapi.addSecurityRequirementObject(SecurityRequirementObject.parseSecurityRequirement(s, map));
-    }
-    if (api.getTags() != null) {
-      for (org.openapi4j.parser.model.v3.Tag t : api.getTags())
-        openapi.addTagObject(TagObject.parseTag(t, map));
-    }
-    if (api.getExternalDocs() != null)
-      openapi.setExternalDocObject(ExternalDocObject.parseExternalDocs(api.getExternalDocs(), map));
-    if (api.getExtensions() != null) {
-      for (String key : api.getExtensions().keySet())
-        openapi.addExtension(new Extension(key, api.getExtensions().get(key)));
-    }
+        return contactObject;
+        }
 
-    map.put(api, openapi);
-    return openapi;
-  }
-
-  public static InfoObject InfoObject.parseInfo(Info info, Map<Object, ASTNode> map) {
-    InfoObject infoObject = new InfoObject();
-
-    if (info.getTitle() != null)
-      infoObject.setTitle(info.getTitle());
-    if (info.getVersion() != null)
-      infoObject.setVersion(info.getVersion());
-    if (info.getDescription() != null)
-      infoObject.setDescription(info.getDescription());
-    if (info.getTermsOfService() != null)
-      infoObject.setTermsOfService(info.getTermsOfService());
-    if (info.getContact() != null)
-      infoObject.setContactObject(ContactObject.parseContact(info.getContact(), map));
-    if (info.getLicense() != null)
-      infoObject.setLicenseObject(LicenseObject.parseLicense(info.getLicense(), map));
-    if (info.getExtensions() != null) {
-      for (String key : info.getExtensions().keySet())
-        infoObject.addExtension(new Extension(key, info.getExtensions().get(key)));
-    }
+public static LicenseObject LicenseObject.parseLicense(io.swagger.v3.oas.models.info.License license){
+        LicenseObject licenseObject = new LicenseObject();
 
-    map.put(info, infoObject);
-    return infoObject;
-  }
-
-  public static ContactObject ContactObject.parseContact(Contact contact, Map<Object, ASTNode> map){
-    ContactObject contactObject = new ContactObject();
-
-    if (contact.getName() != null)
-      contactObject.setName(contact.getName());
-    if (contact.getUrl() != null)
-      contactObject.setUrl(contact.getUrl());
-    if (contact.getEmail() != null)
-      contactObject.setEmail(contact.getEmail());
-    if (contact.getExtensions() != null) {
-      for (String key : contact.getExtensions().keySet())
-        contactObject.addExtension(new Extension(key, contact.getExtensions().get(key)));
-    }
+        if (license.getName() != null)
+        licenseObject.setName(license.getName());
+        if (license.getUrl() != null)
+        licenseObject.setUrl(license.getUrl());
+        if (license.getExtensions() != null) {
+        for (String key : license.getExtensions().keySet())
+        licenseObject.addEx(new Extension(key, license.getExtensions().get(key)));
+        }
 
-    map.put(contact, contactObject);
-    return contactObject;
-  }
+        /* 3.1.0 features
+        if (license.getIdentifier() != null) ...
+         */
 
-  public static LicenseObject LicenseObject.parseLicense(License license, Map<Object, ASTNode> map){
-    LicenseObject licenseObject = new LicenseObject();
+        return licenseObject;
+        }
 
-    if (license.getName() != null)
-      licenseObject.setName(license.getName());
-    if (license.getUrl() != null)
-      licenseObject.setUrl(license.getUrl());
-    if (license.getExtensions() != null) {
-      for (String key : license.getExtensions().keySet())
-        licenseObject.addExtension(new Extension(key, license.getExtensions().get(key)));
-    }
+public static ServerObject ServerObject.parseServer(Server server){
+        ServerObject serverObject = new ServerObject();
 
-    map.put(license, licenseObject);
-    return licenseObject;
-  }
+        if (server.getUrl() != null)
+        serverObject.setUrl(server.getUrl());
+        if (server.getDescription() != null)
+        serverObject.setDescription(server.getDescription());
+        if (server.getVariables() != null) {
+        for (String key : server.getVariables().keySet())
+        serverObject.addSt(new ServerVariablesTuple(key, ServerVariableObject.parseServerVariable(server.getVariables().get(key))));
+        }
+        if (server.getExtensions() != null) {
+        for (String key : server.getExtensions().keySet())
+        serverObject.addEx(new Extension(key, server.getExtensions().get(key)));
+        }
 
-  public static ServerObject ServerObject.parseServer(Server server, Map<Object, ASTNode> map){
-    ServerObject serverObject = new ServerObject();
+        return serverObject;
+        }
 
-    if (server.getUrl() != null)
-      serverObject.setUrl(server.getUrl());
-    if (server.getDescription() != null)
-      serverObject.setDescription(server.getDescription());
-    if (server.getVariables() != null) {
-      for (String key : server.getVariables().keySet())
-        serverObject.addServerVariablesTuple(new ServerVariablesTuple(key, ServerVariableObject.parseServerVariable(server.getVariable(key), map)));
-    }
-    if (server.getExtensions() != null) {
-      for (String key : server.getExtensions().keySet())
-        serverObject.addExtension(new Extension(key, server.getExtensions().get(key)));
-    }
+public static ServerVariableObject ServerVariableObject.parseServerVariable(ServerVariable serverVariable){
+        ServerVariableObject serverVariableObject = new ServerVariableObject();
 
-    map.put(server, serverObject);
-    return serverObject;
-  }
+        if (serverVariable.getDefault() != null)
+        serverVariableObject.setDefault(serverVariable.getDefault());
+        if (serverVariable.getDescription() != null)
+        serverVariableObject.setDescription(serverVariable.getDescription());
+        if (serverVariable.getEnum() != null) {
+        for (String e : serverVariable.getEnum())
+        serverVariableObject.addE(new Enum(e));
+        }
+        if (serverVariable.getExtensions() != null) {
+        for (String key : serverVariable.getExtensions().keySet())
+        serverVariableObject.addEx(new Extension(key, serverVariable.getExtensions().get(key)));
+        }
 
-  public static ServerVariableObject ServerVariableObject.parseServerVariable(ServerVariable serverVariable, Map<Object, ASTNode> map){
-    ServerVariableObject serverVariableObject = new ServerVariableObject();
+        return serverVariableObject;
+        }
 
-    if (serverVariable.getDefault() != null)
-      serverVariableObject.setDefault(serverVariable.getDefault());
-    if (serverVariable.getDescription() != null)
-      serverVariableObject.setDescription(serverVariable.getDescription());
-    if (serverVariable.getEnums() != null) {
-      for (String e : serverVariable.getEnums())
-        serverVariableObject.addEnum(new Enum(e));
-    }
-    if (serverVariable.getExtensions() != null) {
-      for (String key : serverVariable.getExtensions().keySet())
-        serverVariableObject.addExtension(new Extension(key, serverVariable.getExtensions().get(key)));
-    }
+public static ComponentsObject ComponentsObject.parseComponents(Components components) {
+        ComponentsObject componentsObject = new ComponentsObject();
 
-    map.put(serverVariable, serverVariableObject);
-    return serverVariableObject;
-  }
+        if (components.getSchemas() != null) {
+        for (String key : components.getSchemas().keySet())
+        componentsObject.addS(new SchemaTuple(key, SchemaOb.parseSchema(components.getSchemas().get(key))));
+        }
+        if (components.getResponses() != null) {
+        for (String key : components.getResponses().keySet())
+        componentsObject.addR(new ResponseTuple(key, ResponseOb.parseResponse(components.getResponses().get(key))));
+        }
+        if (components.getParameters() != null) {
+        for (String key : components.getParameters().keySet())
+        componentsObject.addP(new ParameterTuple(key, ParameterOb.parseParameter(components.getParameters().get(key))));
+        }
+        if (components.getExamples() != null) {
+        for (String key : components.getExamples().keySet())
+        componentsObject.addE(new ExampleTuple(key, ExampleObject.parseExample(components.getExamples().get(key))));
+        }
+        if (components.getRequestBodies() != null) {
+        for (String key : components.getRequestBodies().keySet())
+        componentsObject.addRb(new RequestBodyTuple(key, RequestBodyOb.parseRequestBody(components.getRequestBodies().get(key))));
+        }
+        if (components.getHeaders() != null) {
+        for (String key : components.getHeaders().keySet())
+        componentsObject.addH(new HeaderTuple(key, HeaderOb.parseHeader(components.getHeaders().get(key))));
+        }
+        if (components.getSecuritySchemes() != null) {
+        for (String key : components.getSecuritySchemes().keySet())
+        componentsObject.addSc(new SecuritySchemeTuple(key, SecuritySchemeOb.parseSecurityScheme(components.getSecuritySchemes().get(key))));
+        }
+        if (components.getLinks() != null) {
+        for (String key : components.getLinks().keySet())
+        componentsObject.addL(new LinkTuple(key, LinkOb.parseLink(components.getLinks().get(key))));
+        }
+        if (components.getCallbacks() != null) {
+        for (String key : components.getCallbacks().keySet())
+        componentsObject.addC(new CallbackTuple(key, CallbackOb.parseCallback(components.getCallbacks().get(key))));
+        }
+        if (components.getExtensions() != null) {
+        for (String key : components.getExtensions().keySet())
+        componentsObject.addEx(new Extension(key, components.getExtensions().get(key)));
+        }
 
-  public static ComponentsObject ComponentsObject.parseComponents(Components components, OAIContext context, Map<Object, ASTNode> map) throws DecodeException {
-    ComponentsObject componentsObject = new ComponentsObject();
+        /* 3.1.0 features
+        if (components.getPathItems() != null) ...
+         */
 
-    if (components.getSchemas() != null) {
-      for (String key : components.getSchemas().keySet())
-        componentsObject.addSchemaTuple(new SchemaTuple(key, SchemaOb.parseSchema(components.getSchema(key), context, map)));
-    }
-    if (components.getResponses() != null) {
-      for (String key : components.getResponses().keySet())
-        componentsObject.addResponseTuple(new ResponseTuple(key, ResponseOb.parseResponse(components.getResponse(key), context, map)));
-    }
-    if (components.getParameters() != null) {
-      for (String key : components.getParameters().keySet())
-        componentsObject.addParameterTuple(new ParameterTuple(key, ParameterOb.parseParameter(components.getParameter(key), context, map)));
-    }
-    if (components.getExamples() != null) {
-      for (String key : components.getExamples().keySet())
-        componentsObject.addExampleTuple(new ExampleTuple(key, ExampleObject.parseExample(components.getExample(key), context, map)));
-    }
-    if (components.getRequestBodies() != null) {
-      for (String key : components.getRequestBodies().keySet())
-        componentsObject.addRequestBodyTuple(new RequestBodyTuple(key, RequestBodyOb.parseRequestBody(components.getRequestBody(key), context, map)));
-    }
-    if (components.getHeaders() != null) {
-      for (String key : components.getHeaders().keySet())
-        componentsObject.addHeaderTuple(new HeaderTuple(key, HeaderOb.parseHeader(components.getHeader(key), context, map)));
-    }
-    if (components.getSecuritySchemes() != null) {
-      for (String key : components.getSecuritySchemes().keySet())
-        componentsObject.addSecuritySchemeTuple(new SecuritySchemeTuple(key, SecuritySchemeOb.parseSecurityScheme(components.getSecurityScheme(key), context, map)));
-    }
-    if (components.getLinks() != null) {
-      for (String key : components.getLinks().keySet())
-        componentsObject.addLinkTuple(new LinkTuple(key, LinkOb.parseLink(components.getLink(key), context, map)));
-    }
-    if (components.getCallbacks() != null) {
-      for (String key : components.getCallbacks().keySet())
-        componentsObject.addCallbackTuple(new CallbackTuple(key, CallbackOb.parseCallback(components.getCallback(key), context, map)));
-    }
-    if (components.getExtensions() != null) {
-      for (String key : components.getExtensions().keySet())
-        componentsObject.addExtension(new Extension(key, components.getExtensions().get(key)));
-    }
+        return componentsObject;
+        }
 
-    map.put(components, componentsObject);
-    return componentsObject;
-  }
-
-  public static PathItemObject PathItemObject.parsePath(Path path, OAIContext context, Map<Object, ASTNode> map) throws DecodeException {
-    PathItemObject pathItem = new PathItemObject();
-
-    if (path.getSummary() != null)
-      pathItem.setSummary(path.getSummary());
-    if (path.getDescription() != null)
-      pathItem.setDescription(path.getDescription());
-    if (path.getGet() != null) {
-      Get get = new Get();
-      get.setOperationObject(OperationObject.parseOperation(path.getGet(), context, map));
-      pathItem.setGet(get);
-    }
-    if (path.getPut() != null) {
-      Put put = new Put();
-      put.setOperationObject(OperationObject.parseOperation(path.getPut(), context, map));
-      pathItem.setPut(put);
-    }
-    if (path.getPost() != null) {
-      Post post = new Post();
-      post.setOperationObject(OperationObject.parseOperation(path.getPost(), context, map));
-      pathItem.setPost(post);
-    }
-    if (path.getDelete() != null) {
-      Delete delete = new Delete();
-      delete.setOperationObject(OperationObject.parseOperation(path.getDelete(), context, map));
-      pathItem.setDelete(delete);
-    }
-    if (path.getOptions() != null) {
-      Options options = new Options();
-      options.setOperationObject(OperationObject.parseOperation(path.getOptions(), context, map));
-      pathItem.setOptions(options);
-    }
-    if (path.getHead() != null) {
-      Head head = new Head();
-      head.setOperationObject(OperationObject.parseOperation(path.getHead(), context, map));
-      pathItem.setHead(head);
-    }
-    if (path.getPatch() != null) {
-      Patch patch = new Patch();
-      patch.setOperationObject(OperationObject.parseOperation(path.getPatch(), context, map));
-      pathItem.setPatch(patch);
-    }
-    if (path.getTrace() != null) {
-      Trace trace = new Trace();
-      trace.setOperationObject(OperationObject.parseOperation(path.getTrace(), context, map));
-      pathItem.setTrace(trace);
-    }
-    if (path.getServers() != null) {
-      for (Server s : path.getServers())
-        pathItem.addServerObject(ServerObject.parseServer(s, map));
-    }
-    if (path.getParameters() != null) {
-      for (Parameter p : path.getParameters())
-        pathItem.addParameterOb(ParameterOb.parseParameter(p, context, map));
-    }
-    if (path.getExtensions() != null) {
-      for (String key : path.getExtensions().keySet())
-        pathItem.addExtension(new Extension(key, path.getExtensions().get(key)));
-    }
+public static PathItemOb PathItemOb.parsePath(PathItem path) {
+        PathItemObject pathItem = new PathItemObject();
+
+        if(path.get$ref() != null){
+        PathItemReference r = new PathItemReference();
+        r.setRef(path.get$ref());
+
+      /* 3.1.0 features
+      if (path.getSummary() != null) ...
+      if (path.getDescription() != null) ...
+      if (path.getPathItem() != null) ...
+       */
+
+        return r;
+        } else
+
+        if (path.getSummary() != null)
+        pathItem.setSummary(path.getSummary());
+        if (path.getDescription() != null)
+        pathItem.setDescription(path.getDescription());
+        if (path.getGet() != null) {
+        Get get = new Get();
+        get.setO(OperationObject.parseOperation(path.getGet()));
+        pathItem.setG(get);
+        }
+        if (path.getPut() != null) {
+        Put put = new Put();
+        put.setO(OperationObject.parseOperation(path.getPut()));
+        pathItem.setPutOb(put);
+        }
+        if (path.getPost() != null) {
+        Post post = new Post();
+        post.setO(OperationObject.parseOperation(path.getPost()));
+        pathItem.setPostOb(post);
+        }
+        if (path.getDelete() != null) {
+        Delete delete = new Delete();
+        delete.setO(OperationObject.parseOperation(path.getDelete()));
+        pathItem.setD(delete);
+        }
+        if (path.getOptions() != null) {
+        Options options = new Options();
+        options.setO(OperationObject.parseOperation(path.getOptions()));
+        pathItem.setO(options);
+        }
+        if (path.getHead() != null) {
+        Head head = new Head();
+        head.setO(OperationObject.parseOperation(path.getHead()));
+        pathItem.setH(head);
+        }
+        if (path.getPatch() != null) {
+        Patch patch = new Patch();
+        patch.setO(OperationObject.parseOperation(path.getPatch()));
+        pathItem.setPatchOb(patch);
+        }
+        if (path.getTrace() != null) {
+        Trace trace = new Trace();
+        trace.setO(OperationObject.parseOperation(path.getTrace()));
+        pathItem.setT(trace);
+        }
+        if (path.getServers() != null) {
+        for (Server s : path.getServers())
+        pathItem.addS(ServerObject.parseServer(s));
+        }
+        if (path.getParameters() != null) {
+        for (Parameter p : path.getParameters())
+        pathItem.addPo(ParameterOb.parseParameter(p));
+        }
+        if (path.getExtensions() != null) {
+        for (String key : path.getExtensions().keySet())
+        pathItem.addEx(new Extension(key, path.getExtensions().get(key)));
+        }
 
-    map.put(path, pathItem);
-    return pathItem;
-  }
+        return pathItem;
+        }
 
-  public static OperationObject OperationObject.parseOperation(Operation operation, OAIContext context, Map<Object, ASTNode> map) throws DecodeException{
-    OperationObject operationObject = new OperationObject();
+public static OperationObject OperationObject.parseOperation(io.swagger.v3.oas.models.Operation operation) {
+        OperationObject operationObject = new OperationObject();
 
-    if (operation.getDeprecated() != null)
-      operationObject.setDeprecatedBoolean(operation.getDeprecated());
-    if (operation.getTags() != null) {
-      for (String t : operation.getTags()) {
+        if (operation.getDeprecated() != null)
+        operationObject.setDeprecatedBoolean(operation.getDeprecated());
+        if (operation.getTags() != null) {
+        for (String t : operation.getTags()) {
         de.tudresden.inf.st.openapi.ast.Tag tag = new de.tudresden.inf.st.openapi.ast.Tag();
         tag.setTag(t);
-        operationObject.addTag(tag);
-      }
-    }
-    if (operation.getSummary() != null)
-      operationObject.setSummary(operation.getSummary());
-    if (operation.getDescription() != null)
-      operationObject.setDescription(operation.getDescription());
-    if (operation.getExternalDocs() != null)
-      operationObject.setExternalDocObject(ExternalDocObject.parseExternalDocs(operation.getExternalDocs(), map));
-    if (operation.getOperationId() != null)
-      operationObject.setOperationID(operation.getOperationId());
-    if (operation.getParameters() != null) {
-      for (Parameter p : operation.getParameters())
-        operationObject.addParameterOb(ParameterOb.parseParameter(p, context, map));
-    }
-    if (operation.getRequestBody() != null)
-      operationObject.setRequestBodyOb(RequestBodyOb.parseRequestBody(operation.getRequestBody(), context, map));
-    if (operation.getResponses() != null) {
-      for (String key : operation.getResponses().keySet())
-        operationObject.addResponseTuple(new ResponseTuple(key, ResponseObject.parseResponse(operation.getResponse(key), context, map)));
-    }
-    if (operation.getCallbacks() != null) {
-      for (String key : operation.getCallbacks().keySet())
-        operationObject.addCallbackTuple(new CallbackTuple(key, CallbackObject.parseCallback(operation.getCallback(key), context, map)));
-    }
-    if (operation.getSecurityRequirements() != null) {
-      for (SecurityRequirement s : operation.getSecurityRequirements())
-        operationObject.addSecurityRequirementObject(SecurityRequirementObject.parseSecurityRequirement(s, map));
-    }
-    if (operation.getServers() != null) {
-      for (Server s : operation.getServers())
-        operationObject.addServerObject(ServerObject.parseServer(s, map));
-    }
-    if (operation.getExtensions() != null) {
-      for (String key : operation.getExtensions().keySet())
-        operationObject.addExtension(new Extension(key, operation.getExtensions().get(key)));
-    }
+        operationObject.addT(tag);
+        }
+        }
+        if (operation.getSummary() != null)
+        operationObject.setSummary(operation.getSummary());
+        if (operation.getDescription() != null)
+        operationObject.setDescription(operation.getDescription());
+        if (operation.getExternalDocs() != null)
+        operationObject.setEd(ExternalDocObject.parseExternalDocs(operation.getExternalDocs()));
+        if (operation.getOperationId() != null)
+        operationObject.setOperationID(operation.getOperationId());
+        if (operation.getParameters() != null) {
+        for (Parameter p : operation.getParameters())
+        operationObject.addP(ParameterOb.parseParameter(p));
+        }
+        if (operation.getRequestBody() != null)
+        operationObject.setRb(RequestBodyOb.parseRequestBody(operation.getRequestBody()));
+        if (operation.getResponses() != null) {
+        ResponsesObject r = new ResponsesObject();
+        for (String key : operation.getResponses().keySet())
+        r.addR(new ResponseTuple(key, ResponseObject.parseResponse(operation.getResponses().get(key))));
+        operationObject.setR(r);
+        }
+        if (operation.getCallbacks() != null) {
+        for (String key : operation.getCallbacks().keySet())
+        operationObject.addC(new CallbackTuple(key, CallbackObject.parseCallback(operation.getCallbacks().get(key))));
+        }
+        if (operation.getSecurity() != null) {
+        for (io.swagger.v3.oas.models.security.SecurityRequirement s : operation.getSecurity())
+        operationObject.addSr(SecurityRequirementObject.parseSecurityRequirement(s));
+        }
+        if (operation.getServers() != null) {
+        for (Server s : operation.getServers())
+        operationObject.addS(ServerObject.parseServer(s));
+        }
+        if (operation.getExtensions() != null) {
+        for (String key : operation.getExtensions().keySet())
+        operationObject.addEx(new Extension(key, operation.getExtensions().get(key)));
+        }
 
-    map.put(operation, operationObject);
-    return operationObject;
-  }
+        return operationObject;
+        }
 
-  public static ExternalDocObject ExternalDocObject.parseExternalDocs(ExternalDocs externalDocs, Map<Object, ASTNode> map){
-    ExternalDocObject externalDocObject = new ExternalDocObject();
+public static ExternalDocObject ExternalDocObject.parseExternalDocs(ExternalDocumentation externalDocs){
+        ExternalDocObject externalDocObject = new ExternalDocObject();
 
+        if (externalDocs.getDescription() != null)
+        externalDocObject.setDescription(externalDocs.getDescription());
+        if (externalDocs.getUrl() != null)
+        externalDocObject.setUrl(externalDocs.getUrl());
+        if (externalDocs.getExtensions() != null) {
+        for (String key : externalDocs.getExtensions().keySet())
+        externalDocObject.addEx(new Extension(key, externalDocs.getExtensions().get(key)));
+        }
 
-    if (externalDocs.getDescription() != null)
-      externalDocObject.setDescription(externalDocs.getDescription());
-    if (externalDocs.getUrl() != null)
-      externalDocObject.setUrl(externalDocs.getUrl());
-    if (externalDocs.getExtensions() != null) {
-      for (String key : externalDocs.getExtensions().keySet())
-        externalDocObject.addExtension(new Extension(key, externalDocs.getExtensions().get(key)));
-    }
+        return externalDocObject;
+        }
 
-    map.put(externalDocs, externalDocObject);
-    return externalDocObject;
-  }
+public static ParameterOb ParameterOb.parseParameter(Parameter parameter) {
+        ParameterObject parameterObject = new ParameterObject();
 
-  public static ParameterOb ParameterOb.parseParameter(Parameter parameter, OAIContext context, Map<Object, ASTNode> map) throws DecodeException {
-    ParameterObject parameterObject = new ParameterObject();
+        if (parameter.get$ref() != null) {
+        ParameterReference p = new ParameterReference();
+        p.setRef(parameter.get$ref());
 
-    if (parameter.isRef()) {
-      ParameterReference p = new ParameterReference();
-      p.setRef(parameter.getRef());
-      return p;
-    } else {
-      if (parameter.getName() != null)
+      /* 3.1.0 features
+      if (parameter.getSummary() != null) ...
+      if (parameter.getDescription() != null) ...
+      if (parameter.getParameter() != null) ...
+       */
+
+        return p;
+        } else {
+        if (parameter.getName() != null)
         parameterObject.setName(parameter.getName());
-      if (parameter.getIn() != null)
+        if (parameter.getIn() != null)
         parameterObject.setIn(parameter.getIn());
-      if (parameter.getDescription() != null)
+        if (parameter.getDescription() != null)
         parameterObject.setDescription(parameter.getDescription());
-      if (parameter.getDeprecated() != null)
+        if (parameter.getDeprecated() != null)
         parameterObject.setDeprecatedBoolean(parameter.getDeprecated());
-      if (parameter.getStyle() != null)
-        parameterObject.setStyle(parameter.getStyle());
-      if (parameter.getExplode() != null)
+        if (parameter.getStyle() != null)
+        parameterObject.setStyle(parameter.getStyle().toString());
+        if (parameter.getExplode() != null)
         parameterObject.setExplode(parameter.getExplode());
-      if (parameter.getAllowReserved() != null)
+        if (parameter.getAllowReserved() != null)
         parameterObject.setAllowReserved(parameter.getAllowReserved());
-      if (parameter.getSchema() != null)
-        parameterObject.setSchemaOb(SchemaOb.parseSchema(parameter.getSchema(), context, map));
-      if (parameter.getExample() != null)
+            if (parameter.getAllowEmptyValue() != null)
+                parameterObject.setAllowEmptyValue(parameter.getAllowEmptyValue());
+        if (parameter.getSchema() != null)
+        parameterObject.setSchema(SchemaOb.parseSchema(parameter.getSchema()));
+        if (parameter.getExample() != null)
         parameterObject.setExample(parameter.getExample());
-      if (parameter.getExamples() != null) {
+        if (parameter.getExamples() != null) {
         for (String key : parameter.getExamples().keySet())
-          parameterObject.addExampleTuple(new ExampleTuple(key, ExampleObject.parseExample(parameter.getExample(key), context, map)));
-      }
-      if (parameter.getContentMediaTypes() != null) {
-        for (String key : parameter.getContentMediaTypes().keySet())
-          parameterObject.addContentTuple(new ContentTuple(key, MediaTypeObject.parseMediaType(parameter.getContentMediaType(key), context, map)));
-      }
-      if (parameter.getRequired() != null)
+        parameterObject.addE(new ExampleTuple(key, ExampleObject.parseExample(parameter.getExamples().get(key))));
+        }
+        if (parameter.getContent() != null) {
+        for (String key : parameter.getContent().keySet())
+        parameterObject.addC(new ContentTuple(key, MediaTypeObject.parseMediaType(parameter.getContent().get(key))));
+        }
+        if (parameter.getRequired() != null)
         parameterObject.setRequired(parameter.getRequired());
-      if (parameter.getExtensions() != null) {
+        if (parameter.getExtensions() != null) {
         for (String key : parameter.getExtensions().keySet())
-          parameterObject.addExtension(new Extension(key, parameter.getExtensions().get(key)));
-      }
-    }
+        parameterObject.addEx(new Extension(key, parameter.getExtensions().get(key)));
+        }
+        }
 
-    map.put(parameter, parameterObject);
-    return parameterObject;
-  }
+        return parameterObject;
+        }
 
-  public static RequestBodyOb RequestBodyOb.parseRequestBody(org.openapi4j.parser.model.v3.RequestBody requestBody, OAIContext context, Map<Object, ASTNode> map) throws DecodeException {
-    RequestBodyObject requestBodyObject = new RequestBodyObject();
+public static RequestBodyOb RequestBodyOb.parseRequestBody(RequestBody requestBody) {
+        RequestBodyObject requestBodyObject = new RequestBodyObject();
 
-    if (requestBody.isRef()) {
-      RequestBodyReference r = new RequestBodyReference();
-      r.setRef(requestBody.getRef());
-      return r;
-    } else {
-      if (requestBody.getContentMediaTypes() != null) {
-        for (String key : requestBody.getContentMediaTypes().keySet())
-          requestBodyObject.addContentTuple(new ContentTuple(key, MediaTypeObject.parseMediaType(requestBody.getContentMediaType(key), context, map)));
-      }
-      if (requestBody.getDescription() != null)
+        if (requestBody.get$ref() != null) {
+        RequestBodyReference r = new RequestBodyReference();
+        r.setRef(requestBody.get$ref());
+
+      /* 3.1.0 features
+      if (requestBody.getSummary() != null) ...
+      if (requestBody.getDescription() != null) ...
+       */
+
+        return r;
+        } else {
+        if (requestBody.getContent() != null) {
+        for (String key : requestBody.getContent().keySet())
+        requestBodyObject.addC(new ContentTuple(key, MediaTypeObject.parseMediaType(requestBody.getContent().get(key))));
+        }
+        if (requestBody.getDescription() != null)
         requestBodyObject.setDescription(requestBody.getDescription());
-      if (requestBody.getRequired() != null)
+        if (requestBody.getRequired() != null)
         requestBodyObject.setRequired(requestBody.getRequired());
-      if (requestBody.getExtensions() != null) {
+        if (requestBody.getExtensions() != null) {
         for (String key : requestBody.getExtensions().keySet())
-          requestBodyObject.addExtension(new Extension(key, requestBody.getExtensions().get(key)));
-      }
-    }
+        requestBodyObject.addEx(new Extension(key, requestBody.getExtensions().get(key)));
+        }
+        }
+
+        return requestBodyObject;
+        }
 
-    map.put(requestBody, requestBodyObject);
-    return requestBodyObject;
-  }
+public static MediaTypeObject MediaTypeObject.parseMediaType(MediaType mediaType) {
+        MediaTypeObject mediaTypeObject = new MediaTypeObject();
 
-  public static MediaTypeObject MediaTypeObject.parseMediaType(MediaType mediaType, OAIContext context, Map<Object, ASTNode> map) throws DecodeException {
-    MediaTypeObject mediaTypeObject = new MediaTypeObject();
+        if (mediaType.getSchema() != null)
+        mediaTypeObject.setS(SchemaObject.parseSchema(mediaType.getSchema()));
+        if (mediaType.getExample() != null)
+        mediaTypeObject.setExample(mediaType.getExample());
+        if (mediaType.getExamples() != null) {
+        for (String key : mediaType.getExamples().keySet())
+        mediaTypeObject.addE(new ExampleTuple(key, ExampleObject.parseExample(mediaType.getExamples().get(key))));
+        }
+        if (mediaType.getEncoding() != null) {
+        for (String key : mediaType.getEncoding().keySet())
+        mediaTypeObject.addEn(new EncodingTuple(key, EncodingObject.parseEncoding(mediaType.getEncoding().get(key))));
+        }
+        if (mediaType.getExtensions() != null) {
+        for (String key : mediaType.getExtensions().keySet())
+        mediaTypeObject.addEx(new Extension(key, mediaType.getExtensions().get(key)));
+        }
 
-    if (mediaType.getSchema() != null)
-      mediaTypeObject.setSchemaOb(SchemaObject.parseSchema(mediaType.getSchema(), context, map));
-    if (mediaType.getExample() != null)
-      mediaTypeObject.setExample(mediaType.getExample());
-    if (mediaType.getExamples() != null) {
-      for (String key : mediaType.getExamples().keySet())
-        mediaTypeObject.addExampleTuple(new ExampleTuple(key, ExampleObject.parseExample(mediaType.getExample(key), context, map)));
-    }
-    if (mediaType.getEncodings() != null) {
-      for (String key : mediaType.getEncodings().keySet())
-        mediaTypeObject.addEncodingTuple(new EncodingTuple(key, EncodingObject.parseEncoding(mediaType.getEncoding(key), context, map)));
-    }
-    if (mediaType.getExtensions() != null) {
-      for (String key : mediaType.getExtensions().keySet())
-        mediaTypeObject.addExtension(new Extension(key, mediaType.getExtensions().get(key)));
-    }
+        return mediaTypeObject;
+        }
 
-    map.put(mediaType, mediaTypeObject);
-    return mediaTypeObject;
-  }
+public static EncodingObject EncodingObject.parseEncoding(Encoding encodingProperty) {
+        EncodingObject encodingObject = new EncodingObject();
 
-  public static EncodingObject EncodingObject.parseEncoding(EncodingProperty encodingProperty, OAIContext context, Map<Object, ASTNode> map) throws DecodeException {
-    EncodingObject encodingObject = new EncodingObject();
+        if (encodingProperty.getContentType() != null)
+        encodingObject.setContentType(encodingProperty.getContentType());
+        if (encodingProperty.getHeaders() != null) {
+        for (String key : encodingProperty.getHeaders().keySet())
+        encodingObject.addH(new HeaderTuple(key, HeaderObject.parseHeader(encodingProperty.getHeaders().get(key))));
+        }
+        if (encodingProperty.getStyle() != null)
+        encodingObject.setStyle(encodingProperty.getStyle().toString());
+        if (encodingProperty.getExplode() != null)
+        encodingObject.setExplode(encodingProperty.getExplode());
+        if (encodingProperty.getAllowReserved() != null)
+        encodingObject.setAllowReserved(encodingProperty.getAllowReserved());
+        if (encodingProperty.getExtensions() != null) {
+        for (String key : encodingProperty.getExtensions().keySet())
+        encodingObject.addEx(new Extension(key, encodingProperty.getExtensions().get(key)));
+        }
 
-    if (encodingProperty.getContentType() != null)
-      encodingObject.setContentType(encodingProperty.getContentType());
-    if (encodingProperty.getHeaders() != null) {
-      for (String key : encodingProperty.getHeaders().keySet())
-        encodingObject.addHeaderTuple(new HeaderTuple(key, HeaderObject.parseHeader(encodingProperty.getHeader(key), context, map)));
-    }
-    if (encodingProperty.getStyle() != null)
-      encodingObject.setStyle(encodingProperty.getStyle());
-    if (encodingProperty.getExplode() != null)
-      encodingObject.setExplode(encodingProperty.getExplode());
-    if (encodingProperty.getExtensions() != null) {
-      for (String key : encodingProperty.getExtensions().keySet())
-        encodingObject.addExtension(new Extension(key, encodingProperty.getExtensions().get(key)));
-    }
+        return encodingObject;
+        }
 
-    map.put(encodingProperty, encodingObject);
-    return encodingObject;
-  }
+public static ResponseOb ResponseOb.parseResponse(ApiResponse response) {
+        ResponseObject responseObject = new ResponseObject();
 
-  public static ResponseOb ResponseOb.parseResponse(Response response, OAIContext context, Map<Object, ASTNode> map) throws DecodeException {
-    ResponseObject responseObject = new ResponseObject();
+        if (response.get$ref() != null) {
+        ResponseReference r = new ResponseReference();
+        r.setRef(response.get$ref());
 
-    if (response.isRef()) {
-      ResponseReference r = new ResponseReference();
-      r.setRef(response.getRef());
-      return r;
-    } else {
-      if (response.getDescription() != null)
+      /* 3.1.0 features
+      if (response.getSummary() != null) ...
+      if (response.getDescription() != null) ...
+       */
+
+        return r;
+        } else {
+        if (response.getDescription() != null)
         responseObject.setDescription(response.getDescription());
-      if (response.getHeaders() != null) {
+        if (response.getHeaders() != null) {
         for (String key : response.getHeaders().keySet())
-          responseObject.addHeaderTuple(new HeaderTuple(key, HeaderObject.parseHeader(response.getHeader(key), context, map)));
-      }
-      if (response.getContentMediaTypes() != null) {
-        for (String key : response.getContentMediaTypes().keySet())
-          responseObject.addContentTuple(new ContentTuple(key, MediaTypeObject.parseMediaType(response.getContentMediaType(key), context, map)));
-      }
-      if (response.getLinks() != null) {
+        responseObject.addH(new HeaderTuple(key, HeaderObject.parseHeader(response.getHeaders().get(key))));
+        }
+        if (response.getContent() != null) {
+        for (String key : response.getContent().keySet())
+        responseObject.addC(new ContentTuple(key, MediaTypeObject.parseMediaType(response.getContent().get(key))));
+        }
+        if (response.getLinks() != null) {
         for (String key : response.getLinks().keySet())
-          responseObject.addLinkTuple(new LinkTuple(key, LinkOb.parseLink(response.getLink(key), context, map)));
-      }
-      if (response.getExtensions() != null) {
-        for (String key : response.getExtensions().keySet())
-          responseObject.addExtension(new Extension(key, response.getExtensions().get(key)));
-      }
-    }
+        responseObject.addL(new LinkTuple(key, LinkOb.parseLink(response.getLinks().get(key))));
+        }
+        if (response.getExtensions() != null) {
+        for (String key : response.getExtensions().keySet()) {
+            responseObject.addEx(new Extension(key, response.getExtensions().get(key)));
+        }
+        }
+        }
 
-    map.put(response, responseObject);
-    return responseObject;
-  }
+        return responseObject;
+        }
 
-  public static CallbackOb CallbackOb.parseCallback(Callback callback, OAIContext context, Map<Object, ASTNode> map) throws DecodeException {
-    CallbackObject callbackObject = new CallbackObject();
+public static CallbackOb CallbackOb.parseCallback(Callback callback) {
+        CallbackObject callbackObject = new CallbackObject();
 
-    if (callback.isRef()) {
-      CallbackReference c = new CallbackReference();
-      c.setRef(callback.getRef());
-      return c;
-    } else {
-      if (callback.getCallbackPaths() != null) {
-        for (String key : callback.getCallbackPaths().keySet())
-          callbackObject.addExpression(new Expression(key, PathItemObject.parsePath(callback.getCallbackPath(key), context, map)));
-      }
-      if (callback.getExtensions() != null) {
+        if (callback.get$ref() != null) {
+        CallbackReference c = new CallbackReference();
+        c.setRef(callback.get$ref());
+
+      /* 3.1.0 features
+      if (callback.getSummary() != null) ...
+      if (callback.getDescription() != null) ...
+       */
+
+        return c;
+        } else {
+        if (callback != null) {
+        for (String key : callback.keySet())
+        callbackObject.addE(new Expression(key, PathItemObject.parsePath(callback.get(key))));
+        }
+        if (callback.getExtensions() != null) {
         for (String key : callback.getExtensions().keySet())
-          callbackObject.addExtension(new Extension(key, callback.getExtensions().get(key)));
-      }
-    }
+        callbackObject.addEx(new Extension(key, callback.getExtensions().get(key)));
+        }
+        }
 
-    map.put(callback, callbackObject);
-    return callbackObject;
-  }
-
-  public static ExampleObject ExampleObject.parseExample(Example example, OAIContext context, Map<Object, ASTNode> map){
-    ExampleObject exampleObject = new ExampleObject();
-
-    if (example.getSummary() != null)
-      exampleObject.setSummary(example.getSummary());
-    if (example.getDescription() != null)
-      exampleObject.setDescription(example.getDescription());
-    if (example.getValue() != null)
-      exampleObject.setValue(example.getValue());
-    if (example.getExternalValue() != null)
-      exampleObject.setExternalValue(example.getExternalValue());
-    if (example.getExtensions() != null) {
-      for (String key : example.getExtensions().keySet())
-        exampleObject.addExtension(new Extension(key, example.getExtensions().get(key)));
-    }
-    if (example.getExtensions() != null) {
-      for (String key : example.getExtensions().keySet())
-        exampleObject.addExtension(new Extension(key, example.getExtensions().get(key)));
+        return callbackObject;
+        }
+public static ExampleOb ExampleOb.parseExample(Example example){
+        ExampleObject exampleObject = new ExampleObject();
+
+    if (example.get$ref() != null) {
+        ExampleReference e = new ExampleReference();
+        e.setRef(example.get$ref());
+
+      /* 3.1.0 features
+      if (example.getSummary() != null) ...
+      if (example.getDescription() != null) ...
+       */
+
+        return e;
+    } else {
+
+        if (example.getSummary() != null)
+        exampleObject.setSummary(example.getSummary());
+        if (example.getDescription() != null)
+        exampleObject.setDescription(example.getDescription());
+        if (example.getValue() != null)
+        exampleObject.setValue(example.getValue());
+        if (example.getExternalValue() != null)
+        exampleObject.setExternalValue(example.getExternalValue());
+        if (example.getExtensions() != null) {
+        for (String key : example.getExtensions().keySet())
+        exampleObject.addEx(new Extension(key, example.getExtensions().get(key)));
+        }
     }
 
+        return exampleObject;
+        }
+
+public static LinkOb LinkOb.parseLink(Link link) {
+        LinkObject linkObject = new LinkObject();
 
-    map.put(example, exampleObject);
-    return exampleObject;
-  }
+        if (link.get$ref() != null) {
+        LinkReference l = new LinkReference();
+        l.setRef(link.get$ref());
 
-  public static LinkOb LinkOb.parseLink(Link link, OAIContext context, Map<Object, ASTNode> map) throws DecodeException {
-    LinkObject linkObject = new LinkObject();
+      /* 3.1.0 features
+      if (link.getSummary() != null) ...
+      if (link.getDescription() != null) ...
+       */
 
-    if (link.isRef()) {
-      LinkReference l = new LinkReference();
-      l.setRef(link.getRef());
-      return l;
-    } else {
-      if (link.getOperationRef() != null)
+        return l;
+        } else {
+        if (link.getOperationRef() != null)
         linkObject.setOperationRef(link.getOperationRef());
-      if (link.getOperationId() != null)
+        if (link.getOperationId() != null)
         linkObject.setOperationID(link.getOperationId());
-      if (link.getParameters() != null) {
+        if (link.getParameters() != null) {
         for (String key : link.getParameters().keySet())
-          linkObject.addLinkParameterTuple(new LinkParameterTuple(key, link.getParameter(key)));
-      }
-      if (link.getDescription() != null)
+        linkObject.addL(new LinkParameterTuple(key, link.getParameters().get(key)));
+        }
+        if (link.getDescription() != null)
         linkObject.setDescription(link.getDescription());
-      if (link.getServer() != null)
-        linkObject.setServerObject(ServerObject.parseServer(link.getServer(), map));
-      if (link.getExtensions() != null) {
+        if (link.getServer() != null)
+        linkObject.setS(ServerObject.parseServer(link.getServer()));
+        if (link.getExtensions() != null) {
         for (String key : link.getExtensions().keySet())
-          linkObject.addExtension(new Extension(key, link.getExtensions().get(key)));
-      }
-    }
+        linkObject.addEx(new Extension(key, link.getExtensions().get(key)));
+        }
+        }
+
+        return linkObject;
+        }
 
-    map.put(link, linkObject);
-    return linkObject;
-  }
+public static HeaderOb HeaderOb.parseHeader(Header header) {
+        HeaderObject headerObject = new HeaderObject();
 
-  public static HeaderOb HeaderOb.parseHeader(Header header, OAIContext context, Map<Object, ASTNode> map) throws DecodeException {
-    HeaderObject headerObject = new HeaderObject();
+        if (header.get$ref() != null) {
+        HeaderReference h = new HeaderReference();
+        h.setRef(header.get$ref());
 
-    if (header.isRef()) {
-      HeaderReference h = new HeaderReference();
-      h.setRef(header.getRef());
-      return h;
-    } else {
-      if (header.getRequired() != null)
+      /* 3.1.0 features
+      if (header.getSummary() != null) ...
+      if (header.getDescription() != null) ...
+       */
+
+        return h;
+        } else {
+        if (header.getRequired() != null)
         headerObject.setRequired(header.getRequired());
-      if (header.getDescription() != null)
+        if (header.getDescription() != null)
         headerObject.setDescription(header.getDescription());
-      if (header.getDeprecated() != null)
+        if (header.getDeprecated() != null)
         headerObject.setDeprecatedBoolean(header.getDeprecated());
-      if (header.getStyle() != null)
-        headerObject.setStyle(header.getStyle());
-      if (header.getExplode() != null)
+        if (header.getStyle() != null)
+        headerObject.setStyle(header.getStyle().toString());
+        if (header.getExplode() != null)
         headerObject.setExplode(header.getExplode());
-      if (header.getAllowReserved() != null)
-        headerObject.setExplode(header.getAllowReserved());
-      if (header.getExample() != null)
+        if (header.getExample() != null)
         headerObject.setExample(header.getExample());
-      if (header.getExamples() != null) {
+        if (header.getExamples() != null) {
         for (String key : header.getExamples().keySet())
-          headerObject.addExampleTuple(new ExampleTuple(key, ExampleObject.parseExample(header.getExample(key), context, map)));
-      }
-      if (header.getContentMediaTypes() != null) {
-        for (String key : header.getContentMediaTypes().keySet())
-          headerObject.addContentTuple(new ContentTuple(key, MediaTypeObject.parseMediaType(header.getContentMediaType(key), context, map)));
-      }
-      if (header.getSchema() != null)
-        headerObject.setSchemaOb(SchemaOb.parseSchema(header.getSchema(), context, map));
-      if (header.getExtensions() != null) {
+        headerObject.addE(new ExampleTuple(key, ExampleObject.parseExample(header.getExamples().get(key))));
+        }
+        if (header.getContent() != null) {
+        for (String key : header.getContent().keySet())
+        headerObject.addC(new ContentTuple(key, MediaTypeObject.parseMediaType(header.getContent().get(key))));
+        }
+        if (header.getSchema() != null)
+        headerObject.setS(SchemaOb.parseSchema(header.getSchema()));
+        if (header.getExtensions() != null) {
         for (String key : header.getExtensions().keySet())
-          headerObject.addExtension(new Extension(key, header.getExtensions().get(key)));
-      }
-    }
+        headerObject.addEx(new Extension(key, header.getExtensions().get(key)));
+        }
+        }
 
-    map.put(header, headerObject);
-    return headerObject;
-  }
+        return headerObject;
+        }
 
-  public static TagObject TagObject.parseTag(org.openapi4j.parser.model.v3.Tag tag, Map<Object, ASTNode> map){
-    TagObject tagObject = new TagObject();
+public static TagObject TagObject.parseTag(io.swagger.v3.oas.models.tags.Tag tag){
+        TagObject tagObject = new TagObject();
 
-    tagObject.setName(tag.getName());
+        tagObject.setName(tag.getName());
 
-    if (tag.getDescription() != null)
-      tagObject.setDescription(tag.getDescription());
-    if (tag.getExternalDocs() != null)
-      tagObject.setExternalDocObject(ExternalDocObject.parseExternalDocs(tag.getExternalDocs(), map));
-    if (tag.getExtensions() != null) {
-      for (String key : tag.getExtensions().keySet())
-        tagObject.addExtension(new Extension(key, tag.getExtensions().get(key)));
-    }
-    if (tag.getExtensions() != null) {
-      for (String key : tag.getExtensions().keySet())
-        tagObject.addExtension(new Extension(key, tag.getExtensions().get(key)));
-    }
+        if (tag.getDescription() != null)
+        tagObject.setDescription(tag.getDescription());
+        if (tag.getExternalDocs() != null)
+        tagObject.setE(ExternalDocObject.parseExternalDocs(tag.getExternalDocs()));
+        if (tag.getExtensions() != null) {
+        for (String key : tag.getExtensions().keySet())
+        tagObject.addEx(new Extension(key, tag.getExtensions().get(key)));
+        }
 
-    map.put(tag, tagObject);
-    return tagObject;
-  }
+        return tagObject;
+        }
 
-  public static SchemaOb SchemaOb.parseSchema (org.openapi4j.parser.model.v3.Schema schema, OAIContext context, Map<Object, ASTNode> map) throws DecodeException {
-    SchemaObject schemaObject = new SchemaObject();
+public static SchemaOb SchemaOb.parseSchema (Schema<?> schema) {
+        SchemaObject schemaObject = new SchemaObject();
 
-    if (schema.isRef()) {
-      SchemaReference s = new SchemaReference();
-      s.setRef(schema.getRef());
-      return s;
-    } else {
-      if (schema.getAdditionalProperties() != null)
-        schemaObject.setAdditionalProperties(new AdditionalProperties(parseSchema(schema.getAdditionalProperties(), context, map)));
-      if (schema.getAdditionalProperties() == null && schema.getAdditionalPropertiesAllowed() != null)
-        schemaObject.setAdditionalPropertiesAllowed(schema.getAdditionalPropertiesAllowed());
-      if (schema.getDefault() != null)
+        if (schema.get$ref() != null) {
+        SchemaReference s = new SchemaReference();
+        s.setRef(schema.get$ref());
+
+      /* 3.1.0 features
+      if (schema.getSummary() != null) ...
+      if (schema.getDescription() != null) ...
+       */
+
+        return s;
+        } else {
+        if (schema.getName() != null)
+        schemaObject.setName(schema.getName());
+
+        if (schema.getAdditionalProperties() != null)
+        schemaObject.setAdditionalProperties(schema.getAdditionalProperties());
+        if (schema.getDefault() != null)
         schemaObject.setDefaultValue(schema.getDefault());
-      if (schema.getDescription() != null)
+        if (schema.getDescription() != null)
         schemaObject.setDescription(schema.getDescription());
-      if (schema.getDeprecated() != null)
+        if (schema.getDeprecated() != null)
         schemaObject.setDeprecatedBoolean(schema.getDeprecated());
-      if (schema.getDiscriminator() != null)
-        schemaObject.setDiscriminatorObject(DiscriminatorObject.parseDiscriminator(schema.getDiscriminator(), map));
-      if (schema.getEnums() != null) {
-        for (Object o : schema.getEnums()) {
-          EnumObj enumObj = new EnumObj();
-          enumObj.setEnumOb(o);
-          schemaObject.addEnumObj(enumObj);
-        }
-      }
-      if (schema.getExample() != null)
-        schemaObject.setExample(schema.getExample());
-      if (schema.getExclusiveMaximum() != null)
+        if (schema.getDiscriminator() != null)
+        schemaObject.setD(DiscriminatorObject.parseDiscriminator(schema.getDiscriminator()));
+        if (schema.getEnum() != null) {
+        for (Object o : schema.getEnum()) {
+        EnumObj enumObj = new EnumObj();
+        enumObj.setEnumOb(o);
+        schemaObject.addE(enumObj);
+        }
+        }
+        // in 3.1.0, there are multiple examples
+        if (schema.getExample() != null)
+        schemaObject.addEl(new ExampleElement(schema.getExample()));
+        // in 3.1.0, types are Number instead of Boolean
+        if (schema.getExclusiveMaximum() != null)
         schemaObject.setExclusiveMaximum(schema.getExclusiveMaximum());
-      if (schema.getExclusiveMinimum() != null)
+        if (schema.getExclusiveMinimum() != null)
         schemaObject.setExclusiveMinimum(schema.getExclusiveMinimum());
-      if (schema.getExternalDocs() != null)
-        schemaObject.setExternalDocObject(ExternalDocObject.parseExternalDocs(schema.getExternalDocs(), map));
-      if (schema.getFormat() != null)
+        if (schema.getExternalDocs() != null)
+        schemaObject.setExt(ExternalDocObject.parseExternalDocs(schema.getExternalDocs()));
+        if (schema.getFormat() != null)
         schemaObject.setFormat(schema.getFormat());
-      if (schema.getItemsSchema() != null) {
-        ItemsSchema itemsSchema = new ItemsSchema();
-        itemsSchema.setSchemaOb(parseSchema(schema.getItemsSchema(), context, map));
-        schemaObject.setItemsSchema(itemsSchema);
-      }
-      if (schema.getMaximum() != null)
+        if (schema.getMaximum() != null)
         schemaObject.setMaximum(schema.getMaximum());
-      if (schema.getMinimum() != null)
+        if (schema.getMinimum() != null)
         schemaObject.setMinimum(schema.getMinimum());
-      if (schema.getMaxItems() != null)
+        if (schema.getMaxItems() != null)
         schemaObject.setMaxItems(schema.getMaxItems());
-      if (schema.getMinItems() != null)
+        if (schema.getMinItems() != null)
         schemaObject.setMinItems(schema.getMinItems());
-      if (schema.getMaxLength() != null)
+        if (schema.getMaxLength() != null)
         schemaObject.setMaxLength(schema.getMaxLength());
-      if (schema.getMinLength() != null)
+        if (schema.getMinLength() != null)
         schemaObject.setMinLength(schema.getMinLength());
-      if (schema.getMaxProperties() != null)
+        if (schema.getMaxProperties() != null)
         schemaObject.setMaxProperties(schema.getMaxProperties());
-      if (schema.getMinProperties() != null)
+        if (schema.getMinProperties() != null)
         schemaObject.setMinProperties(schema.getMinProperties());
-      if (schema.getMultipleOf() != null)
+        if (schema.getMultipleOf() != null)
         schemaObject.setMultipleOf(schema.getMultipleOf());
-      if (schema.getNotSchema() != null) {
-        NotSchema notSchema = new NotSchema();
-        notSchema.setSchemaOb(parseSchema(schema.getNotSchema(), context, map));
-        schemaObject.setNotSchema(notSchema);
-      }
-      if (schema.getNullable() != null)
+        if (schema.getNullable() != null)
         schemaObject.setNullable(schema.getNullable());
-      if (schema.getPattern() != null)
+        if (schema.getNot() != null) {
+        NotSchema notSchema = new NotSchema();
+        notSchema.setSchema(parseSchema(schema.getNot()));
+        schemaObject.setN(notSchema);
+        }
+        if (schema.getPattern() != null)
         schemaObject.setPattern(schema.getPattern());
-      if (schema.getProperties() != null) {
-        for (String key : schema.getProperties().keySet()) {
-          PropertyItem propertyItem = new PropertyItem();
-          schemaObject.addPropertyItem(new PropertyItem(key, parseSchema(schema.getProperty(key), context, map)));
-        }
-      }
-      if (schema.getRequiredFields() != null) {
-        for (String s : schema.getRequiredFields()) {
-          RequiredField requiredField = new RequiredField();
-          requiredField.setValue(s);
-          schemaObject.addRequiredField(requiredField);
-        }
-      }
-      if (schema.getAllOfSchemas() != null) {
-        for (org.openapi4j.parser.model.v3.Schema schemaItem : schema.getAllOfSchemas()) {
-          AllOfSchema allOfSchema = new AllOfSchema();
-          allOfSchema.setSchemaOb(parseSchema(schemaItem, context, map));
-          schemaObject.addAllOfSchema(allOfSchema);
-        }
-      }
-      if (schema.getAnyOfSchemas() != null) {
-        for (org.openapi4j.parser.model.v3.Schema schemaItem : schema.getAnyOfSchemas()) {
-          AnyOfSchema anyOfSchema = new AnyOfSchema();
-          anyOfSchema.setSchemaOb(parseSchema(schemaItem, context, map));
-          schemaObject.addAnyOfSchema(anyOfSchema);
-        }
-      }
-      if (schema.getOneOfSchemas() != null) {
-        for (org.openapi4j.parser.model.v3.Schema schemaItem : schema.getOneOfSchemas()) {
-          OneOfSchema oneOfSchema = new OneOfSchema();
-          oneOfSchema.setSchemaOb(parseSchema(schemaItem, context, map));
-          schemaObject.addOneOfSchema(oneOfSchema);
-        }
-      }
-      if (schema.getReadOnly() != null)
+                if (schema.getProperties() != null) {
+                        for (String key : schema.getProperties().keySet())
+                                schemaObject.addP(new PropertyItem(key, parseSchema(schema.getProperties().get(key))));
+                }
+        if (schema.getRequired() != null) {
+        for (String s : schema.getRequired()) {
+        RequiredField requiredField = new RequiredField();
+        requiredField.setValue(s);
+        schemaObject.addR(requiredField);
+        }
+        }
+        if (schema instanceof ArraySchema){
+        if (((ArraySchema) schema).getItems() != null){
+        ItemsSchema itemsSchema = new ItemsSchema();
+        itemsSchema.setSchema(parseSchema(((ArraySchema) schema).getItems()));
+        schemaObject.setI(itemsSchema);
+        }
+        }
+        if (schema instanceof ComposedSchema){
+        if (((ComposedSchema) schema).getOneOf() != null){
+        for (Schema s : ((ComposedSchema) schema).getOneOf())
+        schemaObject.addOne(new OneOfSchema(parseSchema(s)));
+        }
+        if (((ComposedSchema) schema).getAnyOf() != null){
+        for (Schema s : ((ComposedSchema) schema).getAnyOf())
+        schemaObject.addAny(new AnyOfSchema(parseSchema(s)));
+        }
+        if (((ComposedSchema) schema).getAllOf() != null){
+        for (Schema s : ((ComposedSchema) schema).getAllOf())
+        schemaObject.addAll(new AllOfSchema(parseSchema(s)));
+        }
+        }
+        if (schema.getReadOnly() != null)
         schemaObject.setReadOnly(schema.getReadOnly());
-      if (schema.getWriteOnly() != null)
+        if (schema.getWriteOnly() != null)
         schemaObject.setWriteOnly(schema.getWriteOnly());
-      if (schema.getType() != null)
+        if (schema.getType() != null)
         schemaObject.setType(schema.getType());
-      if (schema.getTitle() != null)
+        if (schema.getTitle() != null)
         schemaObject.setTitle(schema.getTitle());
-      if (schema.getUniqueItems() != null)
+        if (schema.getUniqueItems() != null)
         schemaObject.setUniqueItems(schema.getUniqueItems());
-      if (schema.getXml() != null)
-        schemaObject.setXmlObject(XmlObject.parseXml(schema.getXml(), map));
-      if (schema.getExtensions() != null) {
+        if (schema.getXml() != null)
+        schemaObject.setX(XmlObject.parseXml(schema.getXml()));
+        if (schema.getExtensions() != null) {
         for (String key : schema.getExtensions().keySet())
-          schemaObject.addExtension(new Extension(key, schema.getExtensions().get(key)));
-      }
-    }
+        schemaObject.addEx(new Extension(key, schema.getExtensions().get(key)));
+        }
+        }
 
-    map.put(schema, schemaObject);
-    return schemaObject;
-  }
-
-  public static DiscriminatorObject DiscriminatorObject.parseDiscriminator (Discriminator discriminator, Map<Object, ASTNode> map) {
-    DiscriminatorObject discriminatorObject = new DiscriminatorObject();
-
-    if (discriminator.getPropertyName() != null)
-      discriminatorObject.setPropertyName(discriminator.getPropertyName());
-    if (discriminator.getMapping() != null) {
-      MappingTuple mapping = new MappingTuple();
-      for (String key : discriminator.getMapping().keySet()) {
-        mapping.setKey(key);
-        mapping.setValue(discriminator.getMapping().get(key));
-        discriminatorObject.addMappingTuple(mapping);
-      }
-    }
-    map.put(discriminator, discriminatorObject);
-
-    return discriminatorObject;
-  }
-
-  public static XmlObject XmlObject.parseXml (Xml xml, Map<Object, ASTNode> map) {
-    XmlObject xmlObject = new XmlObject();
-
-    if (xml.getName() != null)
-      xmlObject.setName(xml.getName());
-    if (xml.getNamespace() != null)
-      xmlObject.setNamespace(xml.getNamespace());
-    if (xml.getPrefix() != null)
-      xmlObject.setPrefix(xml.getPrefix());
-    if (xml.getAttribute() != null)
-      xmlObject.setAttribute(xml.getAttribute());
-    if (xml.getWrapped() != null)
-      xmlObject.setWrapped(xml.getWrapped());
-    map.put(xml, xmlObject);
-    if (xml.getExtensions() != null) {
-      for (String key : xml.getExtensions().keySet())
-        xmlObject.addExtension(new Extension(key, xml.getExtensions().get(key)));
-    }
+        return schemaObject;
+        }
 
-    return xmlObject;
-  }
-
-  public static SecuritySchemeOb SecuritySchemeOb.parseSecurityScheme(SecurityScheme securityScheme, OAIContext context, Map<Object, ASTNode> map){
-    SecuritySchemeObject securitySchemeObject = new SecuritySchemeObject();
-
-    if (securityScheme.getType() != null)
-      securitySchemeObject.setType(securityScheme.getType());
-    if (securityScheme.getName() != null)
-      securitySchemeObject.setName(securityScheme.getName());
-    if (securityScheme.getIn() != null)
-      securitySchemeObject.setIn(securityScheme.getIn());
-    if (securityScheme.getScheme() != null)
-      securitySchemeObject.setScheme(securityScheme.getScheme());
-    if (securityScheme.getOpenIdConnectUrl() != null)
-      securitySchemeObject.setOpenIdConnectUrl(securityScheme.getOpenIdConnectUrl());
-    if (securityScheme.getFlows() != null)
-      securitySchemeObject.setOAuthFlowsObject(OAuthFlowsObject.parseOAuthFlows(securityScheme.getFlows(), map));
-    if (securityScheme.getDescription() != null)
-      securitySchemeObject.setDescription(securityScheme.getDescription());
-    if (securityScheme.getBearerFormat() != null)
-      securitySchemeObject.setBearerFormat(securityScheme.getBearerFormat());
-    if (securityScheme.getExtensions() != null) {
-      for (String key : securityScheme.getExtensions().keySet())
-        securitySchemeObject.addExtension(new Extension(key, securityScheme.getExtensions().get(key)));
-    }
+public static DiscriminatorObject DiscriminatorObject.parseDiscriminator (Discriminator discriminator) {
+        DiscriminatorObject discriminatorObject = new DiscriminatorObject();
+
+        if (discriminator.getPropertyName() != null)
+                discriminatorObject.setPropertyName(discriminator.getPropertyName());
+        if (discriminator.getMapping() != null) {
+                for (String key : discriminator.getMapping().keySet()) {
+                        MappingTuple mapping = new MappingTuple();
+                        mapping.setKey(key);
+                        mapping.setValue(discriminator.getMapping().get(key));
+                        discriminatorObject.addM(mapping);
+                }
+        }
+
+        return discriminatorObject;
+        }
 
-    map.put(securityScheme, securitySchemeObject);
-    return securitySchemeObject;
-  }
+public static XmlObject XmlObject.parseXml (XML xml) {
+        XmlObject xmlObject = new XmlObject();
+
+        if (xml.getName() != null)
+        xmlObject.setName(xml.getName());
+        if (xml.getNamespace() != null)
+        xmlObject.setNamespace(xml.getNamespace());
+        if (xml.getPrefix() != null)
+        xmlObject.setPrefix(xml.getPrefix());
+        if (xml.getAttribute() != null)
+        xmlObject.setAttribute(xml.getAttribute());
+        if (xml.getWrapped() != null)
+        xmlObject.setWrapped(xml.getWrapped());
+        if (xml.getExtensions() != null) {
+        for (String key : xml.getExtensions().keySet())
+        xmlObject.addEx(new Extension(key, xml.getExtensions().get(key)));
+        }
 
-  public static OAuthFlowsObject OAuthFlowsObject.parseOAuthFlows(OAuthFlows oAuthFlows, Map<Object, ASTNode> map){
-    OAuthFlowsObject oAuthFlowsObject = new OAuthFlowsObject();
-    Implicit implicit = new Implicit();
-    Password password = new Password();
-    ClientCredentials clientCredentials = new ClientCredentials();
-    AuthorizationCode authorizationCode = new AuthorizationCode();
+        return xmlObject;
+        }
 
-    if (oAuthFlows.getImplicit() != null) {
-      implicit.setOAuthFlowObject(OAuthFlowObject.parseOAuthFlow(oAuthFlows.getImplicit(), map));
-      oAuthFlowsObject.setImplicit(implicit);
-    }
-    if (oAuthFlows.getPassword() != null) {
-      password.setOAuthFlowObject(OAuthFlowObject.parseOAuthFlow(oAuthFlows.getPassword(), map));
-      oAuthFlowsObject.setPassword(password);
-    }
-    if (oAuthFlows.getClientCredentials() != null) {
-      clientCredentials.setOAuthFlowObject(OAuthFlowObject.parseOAuthFlow(oAuthFlows.getClientCredentials(), map));
-      oAuthFlowsObject.setClientCredentials(clientCredentials);
-    }
-    if (oAuthFlows.getAuthorizationCode() != null) {
-      authorizationCode.setOAuthFlowObject(OAuthFlowObject.parseOAuthFlow(oAuthFlows.getAuthorizationCode(), map));
-      oAuthFlowsObject.setAuthorizationCode(authorizationCode);
-    }
-    if (oAuthFlows.getExtensions() != null) {
-      for (String key : oAuthFlows.getExtensions().keySet())
-        oAuthFlowsObject.addExtension(new Extension(key, oAuthFlows.getExtensions().get(key)));
-    }
+public static SecuritySchemeOb SecuritySchemeOb.parseSecurityScheme(SecurityScheme securityScheme){
+        SecuritySchemeObject securitySchemeObject = new SecuritySchemeObject();
+
+        if(securityScheme.get$ref() != null){
+        SecuritySchemeReference r = new SecuritySchemeReference();
+        r.setRef(securityScheme.get$ref());
+
+      /* 3.1.0 features
+      if (securityScheme.getSummary() != null) ...
+      if (securityScheme.getDescription() != null) ...
+       */
+
+        return r;
+        } else {
+        if (securityScheme.getType() != null)
+        securitySchemeObject.setType(securityScheme.getType().toString());
+        if (securityScheme.getName() != null)
+        securitySchemeObject.setName(securityScheme.getName());
+        if (securityScheme.getIn() != null)
+        securitySchemeObject.setIn(securityScheme.getIn().toString());
+        if (securityScheme.getScheme() != null)
+        securitySchemeObject.setScheme(securityScheme.getScheme());
+        if (securityScheme.getOpenIdConnectUrl() != null)
+        securitySchemeObject.setOpenIdConnectUrl(securityScheme.getOpenIdConnectUrl());
+        if (securityScheme.getFlows() != null)
+        securitySchemeObject.setO(OAuthFlowsObject.parseOAuthFlows(securityScheme.getFlows()));
+        if (securityScheme.getDescription() != null)
+        securitySchemeObject.setDescription(securityScheme.getDescription());
+        if (securityScheme.getBearerFormat() != null)
+        securitySchemeObject.setBearerFormat(securityScheme.getBearerFormat());
+        if (securityScheme.getExtensions() != null) {
+        for (String key : securityScheme.getExtensions().keySet())
+        securitySchemeObject.addEx(new Extension(key, securityScheme.getExtensions().get(key)));
+        }
+        }
 
-    map.put(oAuthFlows, oAuthFlowsObject);
-    return oAuthFlowsObject;
-  }
-
-  public static OAuthFlowObject OAuthFlowObject.parseOAuthFlow(OAuthFlow oAuthFlow, Map<Object, ASTNode> map){
-    OAuthFlowObject oAuthFlowObject = new OAuthFlowObject();
-
-    if (oAuthFlow.getAuthorizationUrl() != null)
-      oAuthFlowObject.setAuthorizationUrl(oAuthFlow.getAuthorizationUrl());
-    if (oAuthFlow.getTokenUrl() != null)
-      oAuthFlowObject.setTokenUrl(oAuthFlow.getTokenUrl());
-    for (String key : oAuthFlow.getScopes().keySet())
-      oAuthFlowObject.addScopesTuple(new ScopesTuple(key, oAuthFlow.getScope(key)));
-    if (oAuthFlow.getRefreshUrl() != null)
-      oAuthFlowObject.setRefreshUrl(oAuthFlow.getRefreshUrl());
-    if (oAuthFlow.getExtensions() != null) {
-      for (String key : oAuthFlow.getExtensions().keySet())
-        oAuthFlowObject.addExtension(new Extension(key, oAuthFlow.getExtensions().get(key)));
-    }
+        return securitySchemeObject;
+        }
 
-    map.put(oAuthFlow, oAuthFlowObject);
-    return oAuthFlowObject;
-  }
+public static OAuthFlowsObject OAuthFlowsObject.parseOAuthFlows(OAuthFlows oAuthFlows){
+        OAuthFlowsObject oAuthFlowsObject = new OAuthFlowsObject();
+        Implicit implicit = new Implicit();
+        Password password = new Password();
+        ClientCredentials clientCredentials = new ClientCredentials();
+        AuthorizationCode authorizationCode = new AuthorizationCode();
 
-  public static SecurityRequirementObject SecurityRequirementObject.parseSecurityRequirement(SecurityRequirement securityRequirement, Map<Object, ASTNode> map){
-    SecurityRequirementObject securityRequirementObject = new SecurityRequirementObject();
+        if (oAuthFlows.getImplicit() != null) {
+        implicit.setO(OAuthFlowObject.parseOAuthFlow(oAuthFlows.getImplicit()));
+        oAuthFlowsObject.setI(implicit);
+        }
+        if (oAuthFlows.getPassword() != null) {
+        password.setO(OAuthFlowObject.parseOAuthFlow(oAuthFlows.getPassword()));
+        oAuthFlowsObject.setP(password);
+        }
+        if (oAuthFlows.getClientCredentials() != null) {
+        clientCredentials.setO(OAuthFlowObject.parseOAuthFlow(oAuthFlows.getClientCredentials()));
+        oAuthFlowsObject.setC(clientCredentials);
+        }
+        if (oAuthFlows.getAuthorizationCode() != null) {
+        authorizationCode.setO(OAuthFlowObject.parseOAuthFlow(oAuthFlows.getAuthorizationCode()));
+        oAuthFlowsObject.setA(authorizationCode);
+        }
+        if (oAuthFlows.getExtensions() != null) {
+        for (String key : oAuthFlows.getExtensions().keySet())
+        oAuthFlowsObject.addEx(new Extension(key, oAuthFlows.getExtensions().get(key)));
+        }
+
+        return oAuthFlowsObject;
+        }
+
+public static OAuthFlowObject OAuthFlowObject.parseOAuthFlow(OAuthFlow oAuthFlow){
+        OAuthFlowObject oAuthFlowObject = new OAuthFlowObject();
+
+        if (oAuthFlow.getAuthorizationUrl() != null)
+        oAuthFlowObject.setAuthorizationUrl(oAuthFlow.getAuthorizationUrl());
+        if (oAuthFlow.getTokenUrl() != null)
+        oAuthFlowObject.setTokenUrl(oAuthFlow.getTokenUrl());
+        for (String key : oAuthFlow.getScopes().keySet())
+        oAuthFlowObject.addS(new ScopesTuple(key, oAuthFlow.getScopes().get(key)));
+        if (oAuthFlow.getRefreshUrl() != null)
+        oAuthFlowObject.setRefreshUrl(oAuthFlow.getRefreshUrl());
+        if (oAuthFlow.getExtensions() != null) {
+        for (String key : oAuthFlow.getExtensions().keySet())
+        oAuthFlowObject.addEx(new Extension(key, oAuthFlow.getExtensions().get(key)));
+        }
+
+        return oAuthFlowObject;
+        }
+
+public static SecurityRequirementObject SecurityRequirementObject.parseSecurityRequirement(io.swagger.v3.oas.models.security.SecurityRequirement securityRequirement){
+        SecurityRequirementObject securityRequirementObject = new SecurityRequirementObject();
 
-    if (securityRequirement.getRequirements() != null) {
-      for (String key : securityRequirement.getRequirements().keySet()) {
+        if (securityRequirement != null) {
+        for (String key : securityRequirement.keySet()) {
         JastAddList<SecurityRequirementValue> values = new JastAddList<>();
-        for (String v : securityRequirement.getRequirement(key))
-          values.add(new SecurityRequirementValue(v));
-        securityRequirementObject.addSecurityRequirementTuple(new SecurityRequirementTuple(key, values));
-      }
-    }
+        for (String v : securityRequirement.get(key))
+        values.add(new SecurityRequirementValue(v));
+        securityRequirementObject.addTuple(new SecurityRequirementTuple(key, values));
+        }
+        }
 
-    map.put(securityRequirement, securityRequirementObject);
-    return securityRequirementObject;
-  }
-}
\ No newline at end of file
+        return securityRequirementObject;
+        }
+        }
diff --git a/src/main/jastadd/RandomRequestGenerator.jrag b/src/main/jastadd/RandomRequestGenerator.jrag
index 277e9afaa4b02be452ede1ddd7852222f95a7033..9473e1b2ddebe0d99248072317b825be0899366a 100644
--- a/src/main/jastadd/RandomRequestGenerator.jrag
+++ b/src/main/jastadd/RandomRequestGenerator.jrag
@@ -1,3 +1,4 @@
+/*
 import java.io.BufferedReader;
 import java.io.DataOutputStream;
 import java.io.InputStreamReader;
@@ -191,4 +192,6 @@ aspect RandomRequestGenerator{
       return String.valueOf(rand.nextInt(maximum));
     return String.valueOf(rand.nextInt());
   }
-}
\ No newline at end of file
+}
+
+ */
\ No newline at end of file
diff --git a/src/main/jastadd/Reference.jrag b/src/main/jastadd/Reference.jrag
index e37c6183b242877916c14131791d7e5da8972fea..98e783d02bb09789761a898ca3e40b02638c7e3f 100644
--- a/src/main/jastadd/Reference.jrag
+++ b/src/main/jastadd/Reference.jrag
@@ -1,5 +1,42 @@
+/*
+import java.util.*;
 aspect Reference {
 
+        inh OpenAPIObject ASTNode.root();
+        eq OpenAPIObject.getChild().root() = this;
+
+        coll List<SchemaTuple> OpenAPIObject.schemaTuples() [new ArrayList<>()] root OpenAPIObject;
+        SchemaTuple contributes this
+        to OpenAPIObject.schemaTuples();
+
+        coll List<ResponseTuple> OpenAPIObject.responseTuples() [new ArrayList<>()] root OpenAPIObject;
+        ResponseTuple contributes this
+        to OpenAPIObject.responseTuples();
+
+        coll List<ParameterTuple> OpenAPIObject.parameterTuples() [new ArrayList<>()] root OpenAPIObject;
+        ParameterTuple contributes this
+        to OpenAPIObject.parameterTuples();
+
+        coll List<RequestBodyTuple> OpenAPIObject.requestBodyTuples() [new ArrayList<>()] root OpenAPIObject;
+        RequestBodyTuple contributes this
+        to OpenAPIObject.requestBodyTuples();
+
+        coll List<HeaderTuple> OpenAPIObject.headerTuples() [new ArrayList<>()] root OpenAPIObject;
+        HeaderTuple contributes this
+        to OpenAPIObject.headerTuples();
+
+        coll List<SecuritySchemeTuple> OpenAPIObject.securitySchemeTuples() [new ArrayList<>()] root OpenAPIObject;
+        SecuritySchemeTuple contributes this
+        to OpenAPIObject.securitySchemeTuples();
+
+        coll List<LinkTuple> OpenAPIObject.linkTuples() [new ArrayList<>()] root OpenAPIObject;
+        LinkTuple contributes this
+        to OpenAPIObject.linkTuples();
+
+        coll List<CallbackTuple> OpenAPIObject.callbackTuples() [new ArrayList<>()] root OpenAPIObject;
+        CallbackTuple contributes this
+        to OpenAPIObject.callbackTuples();
+
   syn ParameterObject ParameterOb.parameterObject();
   eq ParameterObject.parameterObject() = this;
   eq ParameterReference.parameterObject() {
@@ -80,4 +117,5 @@ aspect Reference {
     return new SecuritySchemeObject();
   }
 
-}
\ No newline at end of file
+}
+*/
\ No newline at end of file
diff --git a/src/main/jastadd/ReverseParser.jrag b/src/main/jastadd/ReverseParser.jrag
new file mode 100644
index 0000000000000000000000000000000000000000..7fe54bf1ca070507154210d720e2dd83f593c79a
--- /dev/null
+++ b/src/main/jastadd/ReverseParser.jrag
@@ -0,0 +1,1035 @@
+import java.math.BigDecimal;
+import java.util.*;
+aspect ReverseParser{
+
+    public static OpenAPI OpenAPIObject.reverseOpenAPI(OpenAPIObject openapi){
+        OpenAPI api = new OpenAPI();
+
+        if (!openapi.getOpenAPI().isEmpty())
+            api.setOpenapi(openapi.getOpenAPI());
+        if (openapi.getI() != null)
+            api.setInfo(InfoObject.reverseInfo(openapi.getI()));
+        if (openapi.getNumServ() != 0) {
+            List<Server> servers = new ArrayList<>();
+            for (ServerObject s : openapi.getServList())
+                servers.add(ServerObject.reverseServer(s));
+            api.setServers(servers);
+        }
+            Paths paths = new Paths();
+            for (PathsObject p : openapi.getPList()) {
+                if (p.getP() instanceof PathItemObject)
+                    paths.addPathItem(p.getRef(), p.getP().reversePath(p.getP()));
+                if (p.getNumEx() != 0) {
+                    for (Extension e : p.getExList())
+                        paths.addExtension(e.getKey(), e.getValue());
+                }
+            }
+            api.setPaths(paths);
+        if (openapi.getC() != null)
+            api.setComponents(ComponentsObject.reverseComponents(openapi.getC()));
+        if (openapi.getNumSr() != 0) {
+            List<io.swagger.v3.oas.models.security.SecurityRequirement> securityRequirements = new ArrayList<>();
+            for (SecurityRequirementObject s : openapi.getSrList())
+                securityRequirements.add(SecurityRequirementObject.reverseSecurityRequirement(s));
+            api.setSecurity(securityRequirements);
+        }
+        if (openapi.getNumT() != 0) {
+            List<io.swagger.v3.oas.models.tags.Tag> tags = new ArrayList<>();
+            for (TagObject t : openapi.getTList())
+                tags.add(TagObject.reverseTag(t));
+            api.setTags(tags);
+        }
+        if (openapi.hasE())
+            api.setExternalDocs(ExternalDocObject.reverseExternalDocs(openapi.getE()));
+        if (openapi.getNumEx() != 0) {
+            Map<String, Object> extensionMap = new HashMap<>();
+            for (Extension e : openapi.getExList())
+                extensionMap.put(e.getKey(), e.getValue());
+            api.setExtensions(extensionMap);
+        }
+
+        /* 3.1.0 features
+    if (openapi.getWebhook != null) ...
+    if (openapi.getJsonSchemaDialect != null) ...
+     */
+        return api;
+    }
+
+    public static io.swagger.v3.oas.models.info.Info InfoObject.reverseInfo(InfoObject infoObject){
+        io.swagger.v3.oas.models.info.Info info = new io.swagger.v3.oas.models.info.Info();
+
+        if (infoObject.getTitle() != null)
+            info.setTitle(infoObject.getTitle());
+        if (!infoObject.getVersion().isEmpty())
+            info.setVersion(infoObject.getVersion());
+        if (!infoObject.getDescription().isEmpty())
+            info.setDescription(infoObject.getDescription());
+        if (!infoObject.getTermsOfService().isEmpty())
+            info.setTermsOfService(infoObject.getTermsOfService());
+        if (infoObject.hasC())
+            info.setContact(ContactObject.reverseContact(infoObject.getC()));
+        if (infoObject.hasL())
+            info.setLicense(LicenseObject.reverseLicense(infoObject.getL()));
+        if (infoObject.getNumEx() != 0) {
+            Map<String, Object> extension = new HashMap<>();
+            for (Extension e : infoObject.getExList())
+                extension.put(e.getKey(), e.getValue());
+            info.setExtensions(extension);
+        }
+
+        return info;
+    }
+
+    public static io.swagger.v3.oas.models.info.Contact ContactObject.reverseContact(ContactObject contactObject){
+        io.swagger.v3.oas.models.info.Contact contact = new io.swagger.v3.oas.models.info.Contact();
+
+        if (!contactObject.getName().isEmpty())
+            contact.setName(contactObject.getName());
+        if (!contactObject.getUrl().isEmpty())
+            contact.setUrl(contactObject.getUrl());
+        if (!contactObject.getEmail().isEmpty())
+            contact.setEmail(contactObject.getEmail());
+        if (contactObject.getNumEx() != 0) {
+            Map<String, Object> extensions = new HashMap<>();
+            for (Extension e : contactObject.getExList())
+                extensions.put(e.getKey(), e.getValue());
+            contact.setExtensions(extensions);
+        }
+
+        return contact;
+    }
+
+    public static io.swagger.v3.oas.models.info.License LicenseObject.reverseLicense(LicenseObject licenseObject){
+        io.swagger.v3.oas.models.info.License license = new io.swagger.v3.oas.models.info.License();
+
+        if (!licenseObject.getName().isEmpty())
+            license.setName(licenseObject.getName());
+        if (!licenseObject.getUrl().isEmpty())
+            license.setUrl(licenseObject.getUrl());
+        if (licenseObject.getNumEx() != 0) {
+            Map<String, Object> extensions = new HashMap<>();
+            for (Extension e : licenseObject.getExList())
+                extensions.put(e.getKey(), e.getValue());
+            license.setExtensions(extensions);
+        }
+
+        return license;
+    }
+
+    public static Server ServerObject.reverseServer(ServerObject serverObject){
+        Server server = new Server();
+
+        if (!serverObject.getUrl().isEmpty())
+            server.setUrl(serverObject.getUrl());
+        if (!serverObject.getDescription().isEmpty())
+            server.setDescription(serverObject.getDescription());
+        if (serverObject.getNumSt() != 0) {
+            ServerVariables serverVariables = new ServerVariables();
+            for (ServerVariablesTuple s : serverObject.getStList())
+                serverVariables.addServerVariable(s.getName(), ServerVariableObject.reverseServerVariable(s.getS()));
+            server.setVariables(serverVariables);
+        }
+        if (serverObject.getNumEx() != 0) {
+            Map<String, Object> extensions = new HashMap<>();
+            for (Extension e : serverObject.getExList())
+                extensions.put(e.getKey(), e.getValue());
+            server.setExtensions(extensions);
+        }
+
+        return server;
+    }
+
+    public static ServerVariable ServerVariableObject.reverseServerVariable(ServerVariableObject serverVariableObject){
+        ServerVariable serverVariable = new ServerVariable();
+
+        if (!serverVariableObject.getDefault().isEmpty())
+            serverVariable.setDefault(serverVariableObject.getDefault());
+        if (!serverVariableObject.getDescription().isEmpty())
+            serverVariable.setDescription(serverVariableObject.getDescription());
+        if (serverVariableObject.getNumE() != 0) {
+            List<String> enums = new ArrayList<>();
+            for (Enum e : serverVariableObject.getEList())
+                enums.add(e.getEnumValue());
+            serverVariable.setEnum(enums);
+        }
+        if (serverVariableObject.getNumEx() != 0) {
+            Map<String, Object> extensions = new HashMap<>();
+            for (Extension e : serverVariableObject.getExList())
+                extensions.put(e.getKey(), e.getValue());
+            serverVariable.setExtensions(extensions);
+        }
+
+        return serverVariable;
+    }
+
+    public static Components ComponentsObject.reverseComponents(ComponentsObject componentsObject){
+        Components components = new Components();
+
+        if (componentsObject.getNumS() != 0) {
+            Map<String, io.swagger.v3.oas.models.media.Schema> schemaMap = new HashMap<>();
+            SchemaOb s;
+            for (SchemaTuple t : componentsObject.getSList())
+                schemaMap.put(t.getKey(), t.getO().reverseSchema(t.getO()));
+            components.setSchemas(schemaMap);
+        }
+        if (componentsObject.getNumR() != 0) {
+            Map<String, ApiResponse> responseMap = new HashMap<>();
+            ResponseOb r;
+            for (ResponseTuple t : componentsObject.getRList()) {
+                r = t.getO();
+                responseMap.put(t.getKey(), r.reverseResponse(r));
+            }
+            components.setResponses(responseMap);
+        }
+        if (componentsObject.getNumP() != 0) {
+            Map<String, Parameter> parameterMap = new HashMap<>();
+            ParameterOb p;
+            for (ParameterTuple t : componentsObject.getPList()) {
+                p = t.getO();
+                parameterMap.put(t.getKey(), p.reverseParameter(p));
+            }
+            components.setParameters(parameterMap);
+        }
+        if (componentsObject.getNumE() != 0) {
+            Map<String, Example> exampleMap = new HashMap<>();
+            for (ExampleTuple t : componentsObject.getEList())
+                exampleMap.put(t.getKey(), t.getO().reverseExample(t.getO()));
+            components.setExamples(exampleMap);
+        }
+        if (componentsObject.getNumRb() != 0) {
+            Map<String, RequestBody> requestBodyMap = new HashMap<>();
+            RequestBodyOb r;
+            for (RequestBodyTuple t : componentsObject.getRbList()) {
+                r = t.getO();
+                requestBodyMap.put(t.getKey(), r.reverseRequestBody(r));
+            }
+            components.setRequestBodies(requestBodyMap);
+        }
+        if (componentsObject.getNumH() != 0) {
+            Map<String, Header> headerMap = new HashMap<>();
+            HeaderOb h;
+            for (HeaderTuple t : componentsObject.getHList()) {
+                h = t.getO();
+                headerMap.put(t.getKey(), h.reverseHeader(h));
+            }
+            components.setHeaders(headerMap);
+        }
+        if (componentsObject.getNumSc() != 0) {
+            Map<String, SecurityScheme> securitySchemeMap = new HashMap<>();
+            SecuritySchemeOb s;
+            for (SecuritySchemeTuple t : componentsObject.getScList()) {
+                s = t.getO();
+                securitySchemeMap.put(t.getKey(), s.reverseSecurityScheme(s));
+            }
+            components.setSecuritySchemes(securitySchemeMap);
+        }
+        if (componentsObject.getNumL() != 0) {
+            Map<String, Link> linkMap = new HashMap<>();
+            LinkOb l;
+            for (LinkTuple t : componentsObject.getLList()) {
+                l = t.getO();
+                linkMap.put(t.getKey(), l.reverseLink(l));
+            }
+            components.setLinks(linkMap);
+        }
+        if (componentsObject.getNumC() != 0) {
+            Map<String, Callback> callbackMap = new HashMap<>();
+            CallbackOb c;
+            for (CallbackTuple t : componentsObject.getCList()) {
+                c = t.getO();
+                callbackMap.put(t.getKey(), c.reverseCallback(c));
+            }
+            components.setCallbacks(callbackMap);
+        }
+        if (componentsObject.getNumEx() != 0) {
+            Map<String, Object> extensions = new HashMap<>();
+            for (Extension e : componentsObject.getExList())
+                extensions.put(e.getKey(), e.getValue());
+            components.setExtensions(extensions);
+        }
+
+        return components;
+    }
+
+    syn PathItem PathItemOb.reversePath(PathItemOb pathItemOb);
+    eq PathItemReference.reversePath(PathItemOb pathItemOb){
+        PathItem pathItem = new PathItem();
+        PathItemReference p = (PathItemReference) pathItemOb;
+
+        /* implement after reference implementation
+        if (!p.getRef().isEmpty()) {
+        try {
+        parameter.setReference(new org.openapi4j.core.model.v3.OAI3Context(new URL("")), new URL(""), p.getRef());
+        } catch (Exception e) {
+        e.printStackTrace();
+        }
+        }
+         */
+
+        return pathItem;
+    }
+    eq PathItemObject.reversePath(PathItemOb pathItemOb){
+        PathItem path = new PathItem();
+        PathItemObject p = (PathItemObject) pathItemOb;
+
+        if (!p.getSummary().isEmpty())
+            path.setSummary(p.getSummary());
+        if (!p.getDescription().isEmpty())
+            path.setDescription(p.getDescription());
+        if (p.hasG())
+            path.setGet(OperationObject.reverseOperation(p.getG().getO()));
+        if (p.hasPutOb())
+            path.setPut(OperationObject.reverseOperation(p.getPutOb().getO()));
+        if (p.hasPostOb())
+            path.setPost(OperationObject.reverseOperation(p.getPostOb().getO()));
+        if (p.hasD())
+            path.setDelete(OperationObject.reverseOperation(p.getD().getO()));
+        if (p.hasO())
+            path.setOptions(OperationObject.reverseOperation(p.getO().getO()));
+        if (p.hasH())
+            path.setHead(OperationObject.reverseOperation(p.getH().getO()));
+        if (p.hasPatchOb())
+            path.setPatch(OperationObject.reverseOperation(p.getPatchOb().getO()));
+        if (p.getNumS() != 0) {
+            for (ServerObject s : p.getSList())
+                path.addServersItem(ServerObject.reverseServer(s));
+        }
+        if (p.getNumPo() != 0) {
+            for (ParameterOb e : p.getPoList())
+                path.addParametersItem(e.reverseParameter(e));
+        }
+        if (p.getNumEx() != 0) {
+            Map<String, Object> extensionMap = new HashMap<>();
+            for (Extension e : p.getExList())
+                extensionMap.put(e.getKey(), e.getValue());
+            path.setExtensions(extensionMap);
+        }
+
+        return path;
+    }
+
+    public static io.swagger.v3.oas.models.Operation OperationObject.reverseOperation(OperationObject operationObject){
+        io.swagger.v3.oas.models.Operation operation = new io.swagger.v3.oas.models.Operation();
+
+        if (operationObject.getNumT() != 0) {
+            for (de.tudresden.inf.st.openapi.ast.Tag t : operationObject.getTList())
+                operation.addTagsItem(t.getTag());
+        }
+        if (!operationObject.getSummary().isEmpty())
+            operation.setSummary(operationObject.getSummary());
+        if (!operationObject.getDescription().isEmpty())
+            operation.setDescription(operationObject.getDescription());
+        if (operationObject.hasEd())
+            operation.setExternalDocs(ExternalDocObject.reverseExternalDocs(operationObject.getEd()));
+        if (!operationObject.getOperationID().isEmpty())
+            operation.setOperationId(operationObject.getOperationID());
+        if (operationObject.getNumP() != 0) {
+            for (ParameterOb p : operationObject.getPList())
+                operation.addParametersItem(p.reverseParameter(p));
+        }
+        if (operationObject.hasRb())
+            operation.setRequestBody(operationObject.getRb().reverseRequestBody(operationObject.getRb()));
+        if (operationObject.getR().getNumR() != 0) {
+            ApiResponses responses = new ApiResponses();
+            for (ResponseTuple t : operationObject.getR().getRList())
+                responses.put(t.getKey(), t.getO().reverseResponse(t.getO()));
+            operation.setResponses(responses);
+        }
+        if (operationObject.getNumC() != 0) {
+            Map<String, Callback> callbacks = new HashMap<>();
+            for (CallbackTuple t : operationObject.getCList())
+                callbacks.put(t.getKey(), t.getO().reverseCallback(t.getO()));
+            operation.setCallbacks(callbacks);
+        }
+        if (operationObject.getDeprecatedBoolean() != null)
+            operation.setDeprecated(operationObject.getDeprecatedBoolean());
+        if (operationObject.getNumSr() != 0) {
+            for (SecurityRequirementObject s : operationObject.getSrList())
+                operation.addSecurityItem(SecurityRequirementObject.reverseSecurityRequirement(s));
+        }
+        if (operationObject.getNumS() != 0) {
+            for (ServerObject s : operationObject.getSList())
+                operation.addServersItem(ServerObject.reverseServer(s));
+        }
+        if (operationObject.getNumEx() != 0) {
+            Map<String, Object> extensionMap = new HashMap<>();
+            for (Extension e : operationObject.getExList())
+                extensionMap.put(e.getKey(), e.getValue());
+            operation.setExtensions(extensionMap);
+        }
+
+        return operation;
+    }
+
+    public static io.swagger.v3.oas.models.ExternalDocumentation ExternalDocObject.reverseExternalDocs(ExternalDocObject externalDocObject){
+        ExternalDocumentation externalDocs = new ExternalDocumentation();
+
+        if (!externalDocObject.getDescription().isEmpty())
+            externalDocs.setDescription(externalDocObject.getDescription());
+        if (!externalDocObject.getUrl().isEmpty())
+            externalDocs.setUrl(externalDocObject.getUrl());
+        if (externalDocObject.getNumEx() != 0) {
+            Map<String, Object> extensionMap = new HashMap<>();
+            for (Extension e : externalDocObject.getExList())
+                extensionMap.put(e.getKey(), e.getValue());
+            externalDocs.setExtensions(extensionMap);
+        }
+
+        return externalDocs;
+    }
+
+    syn io.swagger.v3.oas.models.parameters.Parameter ParameterOb.reverseParameter(ParameterOb parameterOb);
+    eq ParameterReference.reverseParameter(ParameterOb parameterOb){
+        io.swagger.v3.oas.models.parameters.Parameter parameter = new io.swagger.v3.oas.models.parameters.Parameter();
+        ParameterReference p = (ParameterReference) parameterOb;
+
+        if (!p.getRef().isEmpty()) {
+            parameter.set$ref(p.getRef());
+        }
+
+        return parameter;
+    }
+    eq ParameterObject.reverseParameter(ParameterOb parameterOb){
+        io.swagger.v3.oas.models.parameters.Parameter parameter = new io.swagger.v3.oas.models.parameters.Parameter();
+        ParameterObject p = (ParameterObject) parameterOb;
+
+        if (p.getName() != null)
+            parameter.setName(p.getName());
+        if (p.getIn() != null)
+            parameter.setIn(p.getIn());
+        if (p.getRequired() != null)
+            parameter.setRequired(p.getRequired());
+        if (!p.getDescription().isEmpty())
+            parameter.setDescription(p.getDescription());
+        if (p.getDeprecatedBoolean() != null)
+            parameter.setDeprecated(p.getDeprecatedBoolean());
+        switch (p.getStyle()) {
+            case "matrix":
+                parameter.setStyle(Parameter.StyleEnum.MATRIX);
+                break;
+            case "label":
+                parameter.setStyle(Parameter.StyleEnum.LABEL);
+                break;
+            case "form":
+                parameter.setStyle(Parameter.StyleEnum.FORM);
+                break;
+            case "simple":
+                parameter.setStyle(Parameter.StyleEnum.SIMPLE);
+                break;
+            case "spaceDelimited":
+                parameter.setStyle(Parameter.StyleEnum.SPACEDELIMITED);
+                break;
+            case "pipeDelimited":
+                parameter.setStyle(Parameter.StyleEnum.PIPEDELIMITED);
+                break;
+            case "deepObject":
+                parameter.setStyle(Parameter.StyleEnum.DEEPOBJECT);
+                break;
+        }
+        if (p.getAllowReserved() != null)
+            parameter.setAllowReserved(p.getAllowReserved());
+        if (p.getAllowEmptyValue() != null)
+            parameter.setAllowEmptyValue(p.getAllowEmptyValue());
+        if (p.getExplode() != null)
+            parameter.setExplode(p.getExplode());
+        if (p.getSchema() != null)
+            parameter.setSchema(p.getSchema().reverseSchema(p.getSchema()));
+        if (p.getExample() != null)
+            parameter.setExample(p.getExample());
+        if (p.getNumE() != 0) {
+            Map<String, Example> exampleMap = new HashMap<>();
+            for (ExampleTuple t : p.getEList())
+                exampleMap.put(t.getKey(), t.getO().reverseExample(t.getO()));
+            parameter.setExamples(exampleMap);
+        }
+        if (p.getNumC() != 0) {
+            io.swagger.v3.oas.models.media.Content content = new Content();
+            for (ContentTuple t : p.getCList())
+                content.put(t.getKey(), MediaTypeObject.reverseMediaType(t.getM()));
+            parameter.setContent(content);
+        }
+        if (p.getRequired() != null)
+            parameter.setRequired(p.getRequired());
+        if (p.getNumEx() != 0) {
+            Map<String, Object> extensionMap = new HashMap<>();
+            for (Extension e : p.getExList())
+                extensionMap.put(e.getKey(), e.getValue());
+            parameter.setExtensions(extensionMap);
+        }
+
+        return parameter;
+    }
+
+    syn RequestBody RequestBodyOb.reverseRequestBody(RequestBodyOb requestBodyOb);
+    eq RequestBodyReference.reverseRequestBody(RequestBodyOb requestBodyOb){
+        RequestBody requestBody = new RequestBody();
+        RequestBodyReference r = (RequestBodyReference) requestBodyOb;
+
+        if (!r.getRef().isEmpty()) {
+            requestBody.set$ref(r.getRef());
+        }
+
+        return requestBody;
+    }
+    eq RequestBodyObject.reverseRequestBody(RequestBodyOb requestBodyOb){
+        RequestBody requestBody = new RequestBody();
+        RequestBodyObject r = (RequestBodyObject) requestBodyOb;
+
+        io.swagger.v3.oas.models.media.Content contents = new Content();
+        for (ContentTuple t : r.getCList())
+            contents.put(t.getKey(), MediaTypeObject.reverseMediaType(t.getM()));
+        requestBody.setContent(contents);
+        if (!r.getDescription().isEmpty())
+            requestBody.setDescription(r.getDescription());
+        if (r.getRequired() != null)
+            requestBody.setRequired(r.getRequired());
+        if (r.getNumEx() != 0){
+            for ( Extension e : r.getExList() )
+                requestBody.addExtension(e.getKey(), e.getValue());
+        }
+
+        return requestBody;
+    }
+
+    public static io.swagger.v3.oas.models.media.MediaType MediaTypeObject.reverseMediaType(MediaTypeObject mediaTypeObject){
+        MediaType mediaType = new MediaType();
+        SchemaOb s;
+
+        if (mediaTypeObject.getS() != null) {
+            s = mediaTypeObject.getS();
+            mediaType.setSchema(s.reverseSchema(s));
+        }
+        if (mediaTypeObject.getExample() != null)
+            mediaType.setExample(mediaTypeObject.getExample());
+        if (mediaTypeObject.getNumE() != 0) {
+            Map<String, Example> exampleMap = new HashMap<>();
+            for (ExampleTuple t : mediaTypeObject.getEList())
+                exampleMap.put(t.getKey(), t.getO().reverseExample(t.getO()));
+            mediaType.setExamples(exampleMap);
+        }
+        if (mediaTypeObject.getNumEn() != 0) {
+            Map<String, io.swagger.v3.oas.models.media.Encoding> encodingMap = new HashMap<>();
+            for (EncodingTuple t : mediaTypeObject.getEnList())
+                encodingMap.put(t.getKey(), EncodingObject.reverseEncoding(t.getE()));
+            mediaType.setEncoding(encodingMap);
+        }
+
+        return mediaType;
+    }
+
+    public static io.swagger.v3.oas.models.media.Encoding EncodingObject.reverseEncoding(EncodingObject encodingObject){
+        io.swagger.v3.oas.models.media.Encoding encodingProperty = new io.swagger.v3.oas.models.media.Encoding();
+        HeaderOb h;
+
+        if (!encodingObject.getContentType().isEmpty())
+            encodingProperty.setContentType(encodingObject.getContentType());
+        if (encodingObject.getNumH() != 0) {
+            Map<String, Header> headers = new HashMap<>();
+            for (HeaderTuple t : encodingObject.getHList()) {
+                h = t.getO();
+                headers.put(t.getKey(), h.reverseHeader(h));
+            }
+            encodingProperty.setHeaders(headers);
+        }
+        switch (encodingObject.getStyle()) {
+            case ("form") :
+                encodingProperty.setStyle(Encoding.StyleEnum.FORM);
+                break;
+            case ("spaceDelimited") :
+                encodingProperty.setStyle(Encoding.StyleEnum.SPACE_DELIMITED);
+                break;
+            case ("pipeDelimited") :
+                encodingProperty.setStyle(Encoding.StyleEnum.PIPE_DELIMITED);
+                break;
+            case ("deepObject") :
+                encodingProperty.setStyle(Encoding.StyleEnum.DEEP_OBJECT);
+                break;
+        }
+        if (encodingObject.getExplode() != null)
+            encodingProperty.setExplode(encodingObject.getExplode());
+        if (encodingObject.getNumEx() != 0) {
+            Map<String, Object> extensionMap = new HashMap<>();
+            for (Extension e : encodingObject.getExList())
+                extensionMap.put(e.getKey(), e.getValue());
+            encodingProperty.setExtensions(extensionMap);
+        }
+
+        return encodingProperty;
+    }
+
+    syn ApiResponse ResponseOb.reverseResponse(ResponseOb responseOb);
+    eq ResponseReference.reverseResponse(ResponseOb responseOb){
+        ApiResponse response = new ApiResponse();
+        ResponseReference r = (ResponseReference) responseOb;
+
+        if (!r.getRef().isEmpty()) {
+            response.set$ref(r.getRef());
+        }
+
+        return response;
+    }
+    eq ResponseObject.reverseResponse(ResponseOb responseOb){
+        ApiResponse response = new ApiResponse();
+        ResponseObject r = (ResponseObject) responseOb;
+
+        if (r.getDescription() != null)
+            response.setDescription(r.getDescription());
+        if (r.getNumH() != 0) {
+            Map<String, Header> headers = new HashMap<>();
+            for (HeaderTuple t : r.getHList())
+                headers.put(t.getKey(), t.getO().reverseHeader(t.getO()));
+            response.setHeaders(headers);
+        }
+        if (r.getNumC() != 0) {
+            io.swagger.v3.oas.models.media.Content contents = new io.swagger.v3.oas.models.media.Content();
+            for (ContentTuple t : r.getCList())
+                contents.put(t.getKey(), MediaTypeObject.reverseMediaType(t.getM()));
+            response.setContent(contents);
+        }
+        if (r.getNumL() != 0) {
+            Map<String, Link> links = new HashMap<>();
+            for (LinkTuple t : r.getLList())
+                links.put(t.getKey(), t.getO().reverseLink(t.getO()));
+            response.setLinks(links);
+        }
+        if (r.getNumEx() != 0) {
+            Map<String, Object> extensions = new HashMap<>();
+            for (Extension e : r.getExList())
+                extensions.put(e.getKey(), e.getValue());
+            response.setExtensions(extensions);
+        }
+
+        return response;
+    }
+
+    syn io.swagger.v3.oas.models.callbacks.Callback CallbackOb.reverseCallback(CallbackOb callbackOb);
+    eq CallbackReference.reverseCallback(CallbackOb callbackOb){
+        io.swagger.v3.oas.models.callbacks.Callback callback = new io.swagger.v3.oas.models.callbacks.Callback();
+        CallbackReference c = (CallbackReference) callbackOb;
+
+        if (!c.getRef().isEmpty()) {
+            callback.set$ref(c.getRef());
+        }
+
+        return callback;
+    }
+    eq CallbackObject.reverseCallback(CallbackOb callbackOb){
+        io.swagger.v3.oas.models.callbacks.Callback callback = new io.swagger.v3.oas.models.callbacks.Callback();
+        CallbackObject c = (CallbackObject) callbackOb;
+
+        if (c.getNumE() != 0) {
+            Map<String, Path> paths = new HashMap<>();
+            PathItemOb p;
+            for (Expression e : c.getEList())
+                callback.addPathItem(e.getName(), e.getP().reversePath(e.getP()));
+        }
+
+        return callback;
+    }
+
+            syn Example ExampleOb.reverseExample(ExampleOb exampleOb);
+eq ExampleReference.reverseExample(ExampleOb exampleOb){
+        Example example = new Example();
+        ExampleReference e = (ExampleReference) exampleOb;
+
+        if(!e.getRef().isEmpty())
+            example.set$ref(e.getRef());
+
+            return example;
+}
+        eq ExampleObject.reverseExample(ExampleOb exampleOb){
+            Example example = new Example();
+            ExampleObject exampleObject = (ExampleObject) exampleOb;
+
+            if (!exampleObject.getSummary().isEmpty())
+                example.setSummary(exampleObject.getSummary());
+            if (!exampleObject.getDescription().isEmpty())
+                example.setDescription(exampleObject.getDescription());
+            if (exampleObject.getValue() != null)
+                example.setValue(exampleObject.getValue());
+            if (!exampleObject.getExternalValue().isEmpty())
+                example.setExternalValue(exampleObject.getExternalValue());
+            if (exampleObject.getNumEx() != 0) {
+                Map<String, Object> extension = new HashMap<>();
+                for (Extension e : exampleObject.getExList())
+                    extension.put(e.getKey(), e.getValue());
+                example.setExtensions(extension);
+            }
+
+            return example;
+        }
+
+    syn io.swagger.v3.oas.models.links.Link LinkOb.reverseLink(LinkOb linkOb);
+    eq LinkReference.reverseLink(LinkOb linkOb){
+        io.swagger.v3.oas.models.links.Link link = new io.swagger.v3.oas.models.links.Link();
+        LinkReference l = (LinkReference) linkOb;
+
+        if (!l.getRef().isEmpty())
+            link.set$ref(l.getRef());
+
+        return link;
+    }
+    eq LinkObject.reverseLink(LinkOb linkOb){
+        io.swagger.v3.oas.models.links.Link link = new io.swagger.v3.oas.models.links.Link();
+        LinkObject l = (LinkObject) linkOb;
+
+        if (!l.getOperationRef().isEmpty())
+            link.setOperationRef(l.getOperationRef());
+        if (!l.getOperationID().isEmpty())
+            link.setOperationId(l.getOperationID());
+        if (l.getNumL() != 0) {
+            Map<String, String> parameters = new HashMap<>();
+            for (LinkParameterTuple t : l.getLList())
+                parameters.put(t.getKey(), t.getValue());
+            link.setParameters(parameters);
+        }
+        if (!l.getDescription().isEmpty())
+            link.setDescription(l.getDescription());
+        if (l.hasS())
+            link.setServer(ServerObject.reverseServer(l.getS()));
+        if (l.getNumEx() != 0) {
+            for (Extension e : l.getExList())
+                link.addExtension(e.getKey(), e.getValue());
+        }
+
+        return link;
+    }
+
+    syn io.swagger.v3.oas.models.headers.Header HeaderOb.reverseHeader(HeaderOb headerOb);
+    eq HeaderReference.reverseHeader(HeaderOb headerOb){
+        io.swagger.v3.oas.models.headers.Header header = new io.swagger.v3.oas.models.headers.Header();
+        HeaderReference h = (HeaderReference) headerOb;
+
+        if (!h.getRef().isEmpty()) {
+            header.set$ref(h.getRef());
+        }
+
+        return header;
+    }
+    eq HeaderObject.reverseHeader(HeaderOb headerOb){
+        io.swagger.v3.oas.models.headers.Header header = new io.swagger.v3.oas.models.headers.Header();
+        HeaderObject h = (HeaderObject) headerOb;
+
+        if (h.getRequired() != null)
+            header.setRequired(h.getRequired());
+        if (!h.getDescription().isEmpty())
+            header.setDescription(h.getDescription());
+        switch (h.getStyle()) {
+            case "simple":
+                header.setStyle(Header.StyleEnum.SIMPLE);
+                break;
+        }
+        if (h.getExplode() != null)
+            header.setExplode(h.getExplode());
+        //if (h.getAllowReserved() != null)
+        //  header.setAllowReserved(h.getAllowReserved());
+        if (h.getExample() != null)
+            header.setExample(h.getExample());
+        if (h.getNumE() != 0) {
+            Map<String, Example> examples = new HashMap<>();
+            for (ExampleTuple t : h.getEList())
+                examples.put(t.getKey(), t.getO().reverseExample(t.getO()));
+            header.setExample(examples);
+        }
+        if (h.getNumC() != 0) {
+            io.swagger.v3.oas.models.media.Content contents = new io.swagger.v3.oas.models.media.Content();
+            for (ContentTuple t : h.getCList())
+                contents.put(t.getKey(), MediaTypeObject.reverseMediaType(t.getM()));
+            header.setContent(contents);
+        }
+        if (h.hasS())
+            header.setSchema(h.getS().reverseSchema(h.getS()));
+        if (h.getNumEx() != 0){
+            Map<String, Object> extensions = new HashMap<>();
+            for(Extension e : h.getExList())
+                extensions.put(e.getKey(), e.getValue());
+            header.setExtensions(extensions);
+        }
+
+        return header;
+    }
+
+    public static io.swagger.v3.oas.models.tags.Tag TagObject.reverseTag(TagObject tagObject){
+        io.swagger.v3.oas.models.tags.Tag tag = new io.swagger.v3.oas.models.tags.Tag();
+
+        tag.setName(tagObject.getName());
+
+        if (!tagObject.getDescription().isEmpty())
+            tag.setDescription(tagObject.getDescription());
+        if (tagObject.hasE())
+            tag.setExternalDocs(ExternalDocObject.reverseExternalDocs(tagObject.getE()));
+        if (tagObject.getNumEx() != 0) {
+            Map<String, Object> extensionMap = new HashMap<>();
+            for (Extension e : tagObject.getExList())
+                extensionMap.put(e.getKey(), e.getValue());
+            tag.setExtensions(extensionMap);
+        }
+
+        return tag;
+    }
+
+
+    syn io.swagger.v3.oas.models.media.Schema SchemaOb.reverseSchema(SchemaOb schemaOb);
+    eq SchemaReference.reverseSchema(SchemaOb schemaOb){
+        io.swagger.v3.oas.models.media.Schema schema = new io.swagger.v3.oas.models.media.Schema();
+        SchemaReference s = (SchemaReference) schemaOb;
+
+        if (!s.getRef().isEmpty()) {
+            schema.set$ref(s.getRef());
+        }
+
+        return schema;
+    }
+    eq SchemaObject.reverseSchema(SchemaOb schemaOb){
+        io.swagger.v3.oas.models.media.Schema<Object> schema = new io.swagger.v3.oas.models.media.Schema<>();
+        SchemaObject s = (SchemaObject) schemaOb;
+
+        if (s.hasI()) {
+            schema = new ArraySchema();
+            ((ArraySchema) schema).setItems(s.getI().getSchema().reverseSchema(s.getI().getSchema()));
+        }
+        if (s.getNumAll() != 0 || s.getNumAny() != 0 || s.getNumOne() != 0) {
+            schema = new ComposedSchema();
+            if (s.getNumAll() != 0) {
+                for (AllOfSchema a : s.getAllList())
+                    ((ComposedSchema) schema).addAllOfItem(a.getSchema().reverseSchema(a.getSchema()));
+            }
+            if (s.getNumAny() != 0) {
+                for (AnyOfSchema a : s.getAnyList())
+                    ((ComposedSchema) schema).addAnyOfItem(a.getSchema().reverseSchema(a.getSchema()));
+            }
+            if (s.getNumOne() != 0) {
+                for (OneOfSchema o : s.getOneList())
+                    ((ComposedSchema) schema).addOneOfItem(o.getSchema().reverseSchema(o.getSchema()));
+            }
+        }
+
+        if (s.getAdditionalProperties() != null)
+            schema.setAdditionalProperties(s.getAdditionalProperties());
+        if (s.getDefaultValue() != null)
+            schema.setDefault(s.getDefaultValue());
+        if (!s.getDescription().isEmpty())
+            schema.setDescription(s.getDescription());
+        if (s.getDeprecatedBoolean() != null)
+            schema.setDeprecated(s.getDeprecatedBoolean());
+        if (s.hasD())
+            schema.setDiscriminator(DiscriminatorObject.reverseDiscriminator(s.getD()));
+        if (s.getNumE() != 0) {
+            for (EnumObj e : s.getEList())
+                schema.addEnumItemObject(e.getEnumOb());
+        }
+        // in ver 3.0, only one example is provided. In ver 3.1, optionally multiple
+        if (s.getNumEl()!=0)
+            schema.setExample(s.getEl(0).getExample());
+        if (s.getExclusiveMaximum() != null)
+            schema.setExclusiveMaximum(s.getExclusiveMaximum());
+        if (s.getExclusiveMinimum() != null)
+            schema.setExclusiveMinimum(s.getExclusiveMinimum());
+        if (s.hasExt())
+            schema.setExternalDocs(ExternalDocObject.reverseExternalDocs(s.getExt()));
+        if (!s.getFormat().isEmpty())
+            schema.setFormat(s.getFormat());
+        if (s.getMaximum() != null)
+            schema.setMaximum(s.getMaximum());
+        if (s.getMinimum() != null)
+            schema.setMinimum(s.getMinimum());
+        if (s.getMaxItems() != null)
+            schema.setMaxItems(s.getMaxItems());
+        if (s.getMinItems() != null)
+            schema.setMinItems(s.getMinItems());
+        if (s.getMaxLength() != null)
+            schema.setMaxLength(s.getMaxLength());
+        if (s.getMinLength() != null)
+            schema.setMinLength(s.getMinLength());
+        if (s.getMaxProperties() != null)
+            schema.setMaxProperties(s.getMaxProperties());
+        if (s.getMinProperties() != null)
+            schema.setMinProperties(s.getMinProperties());
+        if (s.getMultipleOf() != null)
+            schema.setMultipleOf(s.getMultipleOf());
+        if (s.hasN())
+            schema.setNot(reverseSchema(s.getN().getSchema()));
+        // Nullable will be excluded in version 3.1.0
+        if (s.getNullable() != null)
+            schema.setNullable(s.getNullable());
+        if (!s.getPattern().isEmpty())
+            schema.setPattern(s.getPattern());
+        if (s.getNumP() != 0) {
+            Map<String, io.swagger.v3.oas.models.media.Schema> properties = new HashMap<>();
+            for (PropertyItem p : s.getPList())
+                properties.put(p.getName(), p.getSchema().reverseSchema(p.getSchema()));
+            schema.setProperties(properties);
+        }
+        if (s.getNumR() != 0) {
+            for (RequiredField r : s.getRList())
+                schema.addRequiredItem(r.getValue());
+        }
+        if (s.getReadOnly() != null)
+            schema.setReadOnly(s.getReadOnly());
+        if (s.getWriteOnly() != null)
+            schema.setWriteOnly(s.getWriteOnly());
+        if (!s.getType().isEmpty())
+            schema.setType(s.getType());
+        if (!s.getTitle().isEmpty())
+            schema.setTitle(s.getTitle());
+        if (s.getUniqueItems() != null)
+            schema.setUniqueItems(s.getUniqueItems());
+        if (s.hasX())
+            schema.setXml(XmlObject.reverseXml(s.getX()));
+        if (s.getNumEx() != 0) {
+            Map<String, Object> extensionMap = new HashMap<>();
+            for (Extension e : s.getExList())
+                extensionMap.put(e.getKey(), e.getValue());
+            schema.setExtensions(extensionMap);
+        }
+
+        return schema;
+    }
+
+    public static io.swagger.v3.oas.models.media.Discriminator DiscriminatorObject.reverseDiscriminator(DiscriminatorObject discriminatorObject){
+        io.swagger.v3.oas.models.media.Discriminator discriminator = new io.swagger.v3.oas.models.media.Discriminator();
+
+        if (!discriminatorObject.getPropertyName().isEmpty())
+            discriminator.setPropertyName(discriminatorObject.getPropertyName());
+        if (discriminatorObject.getNumM() != 0) {
+            Map<String, String> mapping = new HashMap<>();
+            for (MappingTuple m : discriminatorObject.getMList())
+                mapping.put(m.getKey(), m.getValue());
+            discriminator.setMapping(mapping);
+        }
+
+        return discriminator;
+    }
+
+    public static io.swagger.v3.oas.models.media.XML XmlObject.reverseXml(XmlObject xmlObject){
+        io.swagger.v3.oas.models.media.XML xml = new io.swagger.v3.oas.models.media.XML();
+
+        if (!xmlObject.getName().isEmpty())
+            xml.setName(xmlObject.getName());
+        if (!xmlObject.getNamespace().isEmpty())
+            xml.setNamespace(xmlObject.getNamespace());
+        if (!xmlObject.getPrefix().isEmpty())
+            xml.setPrefix(xmlObject.getPrefix());
+        if (xmlObject.getAttribute() != null)
+            xml.setAttribute(xmlObject.getAttribute());
+        if (xmlObject.getWrapped() != null)
+            xml.setWrapped(xmlObject.getWrapped());
+        if (xmlObject.getNumEx() != 0) {
+            for ( Extension e : xmlObject.getExList() )
+                xml.addExtension(e.getKey(), e.getValue());
+        }
+
+        return xml;
+    }
+
+    syn io.swagger.v3.oas.models.security.SecurityScheme SecuritySchemeOb.reverseSecurityScheme(SecuritySchemeOb securitySchemeOb);
+    eq SecuritySchemeReference.reverseSecurityScheme(SecuritySchemeOb securitySchemeOb){
+        io.swagger.v3.oas.models.security.SecurityScheme securityScheme = new io.swagger.v3.oas.models.security.SecurityScheme();
+        SecuritySchemeReference s = (SecuritySchemeReference) securitySchemeOb;
+
+        if (!s.getRef().isEmpty()) {
+            securityScheme.set$ref(s.getRef());
+        }
+
+        return securityScheme;
+    }
+    eq SecuritySchemeObject.reverseSecurityScheme(SecuritySchemeOb securitySchemeOb){
+        io.swagger.v3.oas.models.security.SecurityScheme securityScheme = new io.swagger.v3.oas.models.security.SecurityScheme();
+        SecuritySchemeObject s = (SecuritySchemeObject) securitySchemeOb;
+
+        switch (s.getType()) {
+            case "apiKey":
+                securityScheme.setType(SecurityScheme.Type.APIKEY);
+                break;
+            case "http":
+                securityScheme.setType(SecurityScheme.Type.HTTP);
+                break;
+            case "oauth2":
+                securityScheme.setType(SecurityScheme.Type.OAUTH2);
+                break;
+            case "openIdConnect":
+                securityScheme.setType(SecurityScheme.Type.OPENIDCONNECT);
+                break;
+        }
+        if (!s.getName().isEmpty())
+            securityScheme.setName(s.getName());
+        switch (s.getIn()) {
+            case "cookie":
+                securityScheme.setIn(SecurityScheme.In.COOKIE);
+                break;
+            case "header":
+                securityScheme.setIn(SecurityScheme.In.HEADER);
+                break;
+            case "query":
+                securityScheme.setIn(SecurityScheme.In.QUERY);
+                break;
+        }
+        if (!s.getScheme().isEmpty())
+            securityScheme.setScheme(s.getScheme());
+        if (!s.getOpenIdConnectUrl().isEmpty())
+            securityScheme.setOpenIdConnectUrl(s.getOpenIdConnectUrl());
+        if (s.getO() != null)
+            securityScheme.setFlows(OAuthFlowsObject.reverseOAuthFlows(s.getO()));
+        if (!s.getDescription().isEmpty())
+            securityScheme.setDescription(s.getDescription());
+        if (!s.getBearerFormat().isEmpty())
+            securityScheme.setBearerFormat(s.getBearerFormat());
+
+        if (s.getNumEx() != 0) {
+            Map<String, Object> extensionMap = new HashMap<>();
+            for (Extension e : s.getExList())
+                extensionMap.put(e.getKey(), e.getValue());
+            securityScheme.setExtensions(extensionMap);
+        }
+
+        return securityScheme;
+    }
+
+    public static io.swagger.v3.oas.models.security.OAuthFlows OAuthFlowsObject.reverseOAuthFlows(OAuthFlowsObject oAuthFlowsObject){
+        io.swagger.v3.oas.models.security.OAuthFlows oAuthFlows = new io.swagger.v3.oas.models.security.OAuthFlows();
+
+        if (oAuthFlowsObject.hasI())
+            oAuthFlows.setImplicit(OAuthFlowObject.reverseOAuthFlow(oAuthFlowsObject.getI().getO()));
+        if (oAuthFlowsObject.hasP())
+            oAuthFlows.setPassword(OAuthFlowObject.reverseOAuthFlow(oAuthFlowsObject.getP().getO()));
+        if (oAuthFlowsObject.hasC())
+            oAuthFlows.setClientCredentials(OAuthFlowObject.reverseOAuthFlow(oAuthFlowsObject.getC().getO()));
+        if (oAuthFlowsObject.hasA())
+            oAuthFlows.setAuthorizationCode(OAuthFlowObject.reverseOAuthFlow(oAuthFlowsObject.getA().getO()));
+
+        return oAuthFlows;
+    }
+
+    public static io.swagger.v3.oas.models.security.OAuthFlow OAuthFlowObject.reverseOAuthFlow(OAuthFlowObject oAuthFlowObject){
+        io.swagger.v3.oas.models.security.OAuthFlow oAuthFlow = new io.swagger.v3.oas.models.security.OAuthFlow();
+        Scopes scopes = new Scopes();
+
+        if (!oAuthFlowObject.getAuthorizationUrl().isEmpty())
+            oAuthFlow.setAuthorizationUrl(oAuthFlowObject.getAuthorizationUrl());
+        if (!oAuthFlowObject.getTokenUrl().isEmpty())
+            oAuthFlow.setTokenUrl(oAuthFlowObject.getTokenUrl());
+        for (ScopesTuple t : oAuthFlowObject.getSList())
+            scopes.put(t.getScopesKey(), t.getScopesValue());
+        oAuthFlow.setScopes(scopes);
+        if (!oAuthFlowObject.getRefreshUrl().isEmpty())
+            oAuthFlow.setRefreshUrl(oAuthFlowObject.getRefreshUrl());
+
+        return oAuthFlow;
+    }
+
+    public static io.swagger.v3.oas.models.security.SecurityRequirement SecurityRequirementObject.reverseSecurityRequirement(SecurityRequirementObject securityRequirementObject){
+        io.swagger.v3.oas.models.security.SecurityRequirement securityRequirement = new io.swagger.v3.oas.models.security.SecurityRequirement();
+
+        if (securityRequirementObject.getNumTuple() != 0) {
+            Map<String, List<String>> requirements = new HashMap<>();
+            for (SecurityRequirementTuple t : securityRequirementObject.getTupleList()) {
+                List<String> values = new ArrayList<>();
+                for (SecurityRequirementValue v : t.getValueList())
+                    values.add(v.getValue());
+                securityRequirement.addList(t.getName(), values);
+            }
+        }
+
+        return securityRequirement;
+    }
+}
diff --git a/src/main/java/de/tudresden/inf/st/openapi/OpenAPIMain.java b/src/main/java/de/tudresden/inf/st/openapi/OpenAPIMain.java
index aa0842ab9dd95af2a8fdf2b57b50328e4e2a2a93..f08e2738450ce940d3c770edde02f169a9df7537 100644
--- a/src/main/java/de/tudresden/inf/st/openapi/OpenAPIMain.java
+++ b/src/main/java/de/tudresden/inf/st/openapi/OpenAPIMain.java
@@ -1,82 +1,90 @@
 package de.tudresden.inf.st.openapi;
 
-import de.tudresden.inf.st.openapi.ast.OpenAPIObject;
-import org.openapi4j.core.validation.ValidationResults;
-import org.openapi4j.parser.OpenApi3Parser;
-import org.openapi4j.parser.model.v3.OpenApi3;
-
-import java.io.File;
-import java.io.FileNotFoundException;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import io.swagger.models.reader.SwaggerParser;
+import io.swagger.parser.OpenAPIParser;
+import io.swagger.report.MessageBuilder;
+import io.swagger.util.Yaml;
+import io.swagger.v3.core.util.Json;
+import io.swagger.v3.oas.models.OpenAPI;
+import io.swagger.v3.parser.OpenAPIV3Parser;
+import io.swagger.v3.parser.core.models.ParseOptions;
+import io.swagger.v3.parser.core.models.SwaggerParseResult;
+import io.swagger.v3.parser.util.OpenAPIDeserializer;
+import io.swagger.validate.ApiDeclarationJsonValidator;
+import io.swagger.validate.SwaggerSchemaValidator;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.impl.client.HttpClientBuilder;
+
+import javax.net.ssl.HttpsURLConnection;
+import java.io.*;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
 import java.net.URL;
 import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
 
 public class OpenAPIMain {
 
-  /**
-   * main-method, calls the set of methods to test the OpenAPI-Generator with JastAdd
-   **/
-  public static void main(String[] args) throws Exception {
-    OpenAPIObject openApi = new OpenAPIObject();
-    OpenApi3 api3;
-    ValidationResults results;
-    List<String> filenames = new ArrayList<>();
-    String genDir = "./gen-api-ex/";
-    File genDirectory = new File(genDir);
-    File[] contents;
-
-    File resource = new File("./src/main/resources");
-
-    for (File file : resource.listFiles())
-      filenames.add(file.getName());
-    System.out.println(filenames.size());
-
+    /**
+     * main-method, calls the set of methods to test the OpenAPI-Generator with JastAdd
+     **/
+    public static void main(String[] args) throws Exception {
+        List<String> filenames = new ArrayList<>();
+        String genDir = "./gen-api-ex/";
+        File genDirectory = new File(genDir);
+        File[] contents;
+        File resource = new File("./src/main/resources");
+
+        // init parser
+        String fileName = "./src/main/resources/3.0/petstore.yaml";
         /*
-        for( String file : filenames ){
-            String writerName = genDir + file;
+        ParseOptions options = new ParseOptions();
+        options.setResolve(true);
+        options.setResolveFully(true);
+        options.setAllowEmptyString(false);
+         */
+        SwaggerParseResult result = new OpenAPIParser().readLocation(fileName, null, null);
 
-            URL expUrl = OpenAPIMain.class.getClassLoader().getResource(file);
-            OpenApi3 api = new OpenApi3Parser().parse(expUrl, new ArrayList<>(), true);
-            System.out.println("Loading expression DSL file '" + file + "'.");
+        String resultString;
+        OpenAPI openAPI = result.getOpenAPI();
 
-            openApi = OpenAPIObject.parseOpenAPI(api);
-            api3 = OpenAPIObject.composeOpenAPI(openApi);
-            openApi.generateRequests();
+        OpenAPIDeserializer deserializer = new OpenAPIDeserializer();
+        String res = Json.mapper().writeValueAsString(openAPI);
+        ObjectMapper mapper = new ObjectMapper();
+        JsonNode node = mapper.readTree(res);
+        //System.out.println(node.toPrettyString());
 
-        }
-         */
 
-    String fileName = "petstore-v2.yaml";
-    //FileWriter writer = new FileWriter("./gen-api-ex/callback-example_generated.json");
+        /** OpenAPI Validator! **/
+        List<String> validation = new OpenAPIV3Parser().readContents(res).getMessages();
+        for(String mes : validation)
+            System.out.println("message : " + mes);
 
-    URL expUrl = OpenAPIMain.class.getClassLoader().getResource(fileName);
-    File file = null;
-    if (expUrl != null) {
-      file = new File(expUrl.getFile());
-    } else {
-      file = new File(fileName);
-    }
-    if (file == null) {
-      throw new FileNotFoundException("Could not load JSON file " + fileName);
-    }
 
-    OpenApi3 api = new OpenApi3Parser().parse(expUrl, new ArrayList<>(), true);
-    System.out.println("Loading expression DSL file '" + fileName + "'.");
+        //Json.mapper().createParser(Json.mapper().writeValueAsString(openAPI)).
 
-    openApi = OpenAPIObject.parseOpenAPI(api);
-    openApi.generateRequestsWithInferredParameters();
+        // Yaml String
+        //System.out.println(Yaml.mapper().writerWithDefaultPrettyPrinter().writeValueAsString(openAPI));
+        //resultString = Yaml.mapper().writerWithDefaultPrettyPrinter().writeValueAsString(openAPI);
 
-    //writer.write(api3.toNode().toPrettyString());
-    //writer.close();
+        URL expUrl = OpenAPIMain.class.getClassLoader().getResource(fileName);
+        File file = null;
+        if (expUrl != null) {
+            file = new File(expUrl.getFile());
+        } else {
+            file = new File(fileName);
+        }
+        if (file == null) {
+            throw new FileNotFoundException("Could not load JSON file " + fileName);
+        }
 
+        System.out.println("Loading expression DSL file '" + fileName + "'.");
 
-    Map<String, List<String>> s = new HashMap<>();
+        if (args.length > 0) {
+            fileName = args[0];
+        }
 
-    if (args.length > 0) {
-      fileName = args[0];
     }
-
-  }
 }
\ No newline at end of file
diff --git a/src/main/resources/petstore-v2.yaml b/src/main/resources/3.0/petstore-v2.yaml
similarity index 100%
rename from src/main/resources/petstore-v2.yaml
rename to src/main/resources/3.0/petstore-v2.yaml
diff --git a/src/main/resources/petstore.yaml b/src/main/resources/3.0/petstore.yaml
similarity index 100%
rename from src/main/resources/petstore.yaml
rename to src/main/resources/3.0/petstore.yaml
diff --git a/src/main/resources/version.properties b/src/main/resources/version.properties
new file mode 100644
index 0000000000000000000000000000000000000000..9a2095a6a14db658a91b0bf75840df811003fb68
--- /dev/null
+++ b/src/main/resources/version.properties
@@ -0,0 +1,2 @@
+#Fri Mar 11 17:24:51 CET 2022
+version=0.1.0
\ No newline at end of file
diff --git a/src/test/java/openapi/OpenAPIMain_test.java b/src/test/java/openapi/OpenAPIMain_test.java
index 89ff96378bbd151b77461a6b58a2230c74a6c7a7..a5c554df88aef61ad7d2a79efb3df57248e4fbbd 100644
--- a/src/test/java/openapi/OpenAPIMain_test.java
+++ b/src/test/java/openapi/OpenAPIMain_test.java
@@ -1,120 +1,68 @@
 package openapi;
 
 import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.node.ArrayNode;
 import com.flipkart.zjsonpatch.JsonDiff;
 import com.jayway.jsonpath.JsonPath;
-import de.tudresden.inf.st.openapi.ast.OpenAPIObject;
+import de.tudresden.inf.st.openapi.ast.*;
+import io.swagger.parser.OpenAPIParser;
+import io.swagger.v3.core.util.Json;
+import io.swagger.v3.core.util.Yaml;
+import io.swagger.v3.oas.models.OpenAPI;
+import io.swagger.v3.parser.OpenAPIV3Parser;
+import io.swagger.v3.parser.core.models.SwaggerParseResult;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
-import org.openapi4j.core.validation.ValidationResults;
-import org.openapi4j.parser.OpenApi3Parser;
-import org.openapi4j.parser.model.v3.OpenApi3;
 
 import java.io.File;
-import java.io.FileWriter;
 import java.io.IOException;
-import java.net.URL;
 import java.nio.file.Path;
 import java.nio.file.Paths;
-import java.util.ArrayList;
 import java.util.List;
 
 public class OpenAPIMain_test {
 
-  protected static boolean isNumeric(String str) {
-    try {
-      int d = Integer.parseInt(str);
-    } catch (NumberFormatException nfe) {
-      return false;
-    }
-    return true;
-  }
-
   @Test
   public void test() throws Exception {
-    OpenAPIObject openApi = new OpenAPIObject();
-    OpenApi3 api3;
-    ValidationResults results;
-    List<String> filenames = new ArrayList<>();
-    String genDir = "./gen-api-ex/";
-    File genDirectory = new File(genDir);
-    File[] contents;
-
     File resource = new File("./src/main/resources");
 
-    for (File file : resource.listFiles())
-      filenames.add(file.getName());
-    System.out.println(filenames.size());
-
-    for (String file : filenames) {
-      String writerName = genDir + file;
-      FileWriter expectedWriter = new FileWriter((writerName.substring(0, writerName.length() - 5) + "-expected.json"));
-      FileWriter actualWriter = new FileWriter((writerName.substring(0, writerName.length() - 5) + "-actual.json"));
-      URL expUrl = OpenAPIMain_test.class.getClassLoader().getResource(file);
-
-      // parsed openAPI object with openapi4j
-      OpenApi3 api = new OpenApi3Parser().parse(expUrl, new ArrayList<>(), true);
-      System.out.println("Loading expression DSL file '" + file + "'.");
-      // save expected object
-      expectedWriter.write(api.toNode().toPrettyString());
-      expectedWriter.close();
-
-      //results = OpenApi3Validator.instance().validate(api);
-      //System.out.println(results.isValid());
-
-      // openAPI object is integrated in JastAdd grammar
-      openApi = openApi.parseOpenAPI(api);
-      System.out.println(openApi.getPathsObject(0).getPathItemObject().getPost().getOperationObject().getResponseTuple(0).getResponseOb().responseObject().getContentTuple(0).getMediaTypeObject().getSchemaOb().getClass().getName());
-
-      //Map<ResponseObject, String> map = openApi.generateRequests();
-
-      // composed openAPI object, it is expected to be equivalent to parsed source object
-      api3 = OpenAPIObject.composeOpenAPI(openApi);
-
-      // check, if the composed openAPI object is valid
-      //results = OpenApi3Validator.instance().validate(api3);
-      //System.out.println(results.isValid());
-
-      //System.out.println(api.toNode().equals(api3.toNode()));
-
-      // save generated object
-      actualWriter.write(api3.toNode().toPrettyString());
-      actualWriter.close();
-
-      // compare if api (source object) is equivalent to api3 (generated object)
-      compareJson(api3.toNode(), api.toNode(), Paths.get(file));
-    }
-
-    // clean all generated jsons
-    contents = genDirectory.listFiles();
-    if (contents != null) {
-      for (File file : contents)
-        file.delete();
-    }
+    recursiveTest(resource);
   }
 
-  protected void compareJson(JsonNode expectedNode, JsonNode actualNode, Path path) throws IOException {
+  protected static void compareJson(JsonNode expectedNode, JsonNode actualNode, Path path) throws IOException {
     JsonNode diff = JsonDiff.asJson(expectedNode, actualNode);
     String pathNode;
+    String result = "";
 
     for (int i = diff.size() - 1; i >= 0; i--) {
       // get the path of a node involving difference.
-      pathNode = "$" + diff.get(i).get("path").toString()
+      pathNode = "$" + diff.get(i).get("path").toString();
+      for (String s : pathNode.split("/")) {
+        if (s.contains("."))
+          pathNode = pathNode.replace(s, "['" + s + "']");
+        else if (s.contains(" "))
+          pathNode = pathNode.replace(s, "['" + s + "']");
+      }
+      pathNode = pathNode
           .replace("/", ".")
           .replace("~1", "/")
           .replace("\"", "");
       for (String s : pathNode.split("\\.")) {
-        if (isNumeric(s) && Integer.parseInt(s) < 100)
-          pathNode = pathNode.replace(s, "[" + s + "]");
+        if ( !s.contains("['") && isNumeric(s) && Integer.parseInt(s) < 200)
+          result = result.concat("[" + s + "].");
+        else
+          result = result.concat(s + ".");
       }
+      pathNode = result.substring(0, result.length()-1);
 
-
-      // check, if this node exists or has an empty value.
-      if (JsonPath.parse(actualNode.toString()).read(pathNode, String.class) == null || JsonPath.parse(actualNode.toString()).read(pathNode, String.class).isEmpty())
+      // check, if this node is null or has an empty value.
+      if (JsonPath.parse(expectedNode.toString()).read(pathNode, String.class) == null || JsonPath.parse(expectedNode.toString()).read(pathNode, String.class).isEmpty())
         ((ArrayNode) diff).remove(i);
-      else if (!JsonPath.parse(actualNode.toString()).read(pathNode.substring(0, pathNode.lastIndexOf(".")).concat(".$ref"), String.class).isEmpty())
+      else if (JsonPath.parse(actualNode.toString()).read(pathNode, String.class) == null || JsonPath.parse(actualNode.toString()).read(pathNode, String.class).isEmpty())
         ((ArrayNode) diff).remove(i);
+
+      result = "";
     }
 
     // if the Jsons are equivalent, there is no reason to to the text comparison.
@@ -123,4 +71,61 @@ public class OpenAPIMain_test {
       Assertions.assertEquals(actualNode.toPrettyString(), expectedNode.toPrettyString(), "JSONs for " + path + " are different:\n" + diff.toPrettyString());
     }
   }
+
+  protected static boolean isNumeric(String str) {
+    try {
+      int d = Integer.parseInt(str);
+    } catch (NumberFormatException nfe) {
+      return false;
+    }
+    return true;
+  }
+
+  protected static void recursiveTest(File file) throws Exception {
+    if ( file.isDirectory() ) {
+      for ( File f : file.listFiles() )
+        recursiveTest(f);
+    } else if ( file.isFile() && file.getPath().contains("yaml") ) {
+      OpenAPIObject jastAddObject;
+      OpenAPI POJOOpenAPI;
+      ObjectMapper mapper = new ObjectMapper();
+      List<String> validation;
+
+      // parsed openAPI object with swagger-parser
+      SwaggerParseResult result = new OpenAPIParser().readLocation(file.getPath(), null, null);
+      POJOOpenAPI = result.getOpenAPI();
+      System.out.println("Loading expression DSL file '" + file + "'.");
+
+      // validation of OpenAPI in POJO
+      JsonNode expectedNode = mapper.readTree(Json.mapper().writeValueAsString(POJOOpenAPI));
+      validation = new OpenAPIV3Parser().readContents(expectedNode.toString()).getMessages();
+      if ( validation.size() != 0 ) {
+        System.out.println("validation failed!");
+        for ( String s : validation )
+          System.out.println(s);
+      }
+      else
+        System.out.println("validated!");
+
+      // OpenAPI in POJO to OpenAPI in JastAdd
+      jastAddObject = OpenAPIObject.parseOpenAPI(POJOOpenAPI);
+
+      // OpenAPI in JastAdd to OpenAPI in POJO
+      OpenAPI transformedAPI = OpenAPIObject.reverseOpenAPI(jastAddObject);
+
+      // validation of transferred OpenAPI
+      JsonNode actualNode = mapper.readTree(Json.mapper().writeValueAsString(transformedAPI));
+      validation = new OpenAPIV3Parser().readContents(actualNode.toString()).getMessages();
+      if ( validation.size() != 0 ) {
+        System.out.println("validation failed!");
+        for ( String s : validation )
+          System.out.println(s);
+      }
+      else
+        System.out.println("validated");
+
+      // compare if api (source object) is equivalent to api3 (generated object)
+      compareJson(expectedNode, actualNode, Paths.get(file.getPath()));
+    }
+  }
 }
\ No newline at end of file
diff --git a/uml/ast.png b/uml/ast.png
new file mode 100644
index 0000000000000000000000000000000000000000..65ea8d9454d9477ce498f11e6603e5aae974b362
Binary files /dev/null and b/uml/ast.png differ
diff --git a/uml/relast.png b/uml/relast.png
new file mode 100644
index 0000000000000000000000000000000000000000..27c663f7701cc3f8df585f5ab926113e0c2dc98f
Binary files /dev/null and b/uml/relast.png differ