add overriding state to navigation

Change-Id: If8da57830a7bf48d0bc6a59c5870b51459d95876
(cherry picked from commit 6c64fdc62a46dccc91a5b902617339b813a59738)
diff --git a/src/app/core/services/navigation.spec.ts b/src/app/core/services/navigation.spec.ts
index bc27772..b9cb84c 100644
--- a/src/app/core/services/navigation.spec.ts
+++ b/src/app/core/services/navigation.spec.ts
@@ -116,7 +116,7 @@
     service.add(testRoute);
     service.add(testRoute);
     expect($log.warn).toHaveBeenCalled();
-    expect($log.warn).toHaveBeenCalledWith(`[XosNavigation] Route with label: ${testRoute.label}, state: ${testRoute.state} and parent: ${testRoute.parent} already exist`);
+    expect($log.warn).toHaveBeenCalledWith(`[XosNavigation] Route with label: ${testRoute.label}, state: ${testRoute.state} and parent: ${testRoute.parent} already exists`);
     expect(service.query()).toEqual(defaultRoutes.concat([testRoute]));
   });
 });
diff --git a/src/app/core/services/navigation.ts b/src/app/core/services/navigation.ts
index e7fa4ed..660c144 100644
--- a/src/app/core/services/navigation.ts
+++ b/src/app/core/services/navigation.ts
@@ -71,24 +71,27 @@
     return this.routes;
   }
 
-  add(route: IXosNavigationRoute) {
+  add(route: IXosNavigationRoute, override: boolean = false) {
     if (angular.isDefined(route.state) && angular.isDefined(route.url)) {
       throw new Error('[XosNavigation] You can\'t provide both state and url');
     }
 
     // NOTE factor this out in a separate method an eventually use recursion since we can nest more routes
+    let preExisting = null;
     const routeExist = _.findIndex(this.routes, (r: IXosNavigationRoute) => {
-      if (r.label === route.label && r.state === route.state && r.parent === route.parent) {
+      if (r.label === route.label && (r.state === route.state || override) && r.parent === route.parent) {
+        preExisting = r;
         return true;
       }
       else if (_.findIndex(r.children, route) > -1) {
+        preExisting = r;
         return true;
       }
       return false;
     }) > -1;
 
-    if (routeExist) {
-      this.$log.warn(`[XosNavigation] Route with label: ${route.label}, state: ${route.state} and parent: ${route.parent} already exist`);
+    if (routeExist && !override) {
+      this.$log.warn(`[XosNavigation] Route with label: ${route.label}, state: ${route.state} and parent: ${route.parent} already exists`);
       return;
     }
 
@@ -97,6 +100,9 @@
       const parentRoute = _.find(this.routes, {state: route.parent});
       if (angular.isDefined(parentRoute)) {
         if (angular.isArray(parentRoute.children)) {
+          if (override) {
+            _.remove(parentRoute.children, r => r === preExisting);
+          }
           parentRoute.children.push(route);
         }
         else {
@@ -104,11 +110,14 @@
         }
       }
       else {
-        this.$log.warn(`[XosNavigation] Parent State (${route.parent}) for state: ${route.state} does not exists`);
+        this.$log.warn(`[XosNavigation] Parent State (${route.parent}) for state: ${route.state} does not exist`);
         return;
       }
     }
     else {
+      if (override) {
+        _.remove(this.routes, r => r === preExisting);
+      }
       this.routes.push(route);
     }
   }