/**
   * Fixes the VPM after the refactoring has been carried out. This is necessary because the
   * elements referenced by the VPM might have been replaced during the refactoring. This leads to
   * dangling references and an invalid VPM. Fixing is done by applying the recorded changes.
   * Changes are recorded by the protected helper methods of this class.
   *
   * @param variationPoint The variation point to fix.
   */
  private void fixVPMAfterRefactoring(VariationPoint variationPoint) {

    /**
     * The information we collect: - Replacements between an original and a replacement - Newly
     * created elements corresponding to a specific variant
     *
     * <p>What we do: - calculate the transitive closure of replacements to become independent from
     * execution order - partition the stored replacements in replacements that - A: shall be
     * applied - B: are already contained by a newly created element - Apply A - Delete B from the
     * variation point (as it is already included in a newly created element) - Add the newly
     * created elements to the VPM
     */
    Map<EObject, EObject> replacementsClosure = calculateTransitiveClosure(replacements);

    PartitionedReplacements partitionedReplacements =
        partitionReplacements(replacementsClosure, variantSpecificelements);

    for (Map.Entry<EObject, EObject> replacement : partitionedReplacements.getApply()) {
      executeReplacement(replacement, variationPoint);
    }

    for (Map.Entry<EObject, EObject> replacement : partitionedReplacements.getDelete()) {
      LOGGER.debug(String.format("Removing %s from VP.", replacement.getKey()));
      removeSoftwareElement(replacement.getKey(), variationPoint);
    }

    for (Map.Entry<String, Set<EObject>> variantSpecifics : variantSpecificelements.entrySet()) {
      final String variantId = variantSpecifics.getKey();
      Variant variant =
          Iterables.find(
              variationPoint.getVariants(),
              new Predicate<Variant>() {
                @Override
                public boolean apply(Variant arg0) {
                  return variantId.equals(arg0.getId());
                }
              });
      if (variant == null) {
        LOGGER.warn(
            "Elements have been registered to the invalid variant ID "
                + variantId
                + ". Ignoring the entries.");
        continue;
      }

      for (EObject eobject : variantSpecifics.getValue()) {
        SoftwareElement swElement = createSoftwareElement(eobject);
        if (swElement == null) {
          LOGGER.warn(
              "We were unable to create a SoftwareElement for the EObject " + eobject + ".");
        }
        variant.getImplementingElements().add(swElement);
      }
    }
  }
 private void removeSoftwareElement(EObject eobject, VariationPoint variationPoint) {
   for (Variant variant : variationPoint.getVariants()) {
     Iterator<SoftwareElement> swElementIterator = variant.getImplementingElements().iterator();
     while (swElementIterator.hasNext()) {
       if (swElementIterator.next().getWrappedElement() == eobject) {
         swElementIterator.remove();
         return;
       }
     }
   }
 }