diff --git a/core/store/dist/src/main/java/org/onosproject/store/host/impl/ECHostStore.java b/core/store/dist/src/main/java/org/onosproject/store/host/impl/ECHostStore.java
index fcaffe2..e833b2d 100644
--- a/core/store/dist/src/main/java/org/onosproject/store/host/impl/ECHostStore.java
+++ b/core/store/dist/src/main/java/org/onosproject/store/host/impl/ECHostStore.java
@@ -1,282 +1,282 @@
-/*
- * Copyright 2015 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.store.host.impl;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static org.onosproject.net.DefaultAnnotations.merge;
-import static org.onosproject.net.host.HostEvent.Type.HOST_ADDED;
-import static org.onosproject.net.host.HostEvent.Type.HOST_REMOVED;
-import static org.onosproject.net.host.HostEvent.Type.HOST_UPDATED;
-import static org.onosproject.store.service.EventuallyConsistentMapEvent.Type.PUT;
-import static org.onosproject.store.service.EventuallyConsistentMapEvent.Type.REMOVE;
-import static org.slf4j.LoggerFactory.getLogger;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Objects;
-import java.util.Set;
-import java.util.function.Predicate;
-import java.util.stream.Collectors;
-
-import org.apache.felix.scr.annotations.Activate;
-import org.apache.felix.scr.annotations.Component;
-import org.apache.felix.scr.annotations.Deactivate;
-import org.apache.felix.scr.annotations.Reference;
-import org.apache.felix.scr.annotations.ReferenceCardinality;
-import org.apache.felix.scr.annotations.Service;
-import org.onlab.packet.IpAddress;
-import org.onlab.packet.MacAddress;
-import org.onlab.packet.VlanId;
-import org.onlab.util.KryoNamespace;
-import org.onosproject.net.Annotations;
-import org.onosproject.net.ConnectPoint;
-import org.onosproject.net.DefaultAnnotations;
-import org.onosproject.net.DefaultHost;
-import org.onosproject.net.DeviceId;
-import org.onosproject.net.Host;
-import org.onosproject.net.HostId;
-import org.onosproject.net.host.HostDescription;
-import org.onosproject.net.host.HostEvent;
-import org.onosproject.net.host.HostStore;
-import org.onosproject.net.host.HostStoreDelegate;
-import org.onosproject.net.host.PortAddresses;
-import org.onosproject.net.host.HostEvent.Type;
-import org.onosproject.net.provider.ProviderId;
-import org.onosproject.store.AbstractStore;
-import org.onosproject.store.serializers.KryoNamespaces;
-import org.onosproject.store.service.EventuallyConsistentMap;
-import org.onosproject.store.service.EventuallyConsistentMapEvent;
-import org.onosproject.store.service.EventuallyConsistentMapListener;
-import org.onosproject.store.service.LogicalClockService;
-import org.onosproject.store.service.StorageService;
-import org.slf4j.Logger;
-
-import com.google.common.collect.HashMultimap;
-import com.google.common.collect.ImmutableMultimap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Multimaps;
-import com.google.common.collect.SetMultimap;
-import com.google.common.collect.Sets;
-
-/**
- * Manages the inventory of hosts using a {@code EventuallyConsistentMap}.
- */
-@Component(immediate = true)
-@Service
-public class ECHostStore
-    extends AbstractStore<HostEvent, HostStoreDelegate>
-    implements HostStore {
-
-    private final Logger log = getLogger(getClass());
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected StorageService storageService;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected LogicalClockService clockService;
-
-    // Hosts tracked by their location
-    private final SetMultimap<ConnectPoint, Host> locations =
-            Multimaps.synchronizedSetMultimap(
-                    HashMultimap.<ConnectPoint, Host>create());
-
-    private final SetMultimap<ConnectPoint, PortAddresses> portAddresses =
-            Multimaps.synchronizedSetMultimap(
-                    HashMultimap.<ConnectPoint, PortAddresses>create());
-
-    private EventuallyConsistentMap<HostId, DefaultHost> hosts;
-
-    private EventuallyConsistentMapListener<HostId, DefaultHost> hostLocationTracker =
-            new HostLocationTracker();
-
-    @Activate
-    public void activate() {
-        KryoNamespace.Builder hostSerializer = KryoNamespace.newBuilder()
-                .register(KryoNamespaces.API);
-
-        hosts = storageService.<HostId, DefaultHost>eventuallyConsistentMapBuilder()
-                .withName("onos-hosts")
-                .withSerializer(hostSerializer)
-                .withTimestampProvider((k, v) -> clockService.getTimestamp())
-                .build();
-
-        hosts.addListener(hostLocationTracker);
-
-        log.info("Started");
-    }
-
-    @Deactivate
-    public void deactivate() {
-        hosts.removeListener(hostLocationTracker);
-        hosts.destroy();
-        locations.clear();
-        portAddresses.clear();
-
-        log.info("Stopped");
-    }
-
-    @Override
-    public HostEvent createOrUpdateHost(ProviderId providerId,
-            HostId hostId,
-            HostDescription hostDescription) {
-        DefaultHost currentHost = hosts.get(hostId);
-        if (currentHost == null) {
-            DefaultHost newhost = new DefaultHost(
-                        providerId,
-                        hostId,
-                        hostDescription.hwAddress(),
-                        hostDescription.vlan(),
-                        hostDescription.location(),
-                        ImmutableSet.copyOf(hostDescription.ipAddress()),
-                        hostDescription.annotations());
-            hosts.put(hostId, newhost);
-            return new HostEvent(HOST_ADDED, newhost);
-        }
-        return updateHost(providerId, hostId, hostDescription, currentHost);
-    }
-
-    @Override
-    public HostEvent removeHost(HostId hostId) {
-        Host host = hosts.remove(hostId);
-        return host != null ? new HostEvent(HOST_REMOVED, host) : null;
-    }
-
-    @Override
-    public int getHostCount() {
-        return hosts.size();
-    }
-
-    @Override
-    public Iterable<Host> getHosts() {
-        return ImmutableSet.copyOf(hosts.values());
-    }
-
-    @Override
-    public Host getHost(HostId hostId) {
-        return hosts.get(hostId);
-    }
-
-    @Override
-    public Set<Host> getHosts(VlanId vlanId) {
-        return filter(hosts.values(), host -> Objects.equals(host.vlan(), vlanId));
-    }
-
-    @Override
-    public Set<Host> getHosts(MacAddress mac) {
-        return filter(hosts.values(), host -> Objects.equals(host.mac(), mac));
-    }
-
-    @Override
-    public Set<Host> getHosts(IpAddress ip) {
-        return filter(hosts.values(), host -> host.ipAddresses().contains(ip));
-    }
-
-    @Override
-    public Set<Host> getConnectedHosts(ConnectPoint connectPoint) {
-        return ImmutableSet.copyOf(locations.get(connectPoint));
-    }
-
-    @Override
-    public Set<Host> getConnectedHosts(DeviceId deviceId) {
-        return ImmutableMultimap.copyOf(locations)
-                .entries()
-                .stream()
-                .filter(entry -> entry.getKey().deviceId().equals(deviceId))
-                .map(entry -> entry.getValue())
-                .collect(Collectors.toSet());
-    }
-
-    @Override
-    public void updateAddressBindings(PortAddresses addresses) {
-        portAddresses.put(addresses.connectPoint(), addresses);
-    }
-
-    @Override
-    public void removeAddressBindings(PortAddresses addresses) {
-        portAddresses.remove(addresses.connectPoint(), addresses);
-    }
-
-    @Override
-    public void clearAddressBindings(ConnectPoint connectPoint) {
-        portAddresses.removeAll(connectPoint);
-    }
-
-    @Override
-    public Set<PortAddresses> getAddressBindings() {
-        return ImmutableSet.copyOf(portAddresses.values());
-    }
-
-    @Override
-    public Set<PortAddresses> getAddressBindingsForPort(ConnectPoint connectPoint) {
-        synchronized (portAddresses) {
-            Set<PortAddresses> addresses = portAddresses.get(connectPoint);
-            return addresses == null ? Collections.emptySet() : ImmutableSet.copyOf(addresses);
-        }
-    }
-
-    private Set<Host> filter(Collection<DefaultHost> collection, Predicate<DefaultHost> predicate) {
-        return collection.stream().filter(predicate).collect(Collectors.toSet());
-    }
-
-    // checks for type of update to host, sends appropriate event
-    private HostEvent updateHost(ProviderId providerId,
-                                 HostId hostId,
-                                 HostDescription descr,
-                                 DefaultHost currentHost) {
-
-        final boolean hostMoved = !currentHost.location().equals(descr.location());
-        if (hostMoved ||
-                !currentHost.ipAddresses().containsAll(descr.ipAddress()) ||
-                !descr.annotations().keys().isEmpty()) {
-
-            Set<IpAddress> addresses = Sets.newHashSet(currentHost.ipAddresses());
-            addresses.addAll(descr.ipAddress());
-            Annotations annotations = merge((DefaultAnnotations) currentHost.annotations(),
-                                            descr.annotations());
-
-            DefaultHost updatedHost = new DefaultHost(providerId, currentHost.id(),
-                                                currentHost.mac(), currentHost.vlan(),
-                                                descr.location(),
-                                                addresses,
-                                                annotations);
-
-            // TODO: We need a way to detect conflicting changes and abort update.
-            hosts.put(hostId, updatedHost);
-            locations.remove(currentHost.location(), currentHost);
-            locations.put(updatedHost.location(), updatedHost);
-
-            HostEvent.Type eventType = hostMoved ? Type.HOST_MOVED : Type.HOST_UPDATED;
-            return new HostEvent(eventType, updatedHost);
-        }
-        return null;
-    }
-
-    private class HostLocationTracker implements EventuallyConsistentMapListener<HostId, DefaultHost> {
-        @Override
-        public void event(EventuallyConsistentMapEvent<HostId, DefaultHost> event) {
-            DefaultHost host = checkNotNull(event.value());
-            if (event.type() == PUT) {
-                boolean isNew = locations.put(host.location(), host);
-                notifyDelegate(new HostEvent(isNew ? HOST_ADDED : HOST_UPDATED, host));
-            } else if (event.type() == REMOVE) {
-                if (locations.remove(host.location(), host)) {
-                    notifyDelegate(new HostEvent(HOST_REMOVED, host));
-                }
-
-            }
-        }
-    }
-}
+/*
+ * Copyright 2015 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.store.host.impl;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onosproject.net.DefaultAnnotations.merge;
+import static org.onosproject.net.host.HostEvent.Type.HOST_ADDED;
+import static org.onosproject.net.host.HostEvent.Type.HOST_REMOVED;
+import static org.onosproject.net.host.HostEvent.Type.HOST_UPDATED;
+import static org.onosproject.store.service.EventuallyConsistentMapEvent.Type.PUT;
+import static org.onosproject.store.service.EventuallyConsistentMapEvent.Type.REMOVE;
+import static org.slf4j.LoggerFactory.getLogger;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Objects;
+import java.util.Set;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.apache.felix.scr.annotations.Service;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onlab.util.KryoNamespace;
+import org.onosproject.net.Annotations;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DefaultAnnotations;
+import org.onosproject.net.DefaultHost;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Host;
+import org.onosproject.net.HostId;
+import org.onosproject.net.host.HostDescription;
+import org.onosproject.net.host.HostEvent;
+import org.onosproject.net.host.HostStore;
+import org.onosproject.net.host.HostStoreDelegate;
+import org.onosproject.net.host.PortAddresses;
+import org.onosproject.net.host.HostEvent.Type;
+import org.onosproject.net.provider.ProviderId;
+import org.onosproject.store.AbstractStore;
+import org.onosproject.store.serializers.KryoNamespaces;
+import org.onosproject.store.service.EventuallyConsistentMap;
+import org.onosproject.store.service.EventuallyConsistentMapEvent;
+import org.onosproject.store.service.EventuallyConsistentMapListener;
+import org.onosproject.store.service.LogicalClockService;
+import org.onosproject.store.service.StorageService;
+import org.slf4j.Logger;
+
+import com.google.common.collect.HashMultimap;
+import com.google.common.collect.ImmutableMultimap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Multimaps;
+import com.google.common.collect.SetMultimap;
+import com.google.common.collect.Sets;
+
+/**
+ * Manages the inventory of hosts using a {@code EventuallyConsistentMap}.
+ */
+@Component(immediate = true)
+@Service
+public class ECHostStore
+    extends AbstractStore<HostEvent, HostStoreDelegate>
+    implements HostStore {
+
+    private final Logger log = getLogger(getClass());
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected StorageService storageService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected LogicalClockService clockService;
+
+    // Hosts tracked by their location
+    private final SetMultimap<ConnectPoint, Host> locations =
+            Multimaps.synchronizedSetMultimap(
+                    HashMultimap.<ConnectPoint, Host>create());
+
+    private final SetMultimap<ConnectPoint, PortAddresses> portAddresses =
+            Multimaps.synchronizedSetMultimap(
+                    HashMultimap.<ConnectPoint, PortAddresses>create());
+
+    private EventuallyConsistentMap<HostId, DefaultHost> hosts;
+
+    private EventuallyConsistentMapListener<HostId, DefaultHost> hostLocationTracker =
+            new HostLocationTracker();
+
+    @Activate
+    public void activate() {
+        KryoNamespace.Builder hostSerializer = KryoNamespace.newBuilder()
+                .register(KryoNamespaces.API);
+
+        hosts = storageService.<HostId, DefaultHost>eventuallyConsistentMapBuilder()
+                .withName("onos-hosts")
+                .withSerializer(hostSerializer)
+                .withTimestampProvider((k, v) -> clockService.getTimestamp())
+                .build();
+
+        hosts.addListener(hostLocationTracker);
+
+        log.info("Started");
+    }
+
+    @Deactivate
+    public void deactivate() {
+        hosts.removeListener(hostLocationTracker);
+        hosts.destroy();
+        locations.clear();
+        portAddresses.clear();
+
+        log.info("Stopped");
+    }
+
+    @Override
+    public HostEvent createOrUpdateHost(ProviderId providerId,
+            HostId hostId,
+            HostDescription hostDescription) {
+        DefaultHost currentHost = hosts.get(hostId);
+        if (currentHost == null) {
+            DefaultHost newhost = new DefaultHost(
+                        providerId,
+                        hostId,
+                        hostDescription.hwAddress(),
+                        hostDescription.vlan(),
+                        hostDescription.location(),
+                        ImmutableSet.copyOf(hostDescription.ipAddress()),
+                        hostDescription.annotations());
+            hosts.put(hostId, newhost);
+            return new HostEvent(HOST_ADDED, newhost);
+        }
+        return updateHost(providerId, hostId, hostDescription, currentHost);
+    }
+
+    @Override
+    public HostEvent removeHost(HostId hostId) {
+        Host host = hosts.remove(hostId);
+        return host != null ? new HostEvent(HOST_REMOVED, host) : null;
+    }
+
+    @Override
+    public int getHostCount() {
+        return hosts.size();
+    }
+
+    @Override
+    public Iterable<Host> getHosts() {
+        return ImmutableSet.copyOf(hosts.values());
+    }
+
+    @Override
+    public Host getHost(HostId hostId) {
+        return hosts.get(hostId);
+    }
+
+    @Override
+    public Set<Host> getHosts(VlanId vlanId) {
+        return filter(hosts.values(), host -> Objects.equals(host.vlan(), vlanId));
+    }
+
+    @Override
+    public Set<Host> getHosts(MacAddress mac) {
+        return filter(hosts.values(), host -> Objects.equals(host.mac(), mac));
+    }
+
+    @Override
+    public Set<Host> getHosts(IpAddress ip) {
+        return filter(hosts.values(), host -> host.ipAddresses().contains(ip));
+    }
+
+    @Override
+    public Set<Host> getConnectedHosts(ConnectPoint connectPoint) {
+        return ImmutableSet.copyOf(locations.get(connectPoint));
+    }
+
+    @Override
+    public Set<Host> getConnectedHosts(DeviceId deviceId) {
+        return ImmutableMultimap.copyOf(locations)
+                .entries()
+                .stream()
+                .filter(entry -> entry.getKey().deviceId().equals(deviceId))
+                .map(entry -> entry.getValue())
+                .collect(Collectors.toSet());
+    }
+
+    @Override
+    public void updateAddressBindings(PortAddresses addresses) {
+        portAddresses.put(addresses.connectPoint(), addresses);
+    }
+
+    @Override
+    public void removeAddressBindings(PortAddresses addresses) {
+        portAddresses.remove(addresses.connectPoint(), addresses);
+    }
+
+    @Override
+    public void clearAddressBindings(ConnectPoint connectPoint) {
+        portAddresses.removeAll(connectPoint);
+    }
+
+    @Override
+    public Set<PortAddresses> getAddressBindings() {
+        return ImmutableSet.copyOf(portAddresses.values());
+    }
+
+    @Override
+    public Set<PortAddresses> getAddressBindingsForPort(ConnectPoint connectPoint) {
+        synchronized (portAddresses) {
+            Set<PortAddresses> addresses = portAddresses.get(connectPoint);
+            return addresses == null ? Collections.emptySet() : ImmutableSet.copyOf(addresses);
+        }
+    }
+
+    private Set<Host> filter(Collection<DefaultHost> collection, Predicate<DefaultHost> predicate) {
+        return collection.stream().filter(predicate).collect(Collectors.toSet());
+    }
+
+    // checks for type of update to host, sends appropriate event
+    private HostEvent updateHost(ProviderId providerId,
+                                 HostId hostId,
+                                 HostDescription descr,
+                                 DefaultHost currentHost) {
+
+        final boolean hostMoved = !currentHost.location().equals(descr.location());
+        if (hostMoved ||
+                !currentHost.ipAddresses().containsAll(descr.ipAddress()) ||
+                !descr.annotations().keys().isEmpty()) {
+
+            Set<IpAddress> addresses = Sets.newHashSet(currentHost.ipAddresses());
+            addresses.addAll(descr.ipAddress());
+            Annotations annotations = merge((DefaultAnnotations) currentHost.annotations(),
+                                            descr.annotations());
+
+            DefaultHost updatedHost = new DefaultHost(providerId, currentHost.id(),
+                                                currentHost.mac(), currentHost.vlan(),
+                                                descr.location(),
+                                                addresses,
+                                                annotations);
+
+            // TODO: We need a way to detect conflicting changes and abort update.
+            hosts.put(hostId, updatedHost);
+            locations.remove(currentHost.location(), currentHost);
+            locations.put(updatedHost.location(), updatedHost);
+
+            HostEvent.Type eventType = hostMoved ? Type.HOST_MOVED : Type.HOST_UPDATED;
+            return new HostEvent(eventType, updatedHost);
+        }
+        return null;
+    }
+
+    private class HostLocationTracker implements EventuallyConsistentMapListener<HostId, DefaultHost> {
+        @Override
+        public void event(EventuallyConsistentMapEvent<HostId, DefaultHost> event) {
+            DefaultHost host = checkNotNull(event.value());
+            if (event.type() == PUT) {
+                boolean isNew = locations.put(host.location(), host);
+                notifyDelegate(new HostEvent(isNew ? HOST_ADDED : HOST_UPDATED, host));
+            } else if (event.type() == REMOVE) {
+                if (locations.remove(host.location(), host)) {
+                    notifyDelegate(new HostEvent(HOST_REMOVED, host));
+                }
+
+            }
+        }
+    }
+}
