Version 7.1.7 ============= Patch release: **OCL parser fixes + IMG2UML merge-into-existing-model**. Closes #198, #202, and #338. No metamodel or public API changes — the OCL work is a grammar fix plus a diagnostics layer, and the IMG2UML change adds an optional parameter while preserving the original behaviour when the active diagram is empty. Highlights ---------- - **OCL accepts attributes named ``size`` (closes #198)**: ``size`` is a reserved lexer keyword for the OCL ``->size()`` / ``.size()`` collection operation, so any domain model with an attribute literally named ``size`` failed to parse with ``mismatched input '>' expecting '('`` — the lexer tokenized the attribute name as ``SIZE`` and the parser insisted on ``LPAREN RPAREN`` after it. The reporter blamed inheritance because their repro had ``size`` on a parent class, but the bug fired identically on a direct attribute. Grammar fix: ``expression DOT SIZE #dotSizeNavigation`` added as a fallback rule below the existing ``DOT SIZE LPAREN RPAREN``. ANTLR's longest-match keeps ``.size()`` winning when parens follow, so ``collection->size()`` and ``string.size()`` still parse unchanged. The visitor gains ``visitDotSizeNavigation`` that resolves ``size`` via the same property-lookup path as ``visitDotNavigation``. Seven regression tests in ``tests/BUML/metamodel/ocl/test_size_attribute.py``. - **OCL parser emits actionable error messages (closes #202)**: the raw ANTLR diagnostics (``mismatched input 'then' expecting ``, ``missing ')' at ''``) exposed internal parser state and used token names that mean little to someone writing an OCL constraint. The worst example from the issue — forgetting the ``if`` before ``then ... else ...`` — surfaced as ``Error: pop from empty list``, which gives zero hint about what went wrong. ``besser/BUML/notations/ocl/error_handling.py`` now sits on top of ANTLR's error listener and rewrites diagnostics into OCL-level hints: ``Did you forget the 'if'?``, ``Missing 'endif'``, ``Missing closing ')'``, ``operand on the right is missing``, ``must start with 'context inv: ...'``, and so on. When no targeted pattern matches, the raw ANTLR message is kept as a fallback but reformatted into a consistent ``line N, column M: `` shape. Thirteen regression tests in ``tests/BUML/metamodel/ocl/test_error_messages.py`` pin every rewrite rule plus positive-parse sanity checks so the translation layer doesn't reject valid OCL. - **IMG2UML extends an existing class diagram instead of replacing it (closes #338)**: when an image is uploaded while the active ClassDiagram already has elements, the image is now merged into the current model — same-name classes are preserved and only new attributes/methods/relationships from the image are appended, new classes are added with their own relationships. ``image_to_buml`` and ``image_to_plantuml`` gain an optional ``existing_model`` parameter; when supplied, a compact textual summary of the current classes, attributes, methods, associations and inheritance is included in the vision prompt with explicit merge rules so the LLM returns a single merged PlantUML chunk. ``/get-json-model-from-image`` carries an optional ``existing_model`` form field with the current diagram JSON, converted via ``process_class_diagram`` and forwarded down. The frontend submodule only sends the active ClassDiagram when it is non-empty, so empty-diagram imports keep the original "replace" behaviour. Testing ------- Twenty new OCL tests (seven for the ``size`` keyword fix, thirteen for the error-message rewrites) cover every targeted pattern plus positive-parse guards. Full suite: **712 passed, 5 skipped, 3 xfailed** — no regressions against v7.1.6.