/**
   * Applies the given security group permissions to the given node with the given compute service.
   *
   * <p>Takes no action if the compute service does not have a security group extension.
   *
   * @param permissions The set of permissions to be applied to the node
   * @param nodeId The id of the node to update
   * @param computeService The compute service to use to apply the changes
   */
  @VisibleForTesting
  Map<String, SecurityGroup> addPermissionsToLocation(
      Iterable<IpPermission> permissions, final String nodeId, ComputeService computeService) {
    if (!computeService.getSecurityGroupExtension().isPresent()) {
      LOG.warn(
          "Security group extension for {} absent; cannot update node {} with {}",
          new Object[] {computeService, nodeId, permissions});
      return ImmutableMap.of();
    }
    final SecurityGroupExtension securityApi = computeService.getSecurityGroupExtension().get();
    final String locationId = computeService.getContext().unwrap().getId();

    // Expect to have two security groups on the node: one shared between all nodes in the location,
    // that is cached in sharedGroupCache, and one created by Jclouds that is unique to the node.
    // Relies on customize having been called before. This should be safe because the arguments
    // needed to call this method are not available until post-instance creation.
    SecurityGroup machineUniqueSecurityGroup = getSecurityGroup(nodeId, securityApi, locationId);
    MutableList<IpPermission> newPermissions = MutableList.copyOf(permissions);
    Iterables.removeAll(newPermissions, machineUniqueSecurityGroup.getIpPermissions());
    MutableMap<String, SecurityGroup> addedSecurityGroups = MutableMap.of();
    for (IpPermission permission : newPermissions) {
      SecurityGroup addedPermission =
          addPermission(permission, machineUniqueSecurityGroup, securityApi);
      addedSecurityGroups.put(addedPermission.getId(), addedPermission);
    }
    return addedSecurityGroups;
  }
  @Test
  public void testApply() {
    IpPermissions authorization = IpPermissions.permitAnyProtocol();

    org.jclouds.ec2.domain.SecurityGroup origGroup =
        org.jclouds.ec2.domain.SecurityGroup.builder()
            .region("us-east-1")
            .id("some-id")
            .name("some-group")
            .ownerId("some-owner")
            .description("some-description")
            .ipPermission(authorization)
            .build();

    AWSEC2SecurityGroupToSecurityGroup parser = createGroupParser(ImmutableSet.of(provider));

    SecurityGroup group = parser.apply(origGroup);

    assertEquals(group.getLocation(), provider);
    assertEquals(group.getId(), provider.getId() + "/" + origGroup.getId());
    assertEquals(group.getProviderId(), origGroup.getId());
    assertEquals(group.getName(), origGroup.getName());
    assertEquals(group.getIpPermissions(), (Set<IpPermission>) origGroup);
    assertEquals(group.getOwnerId(), origGroup.getOwnerId());
  }
  @Test
  public void testApplyWithGroup() {
    NovaSecurityGroupInZoneToSecurityGroup parser = createGroupParser();

    SecurityGroupInZone origGroup = new SecurityGroupInZone(securityGroupWithGroup(), zone.getId());

    SecurityGroup newGroup = parser.apply(origGroup);

    assertEquals(
        newGroup.getId(), origGroup.getZone() + "/" + origGroup.getSecurityGroup().getId());
    assertEquals(newGroup.getProviderId(), origGroup.getSecurityGroup().getId());
    assertEquals(newGroup.getName(), origGroup.getSecurityGroup().getName());
    assertEquals(newGroup.getOwnerId(), origGroup.getSecurityGroup().getTenantId());
    assertEquals(
        newGroup.getIpPermissions(),
        ImmutableSet.copyOf(
            transform(
                origGroup.getSecurityGroup().getRules(),
                NovaSecurityGroupToSecurityGroupTest.ruleConverter)));
    assertEquals(newGroup.getLocation().getId(), origGroup.getZone());
  }