diff --git a/model_diffsummary/__main__.py b/model_diffsummary/__main__.py
index 71b00d4..d2c8bc5 100644
--- a/model_diffsummary/__main__.py
+++ b/model_diffsummary/__main__.py
@@ -4,10 +4,12 @@
 from __future__ import annotations
 
 import logging
+import pathlib
 import typing as t
 
 import capellambse
 import click
+import yaml
 from capellambse import model as m
 from capellambse.model import common as c
 
@@ -34,9 +36,119 @@ def main(model: dict[str, t.Any], old_version: str, new_version: str):
     old_model = capellambse.MelodyModel(**model, revision=old_version)
     new_model = capellambse.MelodyModel(**model, revision=new_version)
 
-    result = _compare_all_objects(old_model, new_model)
+    metadata = {
+        "model": model["path"],
+        "old-revision": old_version,
+        "new-revision": new_version,
+    }
+    diagrams = _compare_all_diagrams(old_model, new_model)
 
-    print(result)
+    objects = _compare_all_objects(old_model, new_model)
+
+    result = {"metadata": metadata, "diagrams": diagrams, "objects": objects}
+
+    # pathlib.Path("test.yaml").write_text(yaml.dump(result), encoding="utf8")
+
+
+def _compare_all_diagrams(
+    old: capellambse.MelodyModel, new: capellambse.MelodyModel
+) -> t.Any:
+    result: t.Any = {"oa": {}, "la": {}, "pa": {}, "sa": {}}
+    for layer, diagtype in (
+        ("oa", m.modeltypes.DiagramType.COC),
+        ("oa", m.modeltypes.DiagramType.OAIB),
+        ("oa", m.modeltypes.DiagramType.OPD),
+        ("oa", m.modeltypes.DiagramType.OAB),
+        ("sa", m.modeltypes.DiagramType.CC),
+        ("sa", m.modeltypes.DiagramType.SDFB),
+        ("sa", m.modeltypes.DiagramType.MCB),
+        ("sa", m.modeltypes.DiagramType.SAB),
+    ):
+        type_result = _compare_diagram_type(old, new, layer, diagtype)
+        result[layer][diagtype.name] = type_result
+    return result
+
+
+def _compare_diagram_type(
+    old: capellambse.MelodyModel,
+    new: capellambse.MelodyModel,
+    layer: str,
+    diag_type: m.modeltypes.DiagramType,
+) -> t.Any:
+    logging.debug("Collecting diagrams of type %s", diag_type.name)
+    changes = {}
+
+    old_diags = getattr(old, layer).diagrams.by_type(diag_type)
+    new_diags = getattr(new, layer).diagrams.by_type(diag_type)
+
+    old_uuids = {i.uuid for i in old_diags}
+    new_uuids = {i.uuid for i in new_diags}
+
+    if created_uuids := new_uuids - old_uuids:
+        changes["created"] = [new_diags.by_uuid(i).name for i in created_uuids]
+    if deleted_uuids := old_uuids - new_uuids:
+        changes["deleted"] = [old_diags.by_uuid(i).name for i in deleted_uuids]
+
+    # for i in old_uuids & new_uuids:
+    #     if diff := _diag2diff(old_diags.by_uuid(i), new_diags.by_uuid(i)):
+    #         changes.setdefault("modified", []).append(diff)
+    return changes
+
+
+def _diag2diff(
+    old: m.diagram.Diagram, new: m.diagram.Diagram
+) -> dict[str, t.Any] | None:
+    """Serialize the differences between the old and new diagram.
+
+    This function is used for diagrams that were modified. Newly
+    introduced elements and removed elements are serialized.
+
+    The new (current) *display-name* is always serialized. If it didn't
+    change, it will not have the "previous" key.
+
+    The *layout_changes* flag indicates that the diagram has changed
+    positions, sizes or bendpoints for exchanges.
+    """
+    changes: t.Any = {}
+
+    old_uuids = set(old.nodes.by_uuid)
+    new_uuids = set(new.nodes.by_uuid)
+
+    if created_uuids := new_uuids - old_uuids:
+        changes["introduced"] = [
+            _diagelt2dict(new.nodes.by_uuid(i)) for i in created_uuids
+        ]
+    if deleted_uuids := old_uuids - new_uuids:
+        changes["removed"] = [
+            _diagelt2dict(old.nodes.by_uuid(i)) for i in deleted_uuids
+        ]
+
+    old_diag = old.render(None)
+    new_diag = new.render(None)
+    changes["layout_changes"] = False
+    for i in old_uuids & new_uuids:
+        if _diagelt2diff(old_diag[i], new_diag[i]):
+            changes["layout_changes"] = True
+    return changes
+
+
+def _diagelt2dict(obj: c.GenericElement) -> dict[str, t.Any]:
+    """Serialize a diagram element into a dict.
+
+    This function is used for diagram elements that were either
+    introduced or deleted, in which case the id and the name are
+    serialized.
+    """
+    result = _obj2dict(obj)
+    return {"id": result["id"], "name": result.get("name")}
+
+
+def _diagelt2diff(
+    old: capellambse.diagram.DiagramElement,
+    new: capellambse.diagram.DiagramElement,
+) -> dict[str, t.Any]:
+    # TODO
+    return {}
 
 
 def _compare_all_objects(
@@ -78,6 +190,7 @@ def _compare_object_type(
     for i in old_uuids & new_uuids:
         if diff := _obj2diff(old.by_uuid(i), new.by_uuid(i)):
             changes.setdefault("modified", []).append(diff)
+    return changes
 
 
 def _obj2dict(obj: c.GenericElement) -> dict[str, t.Any]: