public PortletContext importPortlet(
      PortletStateType stateType, PortletContext originalPortletContext)
      throws PortletInvokerException, IllegalArgumentException {
    // The original portletcontext is the non cloned version and should be one the PC available from
    // the getPortlets operation
    RegistrationSPI registration = getRegistrationAsSPI();

    if (registration != null) {
      checkOperationIsAllowed(originalPortletContext, registration, "importPortlet");

      PortletContext newPortletContext = super.importPortlet(stateType, originalPortletContext);

      if (!newPortletContext.getId().equals(originalPortletContext.getId())) {
        try {
          registration.addPortletContext(newPortletContext);
        } catch (RegistrationException e) {
          throw new PortletInvokerException(
              "Couldn't add portlet context '"
                  + newPortletContext
                  + "' to registration '"
                  + registration.getRegistrationHandle()
                  + "'",
              e);
        }
      }

      return newPortletContext;
    } else {
      return super.importPortlet(stateType, originalPortletContext);
    }
  }
  public PortletContext setProperties(PortletContext portletContext, PropertyChange[] changes)
      throws IllegalArgumentException, PortletInvokerException, UnsupportedOperationException {
    RegistrationSPI registration = getRegistrationAsSPI();

    if (registration != null) {
      checkOperationIsAllowed(portletContext, registration, "setProperties");
      PortletContext updatedPortletContext = super.setProperties(portletContext, changes);

      if (!portletContext.getId().equals(updatedPortletContext.getId())) {
        try {
          registration.addPortletContext(updatedPortletContext);
        } catch (RegistrationException e) {
          throw new PortletInvokerException(
              "Couldn't add portlet context '"
                  + updatedPortletContext
                  + "' to registration '"
                  + registration.getRegistrationHandle()
                  + "'",
              e);
        }
      }

      return updatedPortletContext;
    } else {
      return super.setProperties(portletContext, changes);
    }
  }
  public PortletContext createClone(PortletStateType stateType, PortletContext portletContext)
      throws IllegalArgumentException, PortletInvokerException, UnsupportedOperationException {
    RegistrationSPI registration = getRegistrationAsSPI();

    if (registration != null) {
      checkOperationIsAllowed(portletContext, registration, "createClone");

      PortletContext clonedPortletContext = super.createClone(stateType, portletContext);
      try {
        registration.addPortletContext(clonedPortletContext);
      } catch (RegistrationException e) {
        throw new PortletInvokerException(
            "Couldn't add portlet context '"
                + clonedPortletContext
                + "' to registration '"
                + registration.getRegistrationHandle()
                + "'",
            e);
      }

      return clonedPortletContext;
    } else {
      return super.createClone(stateType, portletContext);
    }
  }
  public PortletInvocationResponse invoke(PortletInvocation invocation)
      throws IllegalArgumentException, PortletInvokerException {
    PortletContext portletContext = invocation.getTarget();

    RegistrationSPI registration = getRegistrationAsSPI();

    if (registration != null) {
      checkOperationIsAllowed(portletContext, registration, "invoke");

      PortletInvocationResponse response = super.invoke(invocation);

      InstanceContext instanceContext = invocation.getInstanceContext();
      if (instanceContext instanceof WSRPInstanceContext) {
        WSRPInstanceContext wsrpIC = (WSRPInstanceContext) instanceContext;
        PortletContext responseContext = wsrpIC.getPortletContext();
        if (wsrpIC.wasModified() && !responseContext.getId().equals(portletContext.getId())) {
          try {
            registration.addPortletContext(responseContext);
          } catch (RegistrationException e) {
            throw new PortletInvokerException(
                "Couldn't add portlet context '"
                    + responseContext
                    + "' to registration '"
                    + registration.getRegistrationHandle()
                    + "'",
                e);
          }
        }
      }

      return response;
    } else {
      return super.invoke(invocation);
    }
  }
  public Set<Portlet> getPortlets() throws PortletInvokerException {
    Set<Portlet> portlets = new HashSet<Portlet>(super.getPortlets());
    Registration registration = RegistrationLocal.getRegistration();

    if (registration != null) {
      Set<PortletContext> contexts = registration.getKnownPortletContexts();
      for (PortletContext context : contexts) {
        try {
          portlets.add(super.getPortlet(context));
        } catch (NoSuchPortletException e) {
          final RegistrationSPI registrationSPI = getRegistrationAsSPI();
          try {
            registrationSPI.removePortletContext(context);
            log.debug(
                "Removed '"
                    + context
                    + "' from Registration '"
                    + registration.getRegistrationHandle()
                    + "' because it cannot be resolved anymore.");
          } catch (RegistrationException e1) {
            throw new PortletInvokerException(e1);
          }
        }
      }
    }

    return portlets;
  }
  public List<DestroyCloneFailure> destroyClones(List<PortletContext> portletContexts)
      throws IllegalArgumentException, PortletInvokerException, UnsupportedOperationException {
    RegistrationSPI registration = getRegistrationAsSPI();

    if (registration != null) {
      for (PortletContext portletContext : portletContexts) {
        checkOperationIsAllowed(portletContext, registration, "destroyClones");
      }
    }

    List<DestroyCloneFailure> cloneFailures = super.destroyClones(portletContexts);
    boolean noFailures = cloneFailures.isEmpty();

    if (registration != null) {
      for (PortletContext portletContext : portletContexts) {
        // only remove the portlet context if there are no failures or it's not part of the failed
        // clones
        if (noFailures
            || !cloneFailures.contains(new DestroyCloneFailure(portletContext.getId()))) {
          try {
            registration.removePortletContext(portletContext);
          } catch (RegistrationException e) {
            throw new PortletInvokerException(
                "Couldn't remove portlet context '"
                    + portletContext
                    + "' to registration '"
                    + registration.getRegistrationHandle()
                    + "'",
                e);
          }
        }
      }
    }

    return cloneFailures;
  }