Group handling changes:
      Edge case fix in group store where extraneous group buckets are updated so the group can be reused
      Bug fix for broadcast group in OF-DPA as there can only be one l2flood group per vlan
      Group operation failure codes are now reported by the provider to the core
      Group ids are displayed in hex in a couple of places

Change-Id: Ib48d21aa96e0400b77999a1b45839c28f678e524
diff --git a/core/api/src/main/java/org/onosproject/core/DefaultGroupId.java b/core/api/src/main/java/org/onosproject/core/DefaultGroupId.java
index 7467c3c..3f95559 100644
--- a/core/api/src/main/java/org/onosproject/core/DefaultGroupId.java
+++ b/core/api/src/main/java/org/onosproject/core/DefaultGroupId.java
@@ -61,7 +61,7 @@
     @Override
     public String toString() {
         return MoreObjects.toStringHelper(this)
-                .add("id", id)
+                .add("id", "0x" + Integer.toHexString(id))
                 .toString();
     }
 }
diff --git a/core/api/src/main/java/org/onosproject/net/flow/instructions/Instructions.java b/core/api/src/main/java/org/onosproject/net/flow/instructions/Instructions.java
index e1a71fc..3e2335b 100644
--- a/core/api/src/main/java/org/onosproject/net/flow/instructions/Instructions.java
+++ b/core/api/src/main/java/org/onosproject/net/flow/instructions/Instructions.java
@@ -576,7 +576,7 @@
 
         @Override
         public String toString() {
-            return type().toString() + SEPARATOR + Integer.toHexString(groupId.id());
+            return type().toString() + SEPARATOR + "0x" + Integer.toHexString(groupId.id());
         }
 
         @Override
diff --git a/core/api/src/main/java/org/onosproject/net/group/GroupOperation.java b/core/api/src/main/java/org/onosproject/net/group/GroupOperation.java
index e4173b3..42ef9dd 100644
--- a/core/api/src/main/java/org/onosproject/net/group/GroupOperation.java
+++ b/core/api/src/main/java/org/onosproject/net/group/GroupOperation.java
@@ -31,6 +31,7 @@
     private final GroupId groupId;
     private final GroupDescription.Type groupType;
     private final GroupBuckets buckets;
+    private final GroupMsgErrorCode failureCode;
 
     public enum Type {
         /**
@@ -48,6 +49,28 @@
     }
 
     /**
+     * Possible error codes for a failure of a group operation.
+     *
+     */
+    public enum GroupMsgErrorCode {
+        GROUP_EXISTS,
+        INVALID_GROUP,
+        WEIGHT_UNSUPPORTED,
+        OUT_OF_GROUPS,
+        OUT_OF_BUCKETS,
+        CHAINING_UNSUPPORTED,
+        WATCH_UNSUPPORTED,
+        LOOP,
+        UNKNOWN_GROUP,
+        CHAINED_GROUP,
+        BAD_TYPE,
+        BAD_COMMAND,
+        BAD_BUCKET,
+        BAD_WATCH,
+        EPERM;
+    }
+
+    /**
      * Group operation constructor with the parameters.
      *
      * @param opType group operation type
@@ -63,6 +86,23 @@
         this.groupId = checkNotNull(groupId);
         this.groupType = checkNotNull(groupType);
         this.buckets = buckets;
+        this.failureCode = null;
+    }
+
+    /**
+     * Group operation copy-constructor with additional field to set failure code.
+     * Typically used by provider to return information to the core about
+     * the failure reason for a group operation.
+     *
+     * @param groupOp the original group operation
+     * @param failureCode failure code for a failed group operation
+     */
+    private GroupOperation(GroupOperation groupOp, GroupMsgErrorCode failureCode) {
+        this.opType = groupOp.opType;
+        this.groupId = groupOp.groupId;
+        this.groupType = groupOp.groupType;
+        this.buckets = groupOp.buckets;
+        this.failureCode = failureCode;
     }
 
     /**
@@ -109,6 +149,12 @@
 
     }
 
+    public static GroupOperation createFailedGroupOperation(GroupOperation groupOperation,
+                                                            GroupMsgErrorCode failureCode) {
+        checkNotNull(groupOperation);
+        return new GroupOperation(groupOperation, failureCode);
+    }
+
     /**
      * Returns group operation type.
      *
@@ -145,6 +191,15 @@
         return this.buckets;
     }
 
+    /**
+     * Returns the failure code representing the failure of a group operation.
+     *
+     * @return error code for failure of group operation
+     */
+    public GroupMsgErrorCode failureCode() {
+        return failureCode;
+    }
+
     @Override
     /*
      * The deviceId, type and buckets are used for hash.