diff --git a/src/main/xtend-gen/org/oceandsl/rqda/log/generator/graphml/GraphmlGenerator.java b/src/main/xtend-gen/org/oceandsl/rqda/log/generator/graphml/GraphmlGenerator.java
new file mode 100644
index 0000000000000000000000000000000000000000..328dabd1df744e76021b70da61157da8b1aad286
--- /dev/null
+++ b/src/main/xtend-gen/org/oceandsl/rqda/log/generator/graphml/GraphmlGenerator.java
@@ -0,0 +1,397 @@
+/**
+ * Copyright (C) 2021 OceanDSL (https://oceandsl.uni-kiel.de)
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.oceandsl.rqda.log.generator.graphml;
+
+import java.sql.SQLException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.function.Consumer;
+import org.eclipse.xtend2.lib.StringConcatenation;
+import org.eclipse.xtext.xbase.lib.Exceptions;
+import org.eclipse.xtext.xbase.lib.Functions.Function1;
+import org.eclipse.xtext.xbase.lib.IterableExtensions;
+import org.oceandsl.rqda.log.DatabaseUtils;
+import org.oceandsl.rqda.log.PlotUtils;
+import org.oceandsl.rqda.log.Tuple;
+import org.oceandsl.rqda.log.Tuples;
+import org.oceandsl.rqda.log.generator.IGenerator;
+
+/**
+ * @author Reiner Jung
+ * 
+ * @since 1.0
+ */
+@SuppressWarnings("all")
+public class GraphmlGenerator implements IGenerator {
+  private int leafId = 0;
+  
+  private int edgeId = 0;
+  
+  @Override
+  public CharSequence generateAggregatedCodes(final DatabaseUtils databaseAccess) {
+    try {
+      StringConcatenation _builder = new StringConcatenation();
+      String _createHeader = GraphmlTemplates.createHeader();
+      _builder.append(_createHeader);
+      _builder.newLineIfNotEmpty();
+      CharSequence _plotAggregatedCodes = this.plotAggregatedCodes(databaseAccess);
+      _builder.append(_plotAggregatedCodes);
+      _builder.newLineIfNotEmpty();
+      String _createFooter = GraphmlTemplates.createFooter();
+      _builder.append(_createFooter);
+      _builder.newLineIfNotEmpty();
+      return _builder;
+    } catch (Throwable _e) {
+      throw Exceptions.sneakyThrow(_e);
+    }
+  }
+  
+  @Override
+  public CharSequence generateAllCategories(final DatabaseUtils databaseAccess, final boolean plotCodes) {
+    try {
+      StringConcatenation _builder = new StringConcatenation();
+      String _createHeader = GraphmlTemplates.createHeader();
+      _builder.append(_createHeader);
+      _builder.newLineIfNotEmpty();
+      CharSequence _plotAllCategories = this.plotAllCategories(databaseAccess, plotCodes);
+      _builder.append(_plotAllCategories);
+      _builder.newLineIfNotEmpty();
+      String _createFooter = GraphmlTemplates.createFooter();
+      _builder.append(_createFooter);
+      _builder.newLineIfNotEmpty();
+      return _builder;
+    } catch (Throwable _e) {
+      throw Exceptions.sneakyThrow(_e);
+    }
+  }
+  
+  @Override
+  public CharSequence generateThemeMap(final DatabaseUtils databaseAccess, final boolean plotCodes, final String category) {
+    try {
+      StringConcatenation _builder = new StringConcatenation();
+      String _createHeader = GraphmlTemplates.createHeader();
+      _builder.append(_createHeader);
+      _builder.newLineIfNotEmpty();
+      CharSequence _plotThemeNode = this.plotThemeNode(databaseAccess, plotCodes, category);
+      _builder.append(_plotThemeNode);
+      _builder.newLineIfNotEmpty();
+      String _createFooter = GraphmlTemplates.createFooter();
+      _builder.append(_createFooter);
+      _builder.newLineIfNotEmpty();
+      return _builder;
+    } catch (Throwable _e) {
+      throw Exceptions.sneakyThrow(_e);
+    }
+  }
+  
+  /**
+   * plot aggregated codes.
+   */
+  private CharSequence plotAggregatedCodes(final DatabaseUtils databaseAccess) throws SQLException {
+    CharSequence _xblockexpression = null;
+    {
+      final Map<Integer, String> categories = databaseAccess.getCategories();
+      final Map<Integer, String> codes = databaseAccess.getCodes();
+      final Tuples<Integer, Integer> links = databaseAccess.getLinks();
+      final HashMap<Integer, String> singleAssignedCodes = new HashMap<Integer, String>();
+      final HashMap<Integer, List<Integer>> multiAssignedCodes = new HashMap<Integer, List<Integer>>();
+      final Tuples<Integer, Integer> singleLinks = new Tuples<Integer, Integer>();
+      Set<Map.Entry<Integer, String>> _entrySet = codes.entrySet();
+      for (final Map.Entry<Integer, String> entry : _entrySet) {
+        {
+          final List<Integer> sharingCategories = databaseAccess.getCategoriesForCode(entry.getKey());
+          int _size = sharingCategories.size();
+          boolean _greaterThan = (_size > 1);
+          if (_greaterThan) {
+            multiAssignedCodes.put(entry.getKey(), sharingCategories);
+          } else {
+            int _size_1 = sharingCategories.size();
+            boolean _equals = (_size_1 == 1);
+            if (_equals) {
+              singleAssignedCodes.put(entry.getKey(), entry.getValue());
+              singleLinks.put(sharingCategories.get(0), entry.getKey());
+            }
+          }
+        }
+      }
+      this.leafId = 0;
+      this.edgeId = 0;
+      Set<Integer> _keySet = categories.keySet();
+      for (final Integer id : _keySet) {
+        if ((this.leafId < (id).intValue())) {
+          this.leafId = (id).intValue();
+        }
+      }
+      StringConcatenation _builder = new StringConcatenation();
+      final Function1<Map.Entry<Integer, String>, String> _function = (Map.Entry<Integer, String> it) -> {
+        return GraphmlTemplates.createNode((it.getKey()).intValue(), it.getValue(), GraphmlTemplates.getColor(it.getValue()));
+      };
+      String _join = IterableExtensions.join(IterableExtensions.<Map.Entry<Integer, String>, String>map(categories.entrySet(), _function));
+      _builder.append(_join);
+      _builder.newLineIfNotEmpty();
+      final Function1<Tuple<Integer, Integer>, String> _function_1 = (Tuple<Integer, Integer> it) -> {
+        int _plusPlus = this.edgeId++;
+        return GraphmlTemplates.createEdge(_plusPlus, (it.getLeft()).intValue(), (it.getRight()).intValue());
+      };
+      String _join_1 = IterableExtensions.join(IterableExtensions.<Tuple<Integer, Integer>, String>map(links.getTuples(), _function_1));
+      _builder.append(_join_1);
+      _builder.newLineIfNotEmpty();
+      final Function1<Map.Entry<Integer, String>, String> _function_2 = (Map.Entry<Integer, String> code) -> {
+        String _xblockexpression_1 = null;
+        {
+          final Integer categoryId = singleLinks.find4Right(code.getKey());
+          String _createNode = GraphmlTemplates.createNode(this.leafId, code.getValue(), "#FFFFFF");
+          int _plusPlus = this.edgeId++;
+          int _plusPlus_1 = this.leafId++;
+          String _createEdge = GraphmlTemplates.createEdge(_plusPlus, (categoryId).intValue(), _plusPlus_1);
+          _xblockexpression_1 = (_createNode + _createEdge);
+        }
+        return _xblockexpression_1;
+      };
+      Iterable<String> _map = IterableExtensions.<Map.Entry<Integer, String>, String>map(singleAssignedCodes.entrySet(), _function_2);
+      _builder.append(_map);
+      _builder.newLineIfNotEmpty();
+      final Function1<Map.Entry<Integer, List<Integer>>, CharSequence> _function_3 = (Map.Entry<Integer, List<Integer>> entry_1) -> {
+        return this.computeIndirectCategoryInterdependency(entry_1.getValue());
+      };
+      String _join_2 = IterableExtensions.join(IterableExtensions.<Map.Entry<Integer, List<Integer>>, CharSequence>map(multiAssignedCodes.entrySet(), _function_3));
+      _builder.append(_join_2);
+      _builder.newLineIfNotEmpty();
+      _xblockexpression = _builder;
+    }
+    return _xblockexpression;
+  }
+  
+  private CharSequence computeIndirectCategoryInterdependency(final List<Integer> assignedCategories) {
+    String result = "";
+    final Tuples<Integer, Integer> existingLinks = new Tuples<Integer, Integer>();
+    for (int i = 0; (i < (assignedCategories.size() - 1)); i++) {
+      for (int j = (i + 1); (j < assignedCategories.size()); j++) {
+        boolean _edgeExists = PlotUtils.edgeExists(existingLinks, assignedCategories.get(i), assignedCategories.get(j));
+        boolean _not = (!_edgeExists);
+        if (_not) {
+          String _result = result;
+          int _plusPlus = this.edgeId++;
+          String _createDashedEdge = GraphmlTemplates.createDashedEdge(_plusPlus, assignedCategories.get(i), 
+            assignedCategories.get(j));
+          result = (_result + _createDashedEdge);
+          existingLinks.put(assignedCategories.get(i), assignedCategories.get(j));
+        }
+      }
+    }
+    return result;
+  }
+  
+  /**
+   * PLot all categories and their links.
+   * 
+   * @param databaseAccess
+   *            source model
+   * @param plotCodes
+   *            whether to plot codes
+   * 
+   * @throws SQLException
+   * @throws IOException
+   */
+  private CharSequence plotAllCategories(final DatabaseUtils databaseAccess, final boolean plotCodes) throws SQLException {
+    CharSequence _xblockexpression = null;
+    {
+      final Map<Integer, String> categories = databaseAccess.getCategories();
+      final HashMap<Integer, String> existingCodes = new HashMap<Integer, String>();
+      final Tuples<Integer, Integer> links = databaseAccess.getLinks();
+      this.leafId = 0;
+      this.edgeId = 0;
+      Set<Integer> _keySet = categories.keySet();
+      for (final Integer id : _keySet) {
+        if ((this.leafId < (id).intValue())) {
+          this.leafId = (id).intValue();
+        }
+      }
+      StringConcatenation _builder = new StringConcatenation();
+      final Function1<Map.Entry<Integer, String>, String> _function = (Map.Entry<Integer, String> it) -> {
+        try {
+          String _createNode = GraphmlTemplates.createNode((it.getKey()).intValue(), it.getValue(), GraphmlTemplates.getColor(it.getValue()));
+          CharSequence _xifexpression = null;
+          if (plotCodes) {
+            _xifexpression = this.plotAllCategoryCodes(databaseAccess, (it.getKey()).intValue(), it.getValue(), links, existingCodes);
+          }
+          return (_createNode + _xifexpression);
+        } catch (Throwable _e) {
+          throw Exceptions.sneakyThrow(_e);
+        }
+      };
+      String _join = IterableExtensions.join(IterableExtensions.<Map.Entry<Integer, String>, String>map(categories.entrySet(), _function));
+      _builder.append(_join);
+      _builder.newLineIfNotEmpty();
+      final Function1<Tuple<Integer, Integer>, String> _function_1 = (Tuple<Integer, Integer> it) -> {
+        int _plusPlus = this.edgeId++;
+        return GraphmlTemplates.createEdge(_plusPlus, (it.getLeft()).intValue(), (it.getRight()).intValue());
+      };
+      String _join_1 = IterableExtensions.join(IterableExtensions.<Tuple<Integer, Integer>, String>map(links.getTuples(), _function_1));
+      _builder.append(_join_1);
+      _builder.newLineIfNotEmpty();
+      _xblockexpression = _builder;
+    }
+    return _xblockexpression;
+  }
+  
+  /**
+   * Plot all code nodes corresponding to a given category and collect all links between the
+   * category and the codes for later processing.
+   * 
+   * @param databaseAccess
+   *            source model
+   * @param parentId
+   *            id of the category
+   * @param parentName
+   *            name of the category
+   * @param links
+   *            tuples containing links
+   * @param existingNodes
+   *            map of existing nodes to avoid code duplication
+   * 
+   * @throws SQLException
+   * @throws IOException
+   */
+  private CharSequence plotAllCategoryCodes(final DatabaseUtils databaseAccess, final int parentId, final String parentName, final Tuples<Integer, Integer> links, final Map<Integer, String> existingNodes) throws SQLException {
+    String result = "";
+    List<String> _codesForCategory = databaseAccess.getCodesForCategory(parentName);
+    for (final String code : _codesForCategory) {
+      {
+        boolean _nodeExists = PlotUtils.nodeExists(existingNodes, code);
+        boolean _not = (!_nodeExists);
+        if (_not) {
+          String _result = result;
+          String _createNode = GraphmlTemplates.createNode(this.leafId, code, "#FFFFFF");
+          result = (_result + _createNode);
+          int _plusPlus = this.leafId++;
+          existingNodes.put(Integer.valueOf(_plusPlus), code);
+        }
+        final Integer childId = PlotUtils.findNodeId(existingNodes, code);
+        boolean _edgeExists = PlotUtils.edgeExists(links, Integer.valueOf(parentId), childId);
+        boolean _not_1 = (!_edgeExists);
+        if (_not_1) {
+          links.put(Integer.valueOf(parentId), childId);
+        }
+      }
+    }
+    return result;
+  }
+  
+  /**
+   * Plot theme node and all subsequent categories and their code nodes.
+   * 
+   * @param databaseAccess
+   *            source model
+   * @param plotCodes
+   *            whether to plot codes
+   * @param theme
+   *            theme name
+   * 
+   * @throws SQLException
+   * @throws IOException
+   */
+  private CharSequence plotThemeNode(final DatabaseUtils databaseAccess, final boolean plotCodes, final String theme) throws SQLException {
+    CharSequence _xblockexpression = null;
+    {
+      final Map<Integer, String> categories = databaseAccess.getCategories();
+      final Tuples<Integer, Integer> links = databaseAccess.getLinks();
+      final HashMap<Integer, String> existingCategoryNodes = new HashMap<Integer, String>();
+      this.leafId = 400;
+      this.edgeId = 0;
+      final Integer themeId = PlotUtils.findNodeId(categories, theme);
+      existingCategoryNodes.put(themeId, theme);
+      final Tuples<Integer, Integer> resultLinks = this.collectCategoriesAndLinks(categories, links, (themeId).intValue(), existingCategoryNodes);
+      final HashMap<Integer, String> existingCodeNodes = new HashMap<Integer, String>();
+      StringConcatenation _builder = new StringConcatenation();
+      String _createNode = GraphmlTemplates.createNode((themeId).intValue(), theme, GraphmlTemplates.getColor(theme));
+      _builder.append(_createNode);
+      _builder.newLineIfNotEmpty();
+      final Function1<Map.Entry<Integer, String>, String> _function = (Map.Entry<Integer, String> category) -> {
+        return GraphmlTemplates.createNode((category.getKey()).intValue(), category.getValue(), GraphmlTemplates.getColor(category.getValue()));
+      };
+      String _join = IterableExtensions.join(IterableExtensions.<Map.Entry<Integer, String>, String>map(existingCategoryNodes.entrySet(), _function));
+      _builder.append(_join);
+      _builder.newLineIfNotEmpty();
+      final Function1<Map.Entry<Integer, String>, CharSequence> _function_1 = (Map.Entry<Integer, String> code) -> {
+        try {
+          return this.plotAllCategoryCodes(databaseAccess, (code.getKey()).intValue(), code.getValue(), resultLinks, existingCodeNodes);
+        } catch (Throwable _e) {
+          throw Exceptions.sneakyThrow(_e);
+        }
+      };
+      String _join_1 = IterableExtensions.join(IterableExtensions.<Map.Entry<Integer, String>, CharSequence>map(existingCategoryNodes.entrySet(), _function_1));
+      _builder.append(_join_1);
+      _builder.newLineIfNotEmpty();
+      final Function1<Tuple<Integer, Integer>, String> _function_2 = (Tuple<Integer, Integer> tuple) -> {
+        int _plusPlus = this.edgeId++;
+        return GraphmlTemplates.createEdge(_plusPlus, (tuple.getLeft()).intValue(), (tuple.getRight()).intValue());
+      };
+      String _join_2 = IterableExtensions.join(IterableExtensions.<Tuple<Integer, Integer>, String>map(resultLinks.getTuples(), _function_2));
+      _builder.append(_join_2);
+      _builder.newLineIfNotEmpty();
+      _xblockexpression = _builder;
+    }
+    return _xblockexpression;
+  }
+  
+  /**
+   * Plot category nodes following recursively their category to category links. Also collect
+   * links for later processing.
+   * 
+   * @param writer
+   *            file writer
+   * @param categories
+   *            map of category ids and names
+   * @param links
+   *            tuples containing links between categories
+   * @param parentId
+   *            the parent category
+   * @param existingNodes
+   *            existing nodes
+   * 
+   * @return returns links between code nodes and categories
+   * 
+   * @throws IOException
+   * @throws SQLException
+   */
+  private Tuples<Integer, Integer> collectCategoriesAndLinks(final Map<Integer, String> categories, final Tuples<Integer, Integer> links, final int parentId, final Map<Integer, String> existingNodes) throws SQLException {
+    final Tuples<Integer, Integer> resultLinks = new Tuples<Integer, Integer>();
+    final Consumer<Tuple<Integer, Integer>> _function = (Tuple<Integer, Integer> it) -> {
+      try {
+        Integer _left = it.getLeft();
+        boolean _tripleEquals = ((_left).intValue() == parentId);
+        if (_tripleEquals) {
+          final Integer id = it.getRight();
+          final String label = categories.get(id);
+          if ((label != null)) {
+            existingNodes.put(id, label);
+            resultLinks.addAll(this.collectCategoriesAndLinks(categories, links, (id).intValue(), existingNodes));
+            resultLinks.put(Integer.valueOf(parentId), id);
+          } else {
+            System.err.println(("Missing child category id " + id));
+          }
+        }
+      } catch (Throwable _e) {
+        throw Exceptions.sneakyThrow(_e);
+      }
+    };
+    links.getTuples().forEach(_function);
+    return resultLinks;
+  }
+}
diff --git a/src/main/xtend-gen/org/oceandsl/rqda/log/generator/json/JsonGenerator.java b/src/main/xtend-gen/org/oceandsl/rqda/log/generator/json/JsonGenerator.java
new file mode 100644
index 0000000000000000000000000000000000000000..080aa914f8d0a5cd647253d5c9964dd46cd32229
--- /dev/null
+++ b/src/main/xtend-gen/org/oceandsl/rqda/log/generator/json/JsonGenerator.java
@@ -0,0 +1,193 @@
+/**
+ * Copyright (C) 2021 OceanDSL (https://oceandsl.uni-kiel.de)
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.oceandsl.rqda.log.generator.json;
+
+import java.util.List;
+import java.util.Map;
+import org.eclipse.xtend2.lib.StringConcatenation;
+import org.eclipse.xtext.xbase.lib.Exceptions;
+import org.eclipse.xtext.xbase.lib.Functions.Function1;
+import org.eclipse.xtext.xbase.lib.IterableExtensions;
+import org.eclipse.xtext.xbase.lib.ListExtensions;
+import org.oceandsl.rqda.log.DatabaseUtils;
+import org.oceandsl.rqda.log.Tuple;
+import org.oceandsl.rqda.log.generator.IGenerator;
+
+/**
+ * @author Reiner Jung
+ * 
+ * @since 1.0
+ */
+@SuppressWarnings("all")
+public class JsonGenerator implements IGenerator {
+  @Override
+  public CharSequence generateAggregatedCodes(final DatabaseUtils databaseAccess) {
+    StringConcatenation _builder = new StringConcatenation();
+    return _builder;
+  }
+  
+  @Override
+  public CharSequence generateAllCategories(final DatabaseUtils databaseAccess, final boolean plotCodes) {
+    StringConcatenation _builder = new StringConcatenation();
+    CharSequence _createNodes = this.createNodes(databaseAccess, plotCodes);
+    _builder.append(_createNodes);
+    _builder.newLineIfNotEmpty();
+    CharSequence _createEdges = this.createEdges(databaseAccess, plotCodes);
+    _builder.append(_createEdges);
+    _builder.newLineIfNotEmpty();
+    return _builder;
+  }
+  
+  @Override
+  public CharSequence generateThemeMap(final DatabaseUtils database, final boolean plotCodes, final String category) {
+    StringConcatenation _builder = new StringConcatenation();
+    return _builder;
+  }
+  
+  private CharSequence createNodes(final DatabaseUtils databaseAccess, final boolean plotCodes) {
+    try {
+      StringConcatenation _builder = new StringConcatenation();
+      _builder.append("nodes: [");
+      _builder.newLine();
+      _builder.append("\t");
+      final Function1<Map.Entry<Integer, String>, CharSequence> _function = (Map.Entry<Integer, String> it) -> {
+        return this.createNode((it.getKey()).intValue(), it.getValue(), this.getCategoryShape(it), this.getCategoryColor(it));
+      };
+      String _join = IterableExtensions.join(IterableExtensions.<Map.Entry<Integer, String>, CharSequence>map(databaseAccess.getCategories().entrySet(), _function), ",\n");
+      _builder.append(_join, "\t");
+      _builder.append(",");
+      _builder.newLineIfNotEmpty();
+      _builder.append("\t");
+      final Function1<Map.Entry<Integer, String>, CharSequence> _function_1 = (Map.Entry<Integer, String> it) -> {
+        Integer _key = it.getKey();
+        int _plus = ((_key).intValue() + 1000);
+        return this.createNode(_plus, it.getValue(), this.getCodeShape(it), this.getCodeColor(it));
+      };
+      String _join_1 = IterableExtensions.join(IterableExtensions.<Map.Entry<Integer, String>, CharSequence>map(databaseAccess.getCodes().entrySet(), _function_1), ",\n");
+      _builder.append(_join_1, "\t");
+      _builder.newLineIfNotEmpty();
+      _builder.append("]");
+      _builder.newLine();
+      return _builder;
+    } catch (Throwable _e) {
+      throw Exceptions.sneakyThrow(_e);
+    }
+  }
+  
+  private String getCategoryShape(final Map.Entry<Integer, String> entry) {
+    return EShapes.BOX.label;
+  }
+  
+  private String getCategoryColor(final Map.Entry<Integer, String> entry) {
+    boolean _startsWith = entry.getValue().startsWith("Theme");
+    if (_startsWith) {
+      return "yellow";
+    } else {
+      return "lightblue";
+    }
+  }
+  
+  private String getCodeShape(final Map.Entry<Integer, String> entry) {
+    return EShapes.ELLIPSE.label;
+  }
+  
+  private String getCodeColor(final Map.Entry<Integer, String> entry) {
+    return "white";
+  }
+  
+  private CharSequence createNode(final int id, final String name, final String shape, final String color) {
+    StringConcatenation _builder = new StringConcatenation();
+    _builder.append("{ id: ");
+    _builder.append(id);
+    _builder.append(", label: \"");
+    _builder.append(name);
+    _builder.append("\", shape: \"");
+    _builder.append(shape);
+    _builder.append("\", color: { background: \"");
+    _builder.append(color);
+    _builder.append("\" border: \"black\"} }");
+    return _builder;
+  }
+  
+  private CharSequence createEdges(final DatabaseUtils databaseAccess, final boolean plotCodes) {
+    try {
+      StringConcatenation _builder = new StringConcatenation();
+      _builder.append("edges: [");
+      _builder.newLine();
+      _builder.append("\t");
+      final Function1<Tuple<Integer, Integer>, CharSequence> _function = (Tuple<Integer, Integer> it) -> {
+        return this.createLink(it.getLeft(), it.getRight());
+      };
+      String _join = IterableExtensions.join(IterableExtensions.<Tuple<Integer, Integer>, CharSequence>map(databaseAccess.getLinks().getTuples(), _function), ",\n");
+      _builder.append(_join, "\t");
+      _builder.append(",");
+      _builder.newLineIfNotEmpty();
+      _builder.append("\t");
+      final Function1<Map.Entry<Integer, String>, Boolean> _function_1 = (Map.Entry<Integer, String> it) -> {
+        try {
+          boolean _isEmpty = databaseAccess.getCodesForCategory(it.getValue()).isEmpty();
+          return Boolean.valueOf((!_isEmpty));
+        } catch (Throwable _e) {
+          throw Exceptions.sneakyThrow(_e);
+        }
+      };
+      final Function1<Map.Entry<Integer, String>, String> _function_2 = (Map.Entry<Integer, String> it) -> {
+        return this.createCategoryCodeLinks(databaseAccess, it);
+      };
+      String _join_1 = IterableExtensions.join(IterableExtensions.<Map.Entry<Integer, String>, String>map(IterableExtensions.<Map.Entry<Integer, String>>filter(databaseAccess.getCategories().entrySet(), _function_1), _function_2), ",\n");
+      _builder.append(_join_1, "\t");
+      _builder.newLineIfNotEmpty();
+      _builder.append("]");
+      _builder.newLine();
+      return _builder;
+    } catch (Throwable _e) {
+      throw Exceptions.sneakyThrow(_e);
+    }
+  }
+  
+  private String createCategoryCodeLinks(final DatabaseUtils databaseAccess, final Map.Entry<Integer, String> category) {
+    try {
+      String _xblockexpression = null;
+      {
+        final Map<Integer, String> codes = databaseAccess.getCodes();
+        final List<String> categoryCodes = databaseAccess.getCodesForCategory(category.getValue());
+        final Function1<String, CharSequence> _function = (String catCode) -> {
+          Integer _key = category.getKey();
+          final Function1<Map.Entry<Integer, String>, Boolean> _function_1 = (Map.Entry<Integer, String> code) -> {
+            return Boolean.valueOf(catCode.equals(code.getValue()));
+          };
+          Integer _key_1 = IterableExtensions.<Map.Entry<Integer, String>>findFirst(codes.entrySet(), _function_1).getKey();
+          int _plus = ((_key_1).intValue() + 1000);
+          return this.createLink(_key, Integer.valueOf(_plus));
+        };
+        _xblockexpression = IterableExtensions.join(ListExtensions.<String, CharSequence>map(categoryCodes, _function), ",\n");
+      }
+      return _xblockexpression;
+    } catch (Throwable _e) {
+      throw Exceptions.sneakyThrow(_e);
+    }
+  }
+  
+  private CharSequence createLink(final Integer left, final Integer right) {
+    StringConcatenation _builder = new StringConcatenation();
+    _builder.append("{ from: ");
+    _builder.append(left);
+    _builder.append(", to: ");
+    _builder.append(right);
+    _builder.append(" }");
+    return _builder;
+  }
+}