/**
   * Ctor.
   *
   * @param revisionEventTypeName name
   * @param spec specification
   * @param statementStopService for stop handling
   * @param eventAdapterService for nested property handling
   */
  public VAERevisionProcessorDeclared(
      String revisionEventTypeName,
      RevisionSpec spec,
      StatementStopService statementStopService,
      EventAdapterService eventAdapterService,
      EventTypeIdGenerator eventTypeIdGenerator) {
    super(spec, revisionEventTypeName, eventAdapterService);

    // on statement stop, remove versions
    statementStopService.addSubscriber(
        new StatementStopCallback() {
          public void statementStopped() {
            statePerKey.clear();
          }
        });

    this.statePerKey = new HashMap<MultiKeyUntyped, RevisionStateDeclared>();
    this.baseEventType = spec.getBaseEventType();
    this.fullKeyGetters = PropertyUtility.getGetters(baseEventType, spec.getKeyPropertyNames());

    // sort non-key properties, removing keys
    groups =
        PropertyUtility.analyzeGroups(
            spec.getChangesetPropertyNames(), spec.getDeltaTypes(), spec.getDeltaNames());
    Map<String, RevisionPropertyTypeDesc> propertyDesc = createPropertyDescriptors(spec, groups);

    typeDescriptors =
        PropertyUtility.getPerType(
            groups, spec.getChangesetPropertyNames(), spec.getKeyPropertyNames());
    EventTypeMetadata metadata =
        EventTypeMetadata.createValueAdd(
            revisionEventTypeName, EventTypeMetadata.TypeClass.REVISION);
    revisionEventType =
        new RevisionEventType(
            metadata,
            eventTypeIdGenerator.getTypeId(revisionEventTypeName),
            propertyDesc,
            eventAdapterService);
  }