Initial import of Microsemi Driver

Change-Id: I431d5f2c18e0b66a84c36273c3d9f0b84f223841

Added in BUCK files for building driver

Change-Id: I70681327f5b89f67e904c45d5974ab393652d51f

Corrected some syntax errors

Change-Id: I11150cc499c212005f80619e3900e747f1c23d96

Updated pom file to clean build

Change-Id: I6613ddc9e6802aa882e716cf04df210249870835

Added in utility functions for EA1000 Init

Change-Id: I51ffe0cf0daf9ffcea0e2479ee9982fcd1755440

Added YMS code to Microsemi Driver

Change-Id: I6f2a14e454c6909bf9e9f6025321c74c98c13c72

Updated driver to work with YMS and YCH

Change-Id: If7dbe3cd5bd1b6f902d09d6b2dc3895605d70f70

Implemented IetfSystemManager as a service and call on YMS as a service

Change-Id: If1c5e8482b1f53f578a3b0b770accd50024111cf

Moved YMS calls over in to Yang Service implementation

Change-Id: I044aad06f1ef7452bc48e88987787a683666cd72

improved unit test for IetfSystemManager

Change-Id: I48fbf831e7e5ca0e1ef3de8288e56da1b5ebb7a4

Major changes to IetfSystemManager to work in live system

Change-Id: I6e3aa118ba422151f314b9a666860d90905c9929

Added in retry mechanism for DeviceDescription to wait for YCH

Change-Id: If8e0f2c2f315ffd6db15627a11382a00217dd262

Added in implementation of MseaSaFiltering and unit tests

Change-Id: I34bf888e0e732bd4664d1fb8ef5abb679b1506fe

Updated driver with unit tests for MseaSaFiltering

Change-Id: I7ea2407a546622ff55d1ab21610c45697546d632

Modified removeFlowRules of Ea1000FlowRuleProgrammable

Change-Id: Ibb4a555f61887a8e6e42af588bb42f7b70f58efb

Added in manager for MseaUniEvc service with unit tests

Change-Id: Idc5853f46051548973f52a0659f7f88982ff960c

Implemented getFlowEntries() for EVCs from EA1000

Change-Id: Ie85dadfa7760f0b30a9bdf6ccd09cca9f097fff9

Added in translation of FlowRules in to EVC on EA1000

Change-Id: Icfb65171c3300c96b3ca4e18cbd327f0ed2190be

Added in handling of FlowRule deletion including complex ceVlanMaps

Change-Id: I7fd0bb0ef04d1b40e4b7d6a6db7f7ee662329780

Updated Service entries for new onos-yang-tools

Change-Id: I44e655202f3a45073e1e16f83737caed6e01afa8

Revert "Updated Service entries for new onos-yang-tools"

This reverts commit 642b550ef1de12ed59bad2eaa3a2da414d2e5e59.

Improved timeout mechanism for YANG model loading

Change-Id: If744ecd206372e822edf2b736c83226321a12256

Minor edits of EVC creation

Change-Id: Ib0a4763deaf6dce37625ba77f5095b39cd98272d

Added in CustomEvc and supporting classes

Change-Id: Iad60eb1bcd48d2aec55b894b2d419b51852c3b2f

Created CeVlanUtils to resolve loading problem

Change-Id: I0d63931ad2c5ad2725861ebc7dccc4d5fe7b9298

Modified startup check

Change-Id: I6e6bcfa7e615044cb08fe7ee2f8a6c8b89aabb21

Modified handlin of flow rules

Change-Id: I965a79c23298866122aeb94c6d9d584aafee3bd5

Fixed problem with ceVlanMap

Change-Id: If1458c35d0b95b5b25b6636f098292f9e91c06c6

Minor Pom edits

Change-Id: I5cefb18674aa04b1f50bd7e2306260c1c3ad3814

Commented out extension references in YANG files to avoid onos-yang-tools problems

Change-Id: I32fdb34c4f476f495fe28e75d0f410aaf14e2ec1

Corrected error in removing 0 in CeVlanMapUtils

Change-Id: I8cd1fd02788b81c2613364d5639ef6e090057f80

Changes in YMS to accomodate EA1000 driver

Change-Id: I6ae2b9bd2be49eae8d4ad2f929dfe3214c514550
diff --git a/drivers/microsemi/ea1000yang/src/main/java/org/onosproject/drivers/microsemi/yang/utils/CeVlanMapUtils.java b/drivers/microsemi/ea1000yang/src/main/java/org/onosproject/drivers/microsemi/yang/utils/CeVlanMapUtils.java
new file mode 100644
index 0000000..52ede6d
--- /dev/null
+++ b/drivers/microsemi/ea1000yang/src/main/java/org/onosproject/drivers/microsemi/yang/utils/CeVlanMapUtils.java
@@ -0,0 +1,196 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed 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.onosproject.drivers.microsemi.yang.utils;
+
+import java.util.Arrays;
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.apache.commons.lang.ArrayUtils;
+
+/**
+ * A set of static utilities that allow a ce-vlan-map to be decomposed.
+ *
+ * This is an implementation specific to Microsemi that encodes ce-vlan-map
+ * in a similar way to Section 7.9 in the MEF 10.2 specification. That specification
+ * suggests comma delimited lists of VIDs - this implementation adds on colons to
+ * specify a contiguous range of IDs
+ */
+public final class CeVlanMapUtils {
+
+    private CeVlanMapUtils() {
+        //Do not allow this utility class to be instantiated
+    }
+
+    /**
+     * Calculate the ceVlanMap in to a Set of values.
+     *
+     * From Yang description
+     *   "This object indicates the CE-VLANs associated with the specific
+     *   EVC on a UNI. CE-VLAN IDs have value of 0 to 4095. The CE-VLAN ID
+     *   list can be a single value or multiple values separated by a delimiter.
+     *   Some valid values are: '100', '1:10', '10,20,30', '1:4095'. In the
+     *   first example only CE-VLAN ID 100 is associated with the VLAN map.
+     *   In the second example the CE-VLAN map includes CE-VLAN IDs 1 through
+     *   10 (range of values). The third example indicates three separate values
+     *   that make up the CE-VLAN map. The last example indicates all CE-VLAN IDs
+     *   are included in the map (range of values). ";
+     *  reference
+     *   "[MEF 6.1] 6.1; [MEF 7.2] 6.2.1.3";
+     * @param ceVlanMap A list of vlan id's in the format described above
+     * @return A set of vlan ids
+     */
+    public static Short[] getVlanSet(String ceVlanMap) {
+        if (ceVlanMap == null || ceVlanMap.isEmpty()) {
+            return new Short[0];
+        }
+        Set<Short> ceVlanSet = new TreeSet<Short>();
+
+        String[] ceVlanMapCommas = ceVlanMap.split(",");
+        for (String ceVlanMapComma:ceVlanMapCommas) {
+            String[] ceVlanMapColon = ceVlanMapComma.split(":");
+            if (ceVlanMapColon.length == 1) {
+                ceVlanSet.add(Short.decode(ceVlanMapColon[0]));
+            } else {
+                short start = Short.decode(ceVlanMapColon[0]);
+                short end = Short.decode(ceVlanMapColon[1]);
+                if ((start < 0 || end > 4095)) {
+                    return null;
+                } else {
+                    for (short i = start; i <= end; i++) {
+                        ceVlanSet.add(i);
+                    }
+                }
+            }
+        }
+
+        return ceVlanSet.toArray(new Short[ceVlanSet.size()]);
+    }
+
+    /**
+     * Convert an array of vlan ids in to a string representation.
+     * @param vlanArray An array of vlan ids
+     * @return A string representation delimited by commas and colons
+     */
+    public static String vlanListAsString(Short[] vlanArray) {
+        boolean colonPending = false;
+        StringBuilder ceVlanMapBuilder = new StringBuilder();
+        if (vlanArray.length == 0) {
+            return "";
+        } else if (vlanArray.length == 1 && vlanArray[0] == 0) {
+            return "0";
+        }
+
+        //To ensure that there are no repeated or out-of-order elements we must convert to TreeSet
+        TreeSet<Short> vlanSet = new TreeSet<>(Arrays.asList(vlanArray));
+
+        if (vlanSet.first() == 0) {
+            vlanSet.remove(vlanSet.first());
+        }
+        short prev = vlanSet.first();
+        for (short s:vlanSet) {
+            if (s == prev) {
+                ceVlanMapBuilder.append(Short.valueOf(s));
+                continue;
+            } else if (prev == (s - 1)) {
+                colonPending = true;
+            } else {
+                if (colonPending) {
+                    ceVlanMapBuilder.append(":" + Short.valueOf(prev));
+                    colonPending = false;
+                }
+                ceVlanMapBuilder.append("," + Short.valueOf(s));
+            }
+            prev = s;
+        }
+        if (colonPending) {
+            ceVlanMapBuilder.append(":" + Short.valueOf(prev));
+        }
+
+        return ceVlanMapBuilder.toString();
+    }
+
+    /**
+     * Add an additional vlan id to an existing string representation.
+     * @param existingMap An array of vlan ids
+     * @param newVlan The new vlan ID to add
+     * @return A string representation delimited by commas and colons
+     */
+    public static String addtoCeVlanMap(String existingMap, Short newVlan) {
+        Short[] vlanArray = getVlanSet(existingMap);
+        TreeSet<Short> vlanSet = new TreeSet<>();
+        for (Short vlan:vlanArray) {
+            vlanSet.add(vlan);
+        }
+
+        vlanSet.add(newVlan);
+
+        return vlanListAsString(vlanSet.toArray(new Short[vlanSet.size()]));
+    }
+
+    /**
+     * If a string representation contains a '0' then remove it.
+     *
+     * Zero is an invalid VLAN id, and is used here as a place holder for null. Null can't
+     * be used in the EA1000 device. Once any other vlan ids are added then the zero should
+     * be removed. It is safe to call this method even if no zero is present - the method will
+     * make no change in that case.
+     *
+     * @param existingMap An string representation of vlan ids, possibly containing a zero
+     * @return A string representation delimited by commas and colons without zero
+     */
+    public static String removeZeroIfPossible(String existingMap) {
+        if (existingMap == null || existingMap.isEmpty()) {
+            return "0";
+        } else if (existingMap == "0") {
+            return existingMap;
+        }
+        return removeFromCeVlanMap(existingMap, (short) 0);
+    }
+
+    /**
+     * Remove a vlan id from an existing string representation.
+     * @param existingMap An array of vlan ids
+     * @param vlanRemove The vlan ID to remove
+     * @return A string representation delimited by commas and colons
+     */
+    public static String removeFromCeVlanMap(String existingMap, Short vlanRemove) {
+        Short[] vlanArray = getVlanSet(existingMap);
+        TreeSet<Short> vlanSet = new TreeSet<>();
+        for (Short vlan:vlanArray) {
+            if (vlan.shortValue() != vlanRemove.shortValue()) {
+                vlanSet.add(vlan);
+            }
+        }
+
+        return vlanListAsString(vlanSet.toArray(new Short[vlanSet.size()]));
+    }
+
+    /**
+     * Combine vlan ids from two existing string representations.
+     *
+     * If there are overlapping elements and ranges, these are consolidated in to one.
+     *
+     * @param set1 A string containing a set of vlan ids
+     * @param set2 A string containing a set of vlan ids
+     * @return A string representation delimited by commas and colons
+     */
+    public static String combineVlanSets(String set1, String set2) {
+        Short[] set1Array = getVlanSet(set1);
+        Short[] set2Array = getVlanSet(set2);
+        return vlanListAsString((Short[]) ArrayUtils.addAll(set1Array, set2Array));
+    }
+}
diff --git a/drivers/microsemi/ea1000yang/src/main/java/org/onosproject/drivers/microsemi/yang/utils/IetfYangTypesUtils.java b/drivers/microsemi/ea1000yang/src/main/java/org/onosproject/drivers/microsemi/yang/utils/IetfYangTypesUtils.java
new file mode 100644
index 0000000..4b706b6
--- /dev/null
+++ b/drivers/microsemi/ea1000yang/src/main/java/org/onosproject/drivers/microsemi/yang/utils/IetfYangTypesUtils.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed 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.onosproject.drivers.microsemi.yang.utils;
+
+import java.time.LocalDateTime;
+import java.time.OffsetDateTime;
+import java.time.ZoneId;
+import java.time.ZonedDateTime;
+import java.time.format.DateTimeFormatter;
+
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev20130715.ietfyangtypes.DateAndTime;
+
+/**
+ * A utility class to change various YANG types to general purpose classes.
+ */
+public final class IetfYangTypesUtils {
+    private IetfYangTypesUtils() {
+        //Hiding the public constructor for this utility class
+    }
+
+    /**
+     * Convert from Date and Time in a ietf-yang-types format to the Java Time API.
+     * @param dateAndTime A date and time from a YANG object
+     * @return A Date and Time with a Time Zone offset
+     */
+    public static OffsetDateTime fromYangDateTime(DateAndTime dateAndTime) {
+        return OffsetDateTime.parse(dateAndTime.toString(), DateTimeFormatter.ISO_OFFSET_DATE_TIME);
+    }
+
+    /**
+     * Convert a from Date and Time in a ietf-yang-types format to the Java Time API and rezone to a given Time Zone.
+     * @param dateAndTime A date and time from a YANG object
+     * @param zoneId The time zone to rezone the time and date to
+     * @return The rezoned time and date
+     */
+    public static ZonedDateTime fromYangDateTimeZoned(DateAndTime dateAndTime, ZoneId zoneId) {
+        return OffsetDateTime.parse(dateAndTime.toString(),
+                DateTimeFormatter.ISO_OFFSET_DATE_TIME).atZoneSameInstant(zoneId);
+    }
+
+    /**
+     * Convert a from Date and Time in a ietf-yang-types format to the Java Time API rezoned to the local Time Zone.
+     * @param dateAndTime A date and time from a YANG object
+     * @return The date and time in the zone of this local machine
+     */
+    public static LocalDateTime fromYangDateTimeToLocal(DateAndTime dateAndTime) {
+        OffsetDateTime odt = OffsetDateTime.parse(dateAndTime.toString(), DateTimeFormatter.ISO_OFFSET_DATE_TIME);
+
+        return LocalDateTime.ofInstant(odt.toInstant(), ZoneId.systemDefault());
+    }
+}
diff --git a/drivers/microsemi/ea1000yang/src/main/java/org/onosproject/drivers/microsemi/yang/utils/package-info.java b/drivers/microsemi/ea1000yang/src/main/java/org/onosproject/drivers/microsemi/yang/utils/package-info.java
new file mode 100644
index 0000000..0c03c46
--- /dev/null
+++ b/drivers/microsemi/ea1000yang/src/main/java/org/onosproject/drivers/microsemi/yang/utils/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed 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 for general utilities and helpers.
+ */
+package org.onosproject.drivers.microsemi.yang.utils;
\ No newline at end of file