diff --git a/compute/src/main/java/org/jclouds/net/domain/IpPermission.java b/compute/src/main/java/org/jclouds/net/domain/IpPermission.java
index 8eb4ab8..bfcb7b2 100644
--- a/compute/src/main/java/org/jclouds/net/domain/IpPermission.java
+++ b/compute/src/main/java/org/jclouds/net/domain/IpPermission.java
@@ -22,8 +22,13 @@
 import static com.google.common.collect.Iterables.transform;
 import static org.jclouds.util.Strings2.isCidrFormat;
 
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.Iterator;
 import java.util.Set;
 
+import org.jclouds.net.util.IpPermissions;
+
 import com.google.common.annotations.Beta;
 import com.google.common.base.Function;
 import com.google.common.base.Objects;
@@ -39,7 +44,7 @@
  * Ingress access to a destination protocol on particular ports by source, which could be an ip
  * range (cidrblock), set of explicit security group ids in the current tenant, or security group
  * names in another tenant.
- * 
+ *
  * @see IpPermissions
  */
 @Beta
@@ -58,7 +63,26 @@
       private Set<String> exclusionCidrBlocks = Sets.newLinkedHashSet();
 
       /**
-       * 
+       * Creates a builder initialized from an existing permission.
+       * @param permission The existing permission.
+       * @return the builder.
+       */
+      public Builder fromPermission(IpPermission permission) {
+         this.ipProtocol = permission.ipProtocol;
+         this.fromPort = permission.fromPort;
+         this.toPort = permission.toPort;
+         this.tenantIdGroupNamePairs = LinkedHashMultimap.create();
+         tenantIdGroupNamePairs.putAll(permission.tenantIdGroupNamePairs);
+         this.groupIds = Sets.newLinkedHashSet();
+         this.groupIds.addAll(permission.groupIds);
+         this.cidrBlocks = Sets.newLinkedHashSet();
+         this.cidrBlocks.addAll(permission.cidrBlocks);
+         this.exclusionCidrBlocks = Sets.newLinkedHashSet();
+         this.exclusionCidrBlocks.addAll(permission.exclusionCidrBlocks);
+         return this;
+      }
+
+      /**
        * @see IpPermission#getIpProtocol()
        */
       public Builder ipProtocol(IpProtocol ipProtocol) {
@@ -67,7 +91,6 @@
       }
 
       /**
-       * 
        * @see IpPermission#getFromPort()
        */
       public Builder fromPort(int fromPort) {
@@ -76,7 +99,6 @@
       }
 
       /**
-       * 
        * @see IpPermission#getToPort()
        */
       public Builder toPort(int toPort) {
@@ -129,7 +151,7 @@
       @Beta
       public Builder exclusionCidrBlock(String exclusionCidrBlock) {
          checkArgument(isCidrFormat(exclusionCidrBlock), "exclusionCidrBlock %s is not a valid CIDR",
-               exclusionCidrBlock);
+            exclusionCidrBlock);
          this.exclusionCidrBlocks.add(exclusionCidrBlock);
          return this;
       }
@@ -167,7 +189,7 @@
 
       public IpPermission build() {
          return new IpPermission(ipProtocol, fromPort, toPort, tenantIdGroupNamePairs, groupIds, cidrBlocks,
-               exclusionCidrBlocks);
+            exclusionCidrBlocks);
       }
    }
 
@@ -180,25 +202,18 @@
    private final Set<String> exclusionCidrBlocks;
 
    public IpPermission(IpProtocol ipProtocol, int fromPort, int toPort,
-         Multimap<String, String> tenantIdGroupNamePairs, Iterable<String> groupIds, Iterable<String> cidrBlocks,
-         Iterable<String> exclusionCidrBlocks) {
+                       Multimap<String, String> tenantIdGroupNamePairs, Iterable<String> groupIds, Iterable<String> cidrBlocks,
+                       Iterable<String> exclusionCidrBlocks) {
       this.fromPort = fromPort;
       this.toPort = toPort;
       this.tenantIdGroupNamePairs = ImmutableMultimap.copyOf(checkNotNull(tenantIdGroupNamePairs,
-            "tenantIdGroupNamePairs"));
+         "tenantIdGroupNamePairs"));
       this.ipProtocol = checkNotNull(ipProtocol, "ipProtocol");
       this.groupIds = ImmutableSet.copyOf(checkNotNull(groupIds, "groupIds"));
       this.cidrBlocks = ImmutableSet.copyOf(checkNotNull(cidrBlocks, "cidrBlocks"));
       this.exclusionCidrBlocks = ImmutableSet.copyOf(checkNotNull(exclusionCidrBlocks, "exclusionCidrBlocks"));
    }
 
-   /**
-    * {@inheritDoc}
-    */
-   @Override
-   public int compareTo(IpPermission o) {
-      return (this == o) ? 0 : getIpProtocol().compareTo(o.getIpProtocol());
-   }
 
    /**
     * destination IP protocol
@@ -252,6 +267,41 @@
       return exclusionCidrBlocks;
    }
 
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public int compareTo(IpPermission that) {
+      if (this == that) return 0;
+      final int proto = getIpProtocol().compareTo(that.getIpProtocol());
+      if (proto != 0) return proto;
+
+      final int fromP = Integer.valueOf(this.fromPort).compareTo(Integer.valueOf(that.fromPort));
+      if (fromP != 0) return fromP;
+
+      final int toP = Integer.valueOf(this.toPort).compareTo(Integer.valueOf(that.toPort));
+      if (toP != 0) return toP;
+
+      final int tenantGroups = new LinkedMultiMapComparator<String, String>()
+         .compare(this.tenantIdGroupNamePairs, that.tenantIdGroupNamePairs);
+      if (tenantGroups != 0) return tenantGroups;
+
+      final int groupIdComp = new CollectionComparator<String>()
+         .compare(this.groupIds, that.groupIds);
+      if (groupIdComp != 0) return groupIdComp;
+
+      final int cidrComp = new CollectionComparator<String>()
+         .compare(this.cidrBlocks, that.cidrBlocks);
+      if (cidrComp != 0) return cidrComp;
+
+      final int exclusionsComp = new CollectionComparator<String>()
+         .compare(this.exclusionCidrBlocks, that.exclusionCidrBlocks);
+      if (exclusionsComp != 0) return exclusionsComp;
+
+      return 0;
+   }
+
    @Override
    public boolean equals(Object o) {
       if (this == o)
@@ -261,15 +311,15 @@
          return false;
       IpPermission that = IpPermission.class.cast(o);
       return equal(this.ipProtocol, that.ipProtocol) && equal(this.fromPort, that.fromPort)
-            && equal(this.toPort, that.toPort) && equal(this.tenantIdGroupNamePairs, that.tenantIdGroupNamePairs)
-            && equal(this.groupIds, that.groupIds) && equal(this.cidrBlocks, that.cidrBlocks)
-            && equal(this.exclusionCidrBlocks, that.exclusionCidrBlocks);
+         && equal(this.toPort, that.toPort) && equal(this.tenantIdGroupNamePairs, that.tenantIdGroupNamePairs)
+         && equal(this.groupIds, that.groupIds) && equal(this.cidrBlocks, that.cidrBlocks)
+         && equal(this.exclusionCidrBlocks, that.exclusionCidrBlocks);
    }
 
    @Override
    public int hashCode() {
       return Objects.hashCode(ipProtocol, fromPort, toPort, tenantIdGroupNamePairs, groupIds, cidrBlocks,
-            exclusionCidrBlocks);
+         exclusionCidrBlocks);
    }
 
    @Override
@@ -279,8 +329,78 @@
 
    protected ToStringHelper string() {
       return Objects.toStringHelper("").add("ipProtocol", ipProtocol).add("fromPort", fromPort)
-            .add("toPort", toPort).add("tenantIdGroupNamePairs", tenantIdGroupNamePairs).add("groupIds", groupIds)
-            .add("cidrBlocks", cidrBlocks).add("exclusionCidrBlocks", exclusionCidrBlocks);
+         .add("toPort", toPort).add("tenantIdGroupNamePairs", tenantIdGroupNamePairs).add("groupIds", groupIds)
+         .add("cidrBlocks", cidrBlocks).add("exclusionCidrBlocks", exclusionCidrBlocks);
+   }
+
+
+   // A private tool for use in implementing a consistent compareTo relation.
+   private static class LinkedMultiMapComparator<K extends Comparable, V> implements Comparator<Multimap<K, V>> {
+
+      /**
+       * Compares {@link Multimap}s, in order of iterators.
+       * If two keys do not compare as zero, the key comparison result is used as the comparison result.
+       * For keys that are equal, the value collections are compared with {@link CollectionComparator}.
+       * If all entries compare as zero the map sizes determine the result.
+       *
+       * @param map1 The first map for comparison
+       * @param map2 The second map for comparison
+       * @return the comparison relation value
+       */
+      @Override
+      public int compare(Multimap<K, V> map1, Multimap<K, V> map2) {
+         final Iterator<K> leftIter = map1.keySet().iterator();
+         final Iterator<K> rightIter = map2.keySet().iterator();
+         while (leftIter.hasNext() && rightIter.hasNext()) {
+            K key1 = leftIter.next();
+            K key2 = rightIter.next();
+
+            int keyComp = key1.compareTo(key2);
+            if (keyComp != 0) return keyComp;
+
+            final int valuesComp = new CollectionComparator().compare(map1.get(key1), map2.get(key2));
+            if (valuesComp != 0) return valuesComp;
+         }
+         if (!leftIter.hasNext() && rightIter.hasNext()) {
+            return -1;
+         }
+         if (leftIter.hasNext() && !rightIter.hasNext()) {
+            return +1;
+         }
+         return 0;
+      }
+   }
+
+   // A private tool for use in implementing a consistent compareTo relation.
+   private static class CollectionComparator<T extends Comparable> implements Comparator<Collection<T>> {
+
+      /**
+       * Compares collections of comparable objects, in order of iterator.
+       * Iterates through the collections in step.
+       * If two entries do not compare as zero, the comparison result is the result of this method.
+       * If all entries compare as zero, then the collection sizes determine the result.
+       *
+       * @param o1 The first collection to compare.
+       * @param o2 The second collection to compare.
+       * @return The comparison relation value.
+       */
+      @Override
+      public int compare(Collection<T> o1, Collection<T> o2) {
+
+         final Iterator<T> leftIter = o1.iterator();
+         final Iterator<T> rightIter = o2.iterator();
+         while (leftIter.hasNext() && rightIter.hasNext()) {
+            int comp = leftIter.next().compareTo(rightIter.next());
+            if (comp != 0) return comp;
+         }
+         if (!leftIter.hasNext() && rightIter.hasNext()) {
+            return -1;
+         }
+         if (leftIter.hasNext() && !rightIter.hasNext()) {
+            return +1;
+         }
+         return 0;
+      }
    }
 
 }
diff --git a/compute/src/test/java/org/jclouds/net/domain/IpPermissionTest.java b/compute/src/test/java/org/jclouds/net/domain/IpPermissionTest.java
new file mode 100644
index 0000000..7f90ea4
--- /dev/null
+++ b/compute/src/test/java/org/jclouds/net/domain/IpPermissionTest.java
@@ -0,0 +1,243 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.net.domain;
+
+import static org.jclouds.net.domain.IpPermission.builder;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+import java.util.List;
+
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableList;
+
+public class IpPermissionTest {
+
+   @Test
+   public void testCompareProtocol() {
+      final IpPermission tcp = builder().ipProtocol(IpProtocol.TCP).build();
+      final IpPermission tcp2 = builder().ipProtocol(IpProtocol.TCP).build();
+      assertEqualAndComparable(tcp, tcp2);
+
+      final IpPermission udp = builder().ipProtocol(IpProtocol.UDP).build();
+      assertOrder(tcp, udp);
+
+      final IpPermission t10 = builder().fromPermission(tcp).fromPort(10).build();
+      final IpPermission t20 = builder().fromPermission(tcp).fromPort(20).build();
+      final IpPermission u10 = builder().fromPermission(udp).fromPort(10).build();
+
+      final IpPermission t0to10 = builder().fromPermission(tcp).toPort(10).build();
+      final IpPermission t0to20 = builder().fromPermission(tcp).toPort(20).build();
+
+      assertTotalOrder(ImmutableList.of(tcp, t0to10, t0to20, t10, t20, udp, u10));
+   }
+
+   @Test
+   public void testCompareTenantIdGroupNamePairs() {
+      final IpPermission tcp = builder().ipProtocol(IpProtocol.TCP).build();
+
+      final IpPermission g1 = builder().fromPermission(tcp)
+         .tenantIdGroupNamePair("tenant1", "group1").build();
+
+      final IpPermission g2 = builder().fromPermission(tcp)
+         .tenantIdGroupNamePair("tenant1", "group2").build();
+
+      final IpPermission g12 = builder().fromPermission(tcp)
+         .tenantIdGroupNamePair("tenant1", "group1")
+         .tenantIdGroupNamePair("tenant1", "group2").build();
+
+      final IpPermission g21 = builder().fromPermission(tcp)
+         .tenantIdGroupNamePair("tenant1", "group2")
+         .tenantIdGroupNamePair("tenant1", "group1").build();
+
+      final IpPermission t2g1 = builder().fromPermission(tcp)
+         .tenantIdGroupNamePair("tenant2", "group1").build();
+
+      assertTotalOrder(ImmutableList.of(tcp, g1, g12, g2, g21, t2g1));
+
+      final IpPermission g12b = builder().fromPermission(tcp)
+         .tenantIdGroupNamePair("tenant1", "group1")
+         .tenantIdGroupNamePair("tenant1", "group2").build();
+
+      assertEqualAndComparable(g12, g12b);
+   }
+
+   @Test
+   public void testCompareGroupIds() {
+      final IpPermission tcp = builder().ipProtocol(IpProtocol.TCP).build();
+
+      final IpPermission aa = builder().fromPermission(tcp)
+         .groupId("a").build();
+
+      final IpPermission a = builder().fromPermission(tcp)
+         .groupId("a").build();
+
+      final IpPermission ab = builder().fromPermission(tcp)
+         .groupId("a")
+         .groupId("b").build();
+
+      final IpPermission ba = builder().fromPermission(tcp)
+         .groupId("b")
+         .groupId("a").build();
+
+      assertTotalOrder(ImmutableList.of(tcp, a, ab, ba));
+      assertEqualAndComparable(a, aa);
+   }
+
+   @Test
+   public void testCompareCidrBlocks() {
+      final IpPermission tcp = builder().ipProtocol(IpProtocol.TCP).build();
+
+      final IpPermission everything = builder().fromPermission(tcp)
+         .cidrBlock("0.0.0.0/0").build();
+      final IpPermission universal = builder().fromPermission(tcp)
+         .cidrBlock("0.0.0.0/0").build();
+      assertEqualAndComparable(everything, universal);
+
+      final IpPermission localhost = builder().fromPermission(tcp)
+         .cidrBlock("127.0.0.1/32").build();
+
+      final IpPermission tenTwentyOne = builder().fromPermission(tcp)
+         .cidrBlock("10.0.0.21/32").build();
+
+      final IpPermission tenTwoHundred = builder().fromPermission(tcp)
+         .cidrBlock("10.0.0.200/32").build();
+
+      // comparison is alphabetic, not by numeric equivalent
+      assertOrder(tenTwoHundred, tenTwentyOne);
+
+      assertTotalOrder(ImmutableList.of(tcp, everything, tenTwoHundred, tenTwentyOne, localhost));
+   }
+
+   @Test
+   public void testCompareExclusionCidrBlocks() {
+      final IpPermission tcp = builder().ipProtocol(IpProtocol.TCP).build();
+
+      final IpPermission everything = builder().fromPermission(tcp)
+         .exclusionCidrBlock("0.0.0.0/0").build();
+      final IpPermission universal = builder().fromPermission(tcp)
+         .exclusionCidrBlock("0.0.0.0/0").build();
+      assertEqualAndComparable(everything, universal);
+
+      final IpPermission localhost = builder().fromPermission(tcp)
+         .exclusionCidrBlock("127.0.0.1/32").build();
+      final IpPermission stillLocal = builder().fromPermission(tcp)
+         .exclusionCidrBlock("127.0.0.1/32").build();
+      assertEqualAndComparable(localhost, stillLocal);
+
+      final IpPermission tenTwentyOne = builder().fromPermission(tcp)
+         .exclusionCidrBlock("10.0.0.21/32").build();
+
+      final IpPermission tenTwoHundred = builder().fromPermission(tcp)
+         .exclusionCidrBlock("10.0.0.200/32").build();
+
+      // comparison is alphabetic, not by numeric equivalent
+      assertOrder(tenTwoHundred, tenTwentyOne);
+
+      assertTotalOrder(ImmutableList.of(tcp, everything, tenTwoHundred, tenTwentyOne, localhost));
+   }
+
+
+   @Test
+   public void testPairwise() {
+
+      final IpPermission tcp = builder().ipProtocol(IpProtocol.TCP).build();
+      final IpPermission udp = builder().ipProtocol(IpProtocol.UDP).build();
+
+      final IpPermission f10 = builder().fromPermission(tcp).fromPort(10).build();
+      final IpPermission f20 = builder().fromPermission(tcp).fromPort(20).build();
+      final IpPermission u10 = builder().fromPermission(udp).fromPort(10).build();
+
+      final IpPermission t20 = builder().fromPermission(f10).toPort(20).build();
+      final IpPermission t30 = builder().fromPermission(f10).toPort(30).build();
+
+      final IpPermission t2g1 = builder().fromPermission(t20)
+         .tenantIdGroupNamePair("tenant1", "group1")
+      .build();
+
+      final IpPermission t2g2 = builder().fromPermission(t20)
+         .tenantIdGroupNamePair("tenant1", "group2")
+      .build();
+
+      final IpPermission gidA = builder().fromPermission(t2g1)
+         .groupId("groupA")
+      .build();
+
+      final IpPermission gidB = builder().fromPermission(t2g1)
+         .groupId("groupB")
+      .build();
+
+      final IpPermission cidr10 = builder().fromPermission(gidA)
+         .cidrBlock("10.10.10.10/32")
+      .build();
+
+      final IpPermission cidr20 = builder().fromPermission(gidA)
+         .cidrBlock("10.10.10.20/32")
+      .build();
+
+      final IpPermission ex10 = builder().fromPermission(cidr10)
+         .exclusionCidrBlock("172.16.10.10/32")
+      .build();
+
+      final IpPermission ex20 = builder().fromPermission(cidr10)
+         .exclusionCidrBlock("172.16.10.20/32")
+      .build();
+
+      assertTotalOrder(ImmutableList.of(
+         tcp,
+            f10,
+               t20,
+                  t2g1,
+                     gidA,
+                        cidr10,
+                           ex10,
+                           ex20,
+                        cidr20,
+                     gidB,
+                  t2g2,
+               t30,
+            f20,
+         udp,
+            u10
+      ));
+   }
+
+
+   public static void assertEqualAndComparable(IpPermission first, IpPermission second) {
+      assertEquals(first, second, first + " does not equal " + second);
+      assertTrue(first.compareTo(second) == 0, first + " does not compare zero to " + second);
+   }
+
+   private static void assertOrder(IpPermission smaller, IpPermission bigger) {
+      assertTrue(smaller.compareTo(bigger) < 0, smaller + " does not compare less than " + bigger);
+      assertTrue(bigger.compareTo(smaller) > 0, bigger + " does not compare greater than " + smaller);
+      assertTrue(smaller.compareTo(smaller) == 0, smaller + " does not compare zero to itself");
+      assertTrue(bigger.compareTo(bigger) == 0, bigger + " does not compare zero to itself");
+   }
+
+   private static void assertTotalOrder(List<IpPermission> permissions) {
+      if (permissions.size() < 2) return;
+      IpPermission head = permissions.get(0);
+      List<IpPermission> tail = permissions.subList(1, permissions.size());
+      for (IpPermission perm : tail) {
+         assertOrder(head, perm);
+      }
+      assertTotalOrder(tail);
+   }
+
+}
