@SuppressWarnings("unchecked")
  private void index(
      Object entity,
      Session session,
      InstanceInitializer sessionInitializer,
      ConversionContext conversionContext)
      throws InterruptedException {

    // abort if the thread has been interrupted while not in wait(), I/O or similar which themselves
    // would have
    // raised the InterruptedException
    if (Thread.currentThread().isInterrupted()) {
      throw new InterruptedException();
    }

    Serializable id = session.getIdentifier(entity);
    Class<?> clazz = HibernateHelper.getClass(entity);
    EntityIndexBinding entityIndexBinding = entityIndexBindings.get(clazz);
    if (entityIndexBinding == null) {
      // it might be possible to receive not-indexes subclasses of the currently indexed type;
      // being not-indexed, we skip them.
      // FIXME for improved performance: avoid loading them in an early phase.
      return;
    }

    EntityIndexingInterceptor interceptor = entityIndexBinding.getEntityIndexingInterceptor();
    if (interceptor != null) {
      IndexingOverride onAdd = interceptor.onAdd(entity);
      switch (onAdd) {
        case REMOVE:
        case SKIP:
          return;
      }
      // default: continue indexing this instance
    }

    DocumentBuilderIndexedEntity docBuilder = entityIndexBinding.getDocumentBuilder();
    TwoWayFieldBridge idBridge = docBuilder.getIdBridge();
    conversionContext.pushProperty(docBuilder.getIdKeywordName());
    String idInString = null;
    try {
      idInString =
          conversionContext.setClass(clazz).twoWayConversionContext(idBridge).objectToString(id);
    } finally {
      conversionContext.popProperty();
    }
    // depending on the complexity of the object graph going to be indexed it's possible
    // that we hit the database several times during work construction.
    AddLuceneWork addWork =
        docBuilder.createAddWork(
            tenantId, clazz, entity, id, idInString, sessionInitializer, conversionContext);
    backend.enqueueAsyncWork(addWork);
  }
 private Work interceptWork(EntityIndexBinding indexBindingForEntity, Work work) {
   if (indexBindingForEntity == null) {
     return work;
   }
   EntityIndexingInterceptor interceptor = indexBindingForEntity.getEntityIndexingInterceptor();
   if (interceptor == null) {
     return work;
   }
   IndexingOverride operation;
   switch (work.getType()) {
     case ADD:
       operation = interceptor.onAdd(work.getEntity());
       break;
     case UPDATE:
       operation = interceptor.onUpdate(work.getEntity());
       break;
     case DELETE:
       operation = interceptor.onDelete(work.getEntity());
       break;
     case COLLECTION:
       operation = interceptor.onCollectionUpdate(work.getEntity());
       break;
     case PURGE:
     case PURGE_ALL:
     case INDEX:
     case DELETE_BY_QUERY:
       operation = IndexingOverride.APPLY_DEFAULT;
       break;
     default:
       throw new AssertionFailure("Unknown work type: " + work.getType());
   }
   Work result = work;
   Class<?> entityClass = work.getEntityClass();
   switch (operation) {
     case APPLY_DEFAULT:
       break;
     case SKIP:
       result = null;
       log.forceSkipIndexOperationViaInterception(entityClass, work.getType());
       break;
     case UPDATE:
       result =
           new Work(work.getTenantIdentifier(), work.getEntity(), work.getId(), WorkType.UPDATE);
       log.forceUpdateOnIndexOperationViaInterception(entityClass, work.getType());
       break;
     case REMOVE:
       // This works because other Work constructors are never used from WorkType ADD, UPDATE,
       // REMOVE, COLLECTION
       // TODO should we force isIdentifierRollback to false if the operation is not a delete?
       result =
           new Work(
               work.getTenantIdentifier(),
               work.getEntity(),
               work.getId(),
               WorkType.DELETE,
               work.isIdentifierWasRolledBack());
       log.forceRemoveOnIndexOperationViaInterception(entityClass, work.getType());
       break;
     default:
       throw new AssertionFailure("Unknown action type: " + operation);
   }
   return result;
 }