diff --git a/result_parser.py b/result_parser.py
index 9fb41fab3feadf926986e80b853f0904d0c42e96..578cdaed3ddd302828e0c326329c75d7ce8fb9c6 100644
--- a/result_parser.py
+++ b/result_parser.py
@@ -14,7 +14,7 @@ from typing import Literal, Optional, TypedDict, Union, cast
 
 from dateutil.parser import parse as parse_date
 
-from utils import UrlOrPath
+from .utils import UrlOrPath
 
 DETAILS_RE = re.compile(r"(?P<avg>\d+) \(± (?P<var>\d+)\) (?P<unit>\w+)")
 
@@ -55,13 +55,14 @@ class RawMeasurement(TypedDict):
     details: str
 
 
-class RawImageInfo(TypedDict):
-    """A info about an image."""
+class RawImageMetadata(TypedDict):
+    """Metadata about an image."""
 
     image: str
     id: str
     versions: list[str]
     created: Optional[str]
+    compliant: Optional[bool]
 
 
 class RawResult(TypedDict):
@@ -73,7 +74,7 @@ class RawResult(TypedDict):
     servers: list[str]
     clients: list[str]
     urls: dict[str, str]
-    versions: Optional[dict[str, RawImageInfo]]
+    images: Optional[dict[str, RawImageMetadata]]
     tests: dict[str, Union[RawTestDescr, RawMeasurementDescr]]
     quic_draft: int
     quic_version: str
@@ -97,9 +98,27 @@ class Implementation:
     url: str
     role: ImplementationRole
 
+    image: Optional[str] = None
     image_id: Optional[str] = None
-    versions: Optional[list[str]] = None
-    created: Optional[datetime] = None
+    image_versions: Optional[list[str]] = None
+    image_created: Optional[datetime] = None
+    compliant: Optional[bool] = None
+
+    def img_metadata_json(self) -> Optional[RawImageMetadata]:
+        if not self.image or not self.image_id:
+            return None
+
+        return {
+            "image": self.image,
+            "id": self.image_id,
+            "versions": self.image_versions or [],
+            "created": (
+                self.image_created.strftime("%Y-%m-%d %H:%M")
+                if self.image_created
+                else None
+            ),
+            "compliant": self.compliant,
+        }
 
 
 @dataclass(frozen=True)
@@ -374,13 +393,13 @@ class Result:
     def log_dir(self, value: UrlOrPath):
         self.raw_data["log_dir"] = str(value)
 
-    def get_image_info(
+    def get_image_metadata(
         self, impl: Union[str, Implementation]
-    ) -> Union[RawImageInfo, dict]:
-        versions = self.raw_data.get("versions", {}) or {}
+    ) -> Union[RawImageMetadata, dict]:
+        images = self.raw_data.get("images", {}) or {}
         impl_name = impl if isinstance(impl, str) else impl.name
 
-        return versions.get(impl_name, {})
+        return images.get(impl_name, {})
 
     def _update_implementations(
         self, value: list[Implementation], role: ImplementationRole
@@ -388,7 +407,7 @@ class Result:
         assert role != ImplementationRole.BOTH
 
         for impl in value:
-            img_info = self.get_image_info(impl.name)
+            img_info = self.get_image_metadata(impl.name)
 
             if impl.name not in self.raw_data["urls"]:
                 self.raw_data["urls"][impl.name] = impl.url
@@ -429,18 +448,18 @@ class Result:
         )
 
         for name in lookup:
-            versions = self.raw_data.get("versions") or {}
-            img_info = versions.get(name, {})
-            created_raw: Optional[str] = img_info.get("created")
+            img_metadata = self.get_image_metadata(name)
+            created_raw: Optional[str] = img_metadata.get("created")
             created = parse_date(created_raw) if created_raw else None
             ret.append(
                 Implementation(
                     name=name,
                     url=self.raw_data["urls"][name],
                     role=ImplementationRole.BOTH if name in lookup_other else role,
-                    image_id=img_info.get("id"),
-                    versions=img_info.get("versions"),
-                    created=created,
+                    image_id=img_metadata.get("id"),
+                    image_versions=img_metadata.get("versions"),
+                    image_created=created,
+                    compliant=img_metadata.get("compliant"),
                 )
             )
 
@@ -467,10 +486,13 @@ class Result:
         self._update_implementations(value, role=ImplementationRole.CLIENT)
 
     @property
-    def implementations(self) -> frozenset[Implementation]:
-        """Return a list of involved implementations."""
+    def implementations(self) -> dict[str, Implementation]:
+        """Return a mapping of involved implementations."""
 
-        return frozenset(self.servers) | frozenset(self.clients)
+        return {
+            **{impl.name: impl for impl in self.servers},
+            **{impl.name: impl for impl in self.clients},
+        }
 
     @property
     def tests(self) -> dict[str, Union[TestDescription, MeasurmentDescription]]:
@@ -841,10 +863,41 @@ class Result:
                     [test.to_raw() for test in meass_merged[server][client].values()]
                 )
 
-        urls = {
-            **{impl.name: impl.url for impl in self.implementations},
-            **{impl.name: impl.url for impl in other.implementations},
-        }
+        urls = dict[str, str]()
+        images = dict[str, RawImageMetadata]()
+
+        for name, impl in self.implementations.items():
+            own_img_metadata = impl.img_metadata_json()
+            common_img_metadata: Optional[RawImageMetadata] = None
+
+            if name in other.implementations.keys():
+                other_impl = other.implementations[name]
+                assert impl.url == other_impl.url
+                other_img_metadata = other_impl.img_metadata_json()
+
+                if own_img_metadata and other_img_metadata:
+                    assert own_img_metadata == other_img_metadata
+                    common_img_metadata = own_img_metadata
+                elif own_img_metadata and not other_img_metadata:
+                    common_img_metadata = own_img_metadata
+                elif not own_img_metadata and other_img_metadata:
+                    common_img_metadata = other_img_metadata
+            else:
+                common_img_metadata = own_img_metadata
+
+            urls[name] = impl.url
+
+            if common_img_metadata:
+                images[name] = common_img_metadata
+
+        for name, impl in other.implementations.items():
+            if name not in self.implementations.keys():
+                urls[name] = impl.url
+                img_metadata = impl.img_metadata_json()
+
+                if img_metadata:
+                    images[name] = img_metadata
+
         test_descriptions: dict[str, Union[RawTestDescr, RawMeasurementDescr]] = {
             **{abbr: test.to_raw() for abbr, test in self.tests.items()},
             **{abbr: test.to_raw() for abbr, test in other.tests.items()},
@@ -857,6 +910,7 @@ class Result:
             "servers": servers_merged,
             "clients": clients_merged,
             "urls": urls,
+            "images": images,
             "tests": test_descriptions,
             "quic_draft": self.quic_draft,
             "quic_version": hex(other.quic_version),