@Override
  public List<ObjectAction> getObjectActions(
      final List<ActionType> types,
      final Contributed contributed,
      final Filter<ObjectAction> filter) {

    // update our list of actions if requesting for contributed actions
    // and they have not yet been added
    // the "contributed.isIncluded()" guard is required because we cannot do this too early;
    // there must be a session available
    if (contributed.isIncluded() && !contributeeActionsAdded) {
      synchronized (this.objectActions) {
        final List<ObjectAction> actions = Lists.newArrayList(this.objectActions);
        actions.addAll(createContributeeActions());
        sortCacheAndUpdateActions(actions);
        contributeeActionsAdded = true;
      }
    }

    final List<ObjectAction> actions = Lists.newArrayList();
    for (final ActionType type : types) {
      final Collection<ObjectAction> filterActions =
          Collections2.filter(objectActionsByType.get(type), Filters.asPredicate(filter));
      actions.addAll(filterActions);
    }
    return Lists.newArrayList(
        Iterables.filter(actions, ContributeeMember.Predicates.regularElse(contributed)));
  }
  private void addContributeeActionsIfAny(
      final ObjectAdapter serviceAdapter, final List<ObjectAction> contributeeActionsToAppendTo) {
    final ObjectSpecification specification = serviceAdapter.getSpecification();
    if (specification == this) {
      return;
    }
    final List<ObjectAction> contributeeActions = Lists.newArrayList();
    final List<ObjectAction> serviceActions =
        specification.getObjectActions(
            ActionType.ALL, Contributed.INCLUDED, Filters.<ObjectAction>any());
    for (final ObjectAction serviceAction : serviceActions) {
      if (isAlwaysHidden(serviceAction)) {
        continue;
      }
      final NotContributedFacet notContributed = serviceAction.getFacet(NotContributedFacet.class);
      if (notContributed != null && notContributed.toActions()) {
        continue;
      }
      if (!(serviceAction instanceof ObjectActionImpl)) {
        continue;
      }
      final ObjectActionImpl contributedAction = (ObjectActionImpl) serviceAction;

      // see if qualifies by inspecting all parameters
      final int contributeeParam = contributeeParameterMatchOf(contributedAction);
      if (contributeeParam != -1) {
        ObjectActionContributee contributeeAction =
            new ObjectActionContributee(
                serviceAdapter, contributedAction, contributeeParam, this, objectMemberContext);
        facetProcessor.processMemberOrder(metadataProperties, contributeeAction);
        contributeeActions.add(contributeeAction);
      }
    }
    contributeeActionsToAppendTo.addAll(contributeeActions);
  }
  protected List<ObjectAssociation> sortAssociations(final List<ObjectAssociation> associations) {
    final DeweyOrderSet orderSet = DeweyOrderSet.createOrderSet(associations);
    final MemberGroupLayoutFacet memberGroupLayoutFacet =
        this.getFacet(MemberGroupLayoutFacet.class);

    if (memberGroupLayoutFacet != null) {
      final List<String> groupOrder = Lists.newArrayList();
      groupOrder.addAll(memberGroupLayoutFacet.getLeft());
      groupOrder.addAll(memberGroupLayoutFacet.getMiddle());
      groupOrder.addAll(memberGroupLayoutFacet.getRight());

      orderSet.reorderChildren(groupOrder);
    }
    final List<ObjectAssociation> orderedAssociations = Lists.newArrayList();
    sortAssociations(orderSet, orderedAssociations);
    return orderedAssociations;
  }
 private void addContributeeAssociationsIfAny(
     final ObjectAdapter serviceAdapter,
     final List<ObjectAssociation> contributeeAssociationsToAppendTo) {
   final ObjectSpecification specification = serviceAdapter.getSpecification();
   if (specification == this) {
     return;
   }
   final List<ObjectAssociation> contributeeAssociations =
       createContributeeAssociations(serviceAdapter);
   contributeeAssociationsToAppendTo.addAll(contributeeAssociations);
 }
  protected void sortCacheAndUpdateActions(final List<ObjectAction> objectActions) {
    final List<ObjectAction> orderedActions = sortActions(objectActions);
    synchronized (this.objectActions) {
      this.objectActions.clear();
      this.objectActions.addAll(orderedActions);

      for (final ActionType type : ActionType.values()) {
        final List<ObjectAction> objectActionForType = objectActionsByType.get(type);
        objectActionForType.clear();
        objectActionForType.addAll(
            Collections2.filter(objectActions, ObjectAction.Predicates.ofType(type)));
      }
    }
  }
 private void appendServiceActionsReturning(
     final ObjectAdapter serviceAdapter,
     final List<ActionType> types,
     final List<ObjectAction> relatedActionsToAppendTo) {
   final List<ObjectAction> matchingActionsToAppendTo = Lists.newArrayList();
   for (final ActionType type : types) {
     final List<ObjectAction> serviceActions =
         serviceAdapter
             .getSpecification()
             .getObjectActions(type, Contributed.INCLUDED, Filters.<ObjectAction>any());
     for (final ObjectAction serviceAction : serviceActions) {
       addIfReturnsSubtype(serviceAction, matchingActionsToAppendTo);
     }
   }
   relatedActionsToAppendTo.addAll(matchingActionsToAppendTo);
 }
 private static void sortActions(
     final DeweyOrderSet orderSet, final List<ObjectAction> actionsToAppendTo) {
   for (final Object element : orderSet) {
     if (element instanceof ObjectAction) {
       final ObjectAction objectAction = (ObjectAction) element;
       actionsToAppendTo.add(objectAction);
     } else if (element instanceof DeweyOrderSet) {
       final DeweyOrderSet set = ((DeweyOrderSet) element);
       final List<ObjectAction> actions = Lists.newArrayList();
       sortActions(set, actions);
       actionsToAppendTo.addAll(actions);
     } else {
       throw new UnknownTypeException(element);
     }
   }
 }
 @Override
 public List<ObjectAssociation> getAssociations(final Contributed contributed) {
   // the "contributed.isIncluded()" guard is required because we cannot do this too early;
   // there must be a session available
   if (contributed.isIncluded() && !contributeeAssociationsAdded) {
     synchronized (this.associations) {
       List<ObjectAssociation> associations = Lists.newArrayList(this.associations);
       associations.addAll(createContributeeAssociations());
       sortAndUpdateAssociations(associations);
       contributeeAssociationsAdded = true;
     }
   }
   final List<ObjectAssociation> associations = Lists.newArrayList(this.associations);
   return Lists.newArrayList(
       Iterables.filter(associations, ContributeeMember.Predicates.regularElse(contributed)));
 }