docs: private static void checkBoundaryEventCompensationHandler(Association association, Node source, Node target) { 
          // check that 
          // - event node is boundary event node
          if( ! (source instanceof BoundaryEventNode) ) { 
              throw new IllegalArgumentException("(Compensation) activities may only be associated with Boundary Event Nodes (not with" +
              		source.getClass().getSimpleName() + " nodes [node " + ((String) source.getMetaData().get("UniqueId")) + "].");
          }
          BoundaryEventNode eventNode = (BoundaryEventNode) source;
          
          // - event node has compensationEvent
          List<EventFilter> eventFilters = eventNode.getEventFilters();
          boolean compensationCheckPassed = false;
          if( eventFilters != null) { 
              for( EventFilter filter : eventFilters ) { 
                  if( filter instanceof EventTypeFilter ) { 
                      String type = ((EventTypeFilter) filter).getType();
                      if( type != null && type.equals("Compensation") ) { 
                          compensationCheckPassed = true;
                      }
                  }
              }
          }
          
          if( ! compensationCheckPassed ) { 
              throw new IllegalArgumentException("An Event [" + ((String) eventNode.getMetaData("UniqueId")) 
                      + "] linked from an association [" + association.getId() 
                      + "] must be a (Boundary) Compensation Event.");
          }
          
          // - boundary event node is attached to the correct type of node? 
          /**
           * Tasks: 
           * business: RuleSetNode
           * manual: WorkItemNode
           * receive: WorkItemNode
           * script: ActionNode
           * send: WorkItemNode
           * service: WorkItemNode
           * task: WorkItemNode
           * user: HumanTaskNode
           */
          String attachedToId = eventNode.getAttachedToNodeId();
          Node attachedToNode = null;
          for( Node node : eventNode.getNodeContainer().getNodes() ) { 
              if( attachedToId.equals(node.getMetaData().get("UniqueId")) ) { 
                  attachedToNode = node;
                  break;
              }
          }
          if( attachedToNode == null ) { 
              throw new IllegalArgumentException("Boundary Event [" + ((String) eventNode.getMetaData("UniqueId")) 
                      + "] is not attached to a node [" + attachedToId + "] that can be found.");
          }
          if( !( attachedToNode instanceof RuleSetNode
                  || attachedToNode instanceof WorkItemNode 
                  || attachedToNode instanceof ActionNode
                  || attachedToNode instanceof HumanTaskNode
                  || attachedToNode instanceof CompositeNode
                  || attachedToNode instanceof SubProcessNode) ) { 
              throw new IllegalArgumentException("Compensation Boundary Event [" + ((String) eventNode.getMetaData("UniqueId")) 
                      + "] must be attached to a task or sub-process.");
          }
          
          // - associated node is a task or subProcess
          compensationCheckPassed = false;
          if( target instanceof WorkItemNode || target instanceof HumanTaskNode 
                  || target instanceof CompositeContextNode || target instanceof SubProcessNode ) { 
              compensationCheckPassed = true;
          } else if( target instanceof ActionNode ) { 
              Object nodeTypeObj = ((ActionNode) target).getMetaData("NodeType");
              if( nodeTypeObj != null && nodeTypeObj.equals("ScriptTask") ) { 
                  compensationCheckPassed = true;
              }
          }
          if( ! compensationCheckPassed ) { 
              throw new IllegalArgumentException("An Activity [" 
                      + ((String) ((NodeImpl)target).getMetaData("UniqueId")) +
                      "] associated with a Boundary Compensation Event must be a Task or a (non-Event) Sub-Process");
          }
          
          // - associated node does not have outgoingConnections of it's own
          compensationCheckPassed = true;
          NodeImpl targetNode = (NodeImpl) target;
          Map<String, List<org.kie.api.definition.process.Connection>> connectionsMap = targetNode.getOutgoingConnections();
          ConnectionImpl outgoingConnection = null;
          for( String connectionType : connectionsMap.keySet() ) { 
             List<org.kie.api.definition.process.Connection> connections = connectionsMap.get(connectionType); 
             if( connections != null && ! connections.isEmpty() ) { 
                for( org.kie.api.definition.process.Connection connection : connections ) { 
                   Object hiddenObj = connection.getMetaData().get("hidden");
                   if( hiddenObj != null && ((Boolean) hiddenObj) ) { 
                       continue;
                   }
                   outgoingConnection = (ConnectionImpl) connection;
                   compensationCheckPassed = false;
                   break;
                }
             }
          }
          if( ! compensationCheckPassed ) { 
              throw new IllegalArgumentException("A Compensation Activity [" 
                      + ((String) targetNode.getMetaData("UniqueId")) 
                      + "] may not have any outgoing connection [" 
                      + (String) outgoingConnection.getMetaData("UniqueId") + "]");
          }
      }