@Override
  public void remove(PersistencePackage persistencePackage) throws ServiceException {
    String[] customCriteria = persistencePackage.getCustomCriteria();
    if (customCriteria != null && customCriteria.length > 0) {
      LOG.warn(
          "custom persistence handlers and custom criteria not supported for remove types other than BASIC");
    }
    PersistencePerspective persistencePerspective = persistencePackage.getPersistencePerspective();
    Entity entity = persistencePackage.getEntity();
    try {
      AdornedTargetList adornedTargetList =
          (AdornedTargetList)
              persistencePerspective
                  .getPersistencePerspectiveItems()
                  .get(PersistencePerspectiveItemType.ADORNEDTARGETLIST);
      Class<?>[] entities =
          persistenceManager.getPolymorphicEntities(
              adornedTargetList.getAdornedTargetEntityClassname());
      Map<String, FieldMetadata> mergedProperties =
          persistenceManager
              .getDynamicEntityDao()
              .getMergedProperties(
                  adornedTargetList.getAdornedTargetEntityClassname(),
                  entities,
                  null,
                  new String[] {},
                  new ForeignKey[] {},
                  MergedPropertyType.ADORNEDTARGETLIST,
                  false,
                  new String[] {},
                  new String[] {},
                  null,
                  "");
      CriteriaTransferObject ctoInserted = new CriteriaTransferObject();
      FilterAndSortCriteria filterCriteriaInsertedLinked =
          ctoInserted.get(adornedTargetList.getCollectionFieldName());
      filterCriteriaInsertedLinked.setFilterValue(
          entity
              .findProperty(
                  adornedTargetList.getLinkedObjectPath()
                      + "."
                      + adornedTargetList.getLinkedIdProperty())
              .getValue());
      FilterAndSortCriteria filterCriteriaInsertedTarget =
          ctoInserted.get(adornedTargetList.getCollectionFieldName() + "Target");
      filterCriteriaInsertedTarget.setFilterValue(
          entity
              .findProperty(
                  adornedTargetList.getTargetObjectPath()
                      + "."
                      + adornedTargetList.getTargetIdProperty())
              .getValue());
      BaseCtoConverter ctoConverterInserted =
          getAdornedTargetCtoConverter(
              persistencePerspective, ctoInserted, mergedProperties, adornedTargetList);
      PersistentEntityCriteria queryCriteriaInserted =
          ctoConverterInserted.convert(
              ctoInserted, adornedTargetList.getAdornedTargetEntityClassname());
      List<Serializable> recordsInserted =
          persistenceManager
              .getDynamicEntityDao()
              .query(
                  queryCriteriaInserted,
                  Class.forName(adornedTargetList.getAdornedTargetEntityClassname()));

      persistenceManager.getDynamicEntityDao().remove(recordsInserted.get(0));
    } catch (Exception e) {
      LOG.error("Problem removing entity", e);
      throw new ServiceException("Problem removing entity : " + e.getMessage(), e);
    }
  }
    public AdornedTargetRetrieval invoke()
        throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException,
            InvocationTargetException, FieldNotAvailableException, NoSuchFieldException {
      CriteriaTransferObject cto = new CriteriaTransferObject();
      FilterAndSortCriteria filterCriteria = cto.get(adornedTargetList.getCollectionFieldName());
      filterCriteria.setFilterValue(
          entity
              .findProperty(
                  adornedTargetList.getLinkedObjectPath()
                      + "."
                      + adornedTargetList.getLinkedIdProperty())
              .getValue());
      if (adornedTargetList.getSortField() != null) {
        FilterAndSortCriteria sortCriteria = cto.get(adornedTargetList.getSortField());
        sortCriteria.setSortAscending(adornedTargetList.getSortAscending());
      }

      Class<?>[] entities2 =
          persistenceManager.getPolymorphicEntities(
              adornedTargetList.getAdornedTargetEntityClassname());
      mergedProperties =
          persistenceManager
              .getDynamicEntityDao()
              .getMergedProperties(
                  adornedTargetList.getAdornedTargetEntityClassname(),
                  entities2,
                  null,
                  new String[] {},
                  new ForeignKey[] {},
                  MergedPropertyType.ADORNEDTARGETLIST,
                  persistencePerspective.getPopulateToOneFields(),
                  persistencePerspective.getIncludeFields(),
                  persistencePerspective.getExcludeFields(),
                  persistencePerspective.getConfigurationKey(),
                  "");
      BaseCtoConverter ctoConverter =
          getAdornedTargetCtoConverter(
              persistencePerspective, cto, mergedProperties, adornedTargetList);
      PersistentEntityCriteria queryCriteria =
          ctoConverter.convert(cto, adornedTargetList.getAdornedTargetEntityClassname());
      records =
          persistenceManager
              .getDynamicEntityDao()
              .query(
                  queryCriteria,
                  Class.forName(adornedTargetList.getAdornedTargetEntityClassname()));

      index = 0;
      Long myEntityId =
          Long.valueOf(
              entity
                  .findProperty(
                      adornedTargetList.getTargetObjectPath()
                          + "."
                          + adornedTargetList.getTargetIdProperty())
                  .getValue());
      FieldManager fieldManager = getFieldManager();
      for (Serializable record : records) {
        Long targetId =
            (Long)
                fieldManager.getFieldValue(
                    record,
                    adornedTargetList.getTargetObjectPath()
                        + "."
                        + adornedTargetList.getTargetIdProperty());
        if (myEntityId.equals(targetId)) {
          break;
        }
        index++;
      }
      return this;
    }
  @Override
  public Entity add(PersistencePackage persistencePackage) throws ServiceException {
    String[] customCriteria = persistencePackage.getCustomCriteria();
    if (customCriteria != null && customCriteria.length > 0) {
      LOG.warn(
          "custom persistence handlers and custom criteria not supported for add types other than BASIC");
    }
    PersistencePerspective persistencePerspective = persistencePackage.getPersistencePerspective();
    String ceilingEntityFullyQualifiedClassname =
        persistencePackage.getCeilingEntityFullyQualifiedClassname();
    Entity entity = persistencePackage.getEntity();
    AdornedTargetList adornedTargetList =
        (AdornedTargetList)
            persistencePerspective
                .getPersistencePerspectiveItems()
                .get(PersistencePerspectiveItemType.ADORNEDTARGETLIST);
    Entity payload;
    try {
      Class<?>[] entities =
          persistenceManager.getPolymorphicEntities(ceilingEntityFullyQualifiedClassname);
      Map<String, FieldMetadata> mergedPropertiesTarget =
          persistenceManager
              .getDynamicEntityDao()
              .getMergedProperties(
                  ceilingEntityFullyQualifiedClassname,
                  entities,
                  null,
                  persistencePerspective.getAdditionalNonPersistentProperties(),
                  persistencePerspective.getAdditionalForeignKeys(),
                  MergedPropertyType.PRIMARY,
                  persistencePerspective.getPopulateToOneFields(),
                  persistencePerspective.getIncludeFields(),
                  persistencePerspective.getExcludeFields(),
                  persistencePerspective.getConfigurationKey(),
                  "");
      Class<?>[] entities2 =
          persistenceManager.getPolymorphicEntities(
              adornedTargetList.getAdornedTargetEntityClassname());
      Map<String, FieldMetadata> mergedProperties =
          persistenceManager
              .getDynamicEntityDao()
              .getMergedProperties(
                  adornedTargetList.getAdornedTargetEntityClassname(),
                  entities2,
                  null,
                  new String[] {},
                  new ForeignKey[] {},
                  MergedPropertyType.ADORNEDTARGETLIST,
                  false,
                  new String[] {},
                  new String[] {},
                  null,
                  "");

      CriteriaTransferObject ctoInserted = new CriteriaTransferObject();
      FilterAndSortCriteria filterCriteriaInsertedLinked =
          ctoInserted.get(adornedTargetList.getCollectionFieldName());
      String linkedPath;
      String targetPath;
      if (adornedTargetList.getInverse()) {
        linkedPath =
            adornedTargetList.getTargetObjectPath() + "." + adornedTargetList.getTargetIdProperty();
        targetPath =
            adornedTargetList.getLinkedObjectPath() + "." + adornedTargetList.getLinkedIdProperty();
      } else {
        targetPath =
            adornedTargetList.getTargetObjectPath() + "." + adornedTargetList.getTargetIdProperty();
        linkedPath =
            adornedTargetList.getLinkedObjectPath() + "." + adornedTargetList.getLinkedIdProperty();
      }
      filterCriteriaInsertedLinked.setFilterValue(
          entity.findProperty(adornedTargetList.getInverse() ? targetPath : linkedPath).getValue());
      FilterAndSortCriteria filterCriteriaInsertedTarget =
          ctoInserted.get(adornedTargetList.getCollectionFieldName() + "Target");
      filterCriteriaInsertedTarget.setFilterValue(
          entity.findProperty(adornedTargetList.getInverse() ? linkedPath : targetPath).getValue());
      BaseCtoConverter ctoConverterInserted =
          getAdornedTargetCtoConverter(
              persistencePerspective, ctoInserted, mergedProperties, adornedTargetList);
      PersistentEntityCriteria queryCriteriaInserted =
          ctoConverterInserted.convert(
              ctoInserted, adornedTargetList.getAdornedTargetEntityClassname());
      List<Serializable> recordsInserted =
          persistenceManager
              .getDynamicEntityDao()
              .query(
                  queryCriteriaInserted,
                  Class.forName(adornedTargetList.getAdornedTargetEntityClassname()));
      if (recordsInserted.size() > 0) {
        payload =
            getRecords(
                mergedPropertiesTarget,
                recordsInserted,
                mergedProperties,
                adornedTargetList.getTargetObjectPath())[0];
      } else {
        Serializable instance = createPopulatedAdornedTargetInstance(adornedTargetList, entity);
        instance = createPopulatedInstance(instance, entity, mergedProperties, false);
        instance = createPopulatedInstance(instance, entity, mergedPropertiesTarget, false);
        FieldManager fieldManager = getFieldManager();
        if (fieldManager.getField(instance.getClass(), "id") != null) {
          fieldManager.setFieldValue(instance, "id", null);
        }
        if (adornedTargetList.getSortField() != null) {
          CriteriaTransferObject cto = new CriteriaTransferObject();
          FilterAndSortCriteria filterCriteria =
              cto.get(adornedTargetList.getCollectionFieldName());
          filterCriteria.setFilterValue(
              entity
                  .findProperty(adornedTargetList.getInverse() ? targetPath : linkedPath)
                  .getValue());
          FilterAndSortCriteria sortCriteria = cto.get(adornedTargetList.getSortField());
          sortCriteria.setSortAscending(adornedTargetList.getSortAscending());
          BaseCtoConverter ctoConverter =
              getAdornedTargetCtoConverter(
                  persistencePerspective, cto, mergedProperties, adornedTargetList);
          int totalRecords = getTotalRecords(persistencePackage, cto, ctoConverter);
          fieldManager.setFieldValue(
              instance, adornedTargetList.getSortField(), Long.valueOf(totalRecords + 1));
        }
        instance = persistenceManager.getDynamicEntityDao().merge(instance);
        persistenceManager.getDynamicEntityDao().flush();
        persistenceManager.getDynamicEntityDao().clear();

        List<Serializable> recordsInserted2 =
            persistenceManager
                .getDynamicEntityDao()
                .query(
                    queryCriteriaInserted,
                    Class.forName(adornedTargetList.getAdornedTargetEntityClassname()));

        payload =
            getRecords(
                mergedPropertiesTarget,
                recordsInserted2,
                mergedProperties,
                adornedTargetList.getTargetObjectPath())[0];
      }
    } catch (Exception e) {
      LOG.error("Problem editing entity", e);
      throw new ServiceException("Problem adding new entity : " + e.getMessage(), e);
    }

    return payload;
  }