@Override
  public void remove(Partition partition) throws IdentityManagementException {
    checkPartitionManagementSupported();
    checkIfPartitionExists(partition);

    try {
      IdentityContext context = createIdentityContext();

      AttributeStore<?> attributeStore = getStoreForAttributeOperation(context);

      if (attributeStore != null) {
        Partition storedType = lookupById(partition.getClass(), partition.getId());

        IdentityManager identityManager = createIdentityManager(storedType);
        IdentityQuery<IdentityType> query = identityManager.createIdentityQuery(IdentityType.class);

        for (IdentityType identityType : query.getResultList()) {
          identityManager.remove(identityType);
        }

        for (Attribute<? extends Serializable> attribute : storedType.getAttributes()) {
          attributeStore.removeAttribute(context, storedType, attribute.getName());
        }
      }

      getStoreForPartitionOperation(context).remove(context, partition);
    } catch (Exception e) {
      throw MESSAGES.partitionRemoveFailed(partition, e);
    }
  }
  @Override
  public void add(Partition partition, String configurationName)
      throws IdentityManagementException {
    checkPartitionManagementSupported();

    if (partition == null) {
      throw MESSAGES.nullArgument("Partition");
    }

    if (isNullOrEmpty(configurationName)) {
      configurationName = getDefaultConfigurationName();
    }

    if (getConfigurationByName(configurationName) != null) {
      if (getPartition(partition.getClass(), partition.getName()) != null) {
        throw MESSAGES.partitionAlreadyExistsWithName(partition.getClass(), partition.getName());
      }

      try {
        IdentityContext context = createIdentityContext();

        getStoreForPartitionOperation(context).add(context, partition, configurationName);

        AttributeStore<?> attributeStore = getStoreForAttributeOperation(context);

        if (attributeStore != null) {
          for (Attribute<? extends Serializable> attribute : partition.getAttributes()) {
            attributeStore.setAttribute(context, partition, attribute);
          }
        }
      } catch (Exception e) {
        throw MESSAGES.partitionAddFailed(partition, configurationName, e);
      }
    }
  }
  @Override
  public void update(Partition partition) throws IdentityManagementException {
    checkPartitionManagementSupported();
    checkIfPartitionExists(partition);

    try {
      IdentityContext context = createIdentityContext();
      getStoreForPartitionOperation(context).update(context, partition);

      AttributeStore<?> attributeStore = getStoreForAttributeOperation(context);

      if (attributeStore != null) {
        Partition storedType = lookupById(partition.getClass(), partition.getId());

        for (Attribute<? extends Serializable> attribute : storedType.getAttributes()) {
          if (partition.getAttribute(attribute.getName()) == null) {
            attributeStore.removeAttribute(context, partition, attribute.getName());
          }
        }

        for (Attribute<? extends Serializable> attribute : partition.getAttributes()) {
          attributeStore.setAttribute(context, partition, attribute);
        }
      }
    } catch (Exception e) {
      throw MESSAGES.partitionUpdateFailed(partition, e);
    }
  }
  private <T extends Partition> void loadAttributes(
      final IdentityContext context, final T partition) {
    AttributeStore<?> attributeStore = getStoreForAttributeOperation(context);

    if (attributeStore != null) {
      attributeStore.loadAttributes(context, partition);
    }
  }