diff --git a/src/app/service-graph/components/coarse/coarse.component.scss b/src/app/service-graph/components/coarse/coarse.component.scss
deleted file mode 100644
index fabfb91..0000000
--- a/src/app/service-graph/components/coarse/coarse.component.scss
+++ /dev/null
@@ -1,59 +0,0 @@
-
-/*
- * Copyright 2017-present Open Networking Foundation
-
- * 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.
- */
-
-
-@import './../../../style/vars.scss';
-@import '../../../../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/variables';
-
-xos-coarse-tenancy-graph {
-  display: block;
-  // background: $color-accent;
-
-  svg {
-    height: 400px;
-    width: 100%;
-    background-color: $panel-filled-bg;
-    border-radius: 3px;
-  }
-
-  .node-group {
-
-    .node {
-      cursor: pointer;
-    }
-
-    .node > rect {
-      stroke: $color-accent;
-      fill: $background-color;
-    }
-
-    .node > text {
-      fill: #fff;
-      font-size: 20px;
-    }
-  }
-
-  .link-group {
-    line {
-      stroke: $color-accent;
-    }
-  }
-  .arrow-marker {
-    stroke: $color-accent;
-    fill: $color-accent;
-  }
-}
\ No newline at end of file
diff --git a/src/app/service-graph/components/coarse/coarse.component.ts b/src/app/service-graph/components/coarse/coarse.component.ts
deleted file mode 100644
index c8e2361..0000000
--- a/src/app/service-graph/components/coarse/coarse.component.ts
+++ /dev/null
@@ -1,265 +0,0 @@
-
-/*
- * Copyright 2017-present Open Networking Foundation
-
- * 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.
- */
-
-
-import './coarse.component.scss';
-import * as d3 from 'd3';
-import * as $ from 'jquery';
-import * as _ from 'lodash';
-import {IXosServiceGraphStore} from '../../services/service-graph.store';
-import {IXosServiceGraph, IXosServiceGraphNode, IXosServiceGraphLink} from '../../interfaces';
-import {XosServiceGraphConfig as config} from '../../graph.config';
-import {IXosDebouncer} from '../../../core/services/helpers/debounce.helper';
-import {Subscription} from 'rxjs';
-import {IXosGraphHelpers} from '../../services/d3-helpers/graph.helpers';
-import {IXosServiceGraphReducer, IXosServiceGraphExtender} from '../../services/graph.extender';
-
-class XosCoarseTenancyGraphCtrl {
-
-  static $inject = [
-    '$log',
-    'XosServiceGraphStore',
-    'XosDebouncer',
-    'XosGraphHelpers',
-    'XosServiceGraphExtender'
-  ];
-
-  public graph: IXosServiceGraph;
-
-  private CoarseGraphSubscription: Subscription;
-  private svg;
-  private forceLayout;
-  private linkGroup;
-  private nodeGroup;
-  private textSize = 20;
-  private textOffset = this.textSize / 4;
-
-  // debounced functions
-  private renderGraph;
-
-  constructor (
-    private $log: ng.ILogService,
-    private XosServiceGraphStore: IXosServiceGraphStore,
-    private XosDebouncer: IXosDebouncer,
-    private XosGraphHelpers: IXosGraphHelpers,
-    private XosServiceGraphExtender: IXosServiceGraphExtender
-  ) {
-
-  }
-
-  $onInit() {
-    this.renderGraph = this.XosDebouncer.debounce(this._renderGraph, 500, this);
-
-    this.CoarseGraphSubscription = this.XosServiceGraphStore.getCoarse()
-      .subscribe(
-        (graph: IXosServiceGraph) => {
-          this.$log.debug(`[XosCoarseTenancyGraph] Coarse Event and render`, graph);
-
-          // id there are no data, do nothing
-          if (graph.nodes.length === 0) {
-            return;
-          }
-          this.graph = graph;
-
-          _.forEach(this.XosServiceGraphExtender.getCoarse(), (r: IXosServiceGraphReducer) => {
-            graph = r.reducer(graph);
-          });
-          this.renderGraph();
-        },
-        err => {
-          this.$log.error(`[XosCoarseTenancyGraph] Coarse Event error`, err);
-        });
-
-    this.handleSvg();
-    this.setupForceLayout();
-
-    $(window).on('resize', () => {
-      this.setupForceLayout();
-      this.renderGraph();
-    });
-  }
-
-  $onDestroy() {
-    this.CoarseGraphSubscription.unsubscribe();
-  }
-
-  private _renderGraph() {
-    if (!angular.isDefined(this.graph) || !angular.isDefined(this.graph.nodes) || !angular.isDefined(this.graph.links)) {
-      return;
-    }
-    this.addNodeLinksToForceLayout(this.graph);
-    this.renderNodes(this.graph.nodes);
-    this.renderLinks(this.graph.links);
-  }
-
-  private getSvgDimensions(): {width: number, height: number} {
-    return {
-      width: $('xos-coarse-tenancy-graph svg').width() || 0,
-      height: $('xos-coarse-tenancy-graph svg').height() || 0
-    };
-  }
-
-  private handleSvg() {
-    this.svg = d3.select('svg');
-
-    this.svg.append('svg:defs')
-      .selectAll('marker')
-      .data(config.markers)
-      .enter()
-      .append('svg:marker')
-      .attr('id', d => d.id)
-      .attr('viewBox', d => d.viewBox)
-      .attr('refX', d => d.refX)
-      .attr('refY', d => d.refY)
-      .attr('markerWidth', d => d.width)
-      .attr('markerHeight', d => d.height)
-      .attr('orient', 'auto')
-      .attr('class', d => `${d.id}-marker`)
-      .append('svg:path')
-      .attr('d', d => d.path);
-
-    this.linkGroup = this.svg.append('g')
-      .attr({
-        class: 'link-group'
-      });
-
-    this.nodeGroup = this.svg.append('g')
-      .attr({
-        class: 'node-group'
-      });
-  }
-
-  private collide(n: any) {
-    const svgDim = this.getSvgDimensions();
-    const x = Math.max(n.width / 2, Math.min(n.x, svgDim.width - (n.width / 2)));
-    const y = Math.max(n.height / 2, Math.min(n.y, svgDim.height - (n.height / 2)));
-    return `${x}, ${y}`;
-  }
-
-  private setupForceLayout() {
-
-    let svgDim = this.getSvgDimensions();
-
-    const tick = () => {
-
-      this.nodeGroup.selectAll('g.node')
-        .attr({
-          transform: d => `translate(${this.collide(d)})`
-        });
-
-      this.linkGroup.selectAll('line')
-        .attr({
-          x1: l => l.source.x || 0,
-          y1: l => l.source.y || 0,
-          x2: l => l.target.x || 0,
-          y2: l => l.target.y || 0,
-        });
-    };
-
-    this.forceLayout = d3.layout.force()
-      .size([svgDim.width, svgDim.height])
-      .linkDistance(config.force.linkDistance)
-      .charge(config.force.charge)
-      .gravity(config.force.gravity)
-      .on('tick', tick);
-  }
-
-  private addNodeLinksToForceLayout(data: IXosServiceGraph) {
-    this.forceLayout
-      .nodes(data.nodes)
-      .links(data.links)
-      .start();
-  }
-
-  private renderNodes(nodes: IXosServiceGraphNode[]) {
-    const self = this;
-    const node = this.nodeGroup
-      .selectAll('g.node')
-      .data(nodes, n => n.id);
-
-    const svgDim = this.getSvgDimensions();
-    const entering = node.enter()
-      .append('g')
-      .attr({
-        id: n => n.id,
-        class: n => `node ${this.XosGraphHelpers.parseElemClasses(n.d3Class)}`,
-        transform: `translate(${svgDim.width / 2}, ${svgDim.height / 2})`
-      })
-      .call(this.forceLayout.drag)
-      .on('mousedown', () => {
-        d3.event.stopPropagation();
-      })
-      .on('mouseup', (d) => {
-        d.fixed = true;
-      });
-
-    entering.append('rect')
-      .attr({
-        rx: config.node.radius,
-        ry: config.node.radius
-      });
-
-    entering.append('text')
-      .attr({
-        'text-anchor': 'middle',
-        'transform': `translate(0,${this.textOffset})`
-      })
-      .text(n => n.label);
-      // .text(n => `${n.id} - ${n.label}`);
-
-    const existing = node.selectAll('rect');
-
-    // resize node > rect as contained text
-
-    existing.each(function(d: any) {
-      const textBBox = self.XosGraphHelpers.getSiblingTextBBox(this);
-      const rect = d3.select(this);
-      rect.attr({
-        width: textBBox.width + config.node.padding,
-        height: textBBox.height + config.node.padding,
-        x: textBBox.x - (config.node.padding / 2),
-        y: (textBBox.y + self.textOffset) - (config.node.padding / 2)
-      });
-      d.width = textBBox.width + config.node.padding;
-      d.height = textBBox.height + config.node.padding;
-    });
-
-  }
-
-  private renderLinks(links: IXosServiceGraphLink[]) {
-    const link = this.linkGroup
-      .selectAll('line')
-      .data(links, l => l.id);
-
-    const entering = link.enter();
-
-    // TODO read classes from graph links
-
-    entering.append('line')
-      .attr({
-        id: n => n.id,
-        class: l => `link ${this.XosGraphHelpers.parseElemClasses(l.d3Class)}`,
-        'marker-start': 'url(#arrow)'
-      });
-  }
-}
-
-export const XosCoarseTenancyGraph: angular.IComponentOptions = {
-  template: require('./coarse.component.html'),
-  controllerAs: 'vm',
-  controller: XosCoarseTenancyGraphCtrl,
-};
diff --git a/src/app/service-graph/components/fine-grained/fine-grained.component.html b/src/app/service-graph/components/fine-grained/fine-grained.component.html
deleted file mode 100644
index 2e8b92e..0000000
--- a/src/app/service-graph/components/fine-grained/fine-grained.component.html
+++ /dev/null
@@ -1,22 +0,0 @@
-
-<!--
-Copyright 2017-present Open Networking Foundation
-
-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.
--->
-
-
-<h1>Fine Grained Tenancy Graph</h1>
-
-<svg>
-</svg>
diff --git a/src/app/service-graph/components/fine-grained/fine-grained.component.scss b/src/app/service-graph/components/fine-grained/fine-grained.component.scss
deleted file mode 100644
index 29ea116..0000000
--- a/src/app/service-graph/components/fine-grained/fine-grained.component.scss
+++ /dev/null
@@ -1,96 +0,0 @@
-
-/*
- * Copyright 2017-present Open Networking Foundation
-
- * 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.
- */
-
-
-@import './../../../style/vars.scss';
-@import '../../../../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/variables';
-
-xos-fine-grained-tenancy-graph {
-  display: block;
-  height: 100%;
-  // background: $color-accent;
-
-  svg {
-    height: 90%;
-    width: 100%;
-    background-color: $panel-filled-bg;
-    border-radius: 3px;
-  }
-
-  .node-group {
-
-    .node {
-      cursor: pointer;
-    }
-
-    .node .symbol {
-        fill-rule: evenodd;
-        stroke: #bbddff;
-        stroke-width: 4.0px;
-        fill: none;
-    }
-    .node .symbol-bg {
-        fill-rule: evenodd;
-        stroke: none;
-        fill: $background-color;
-    }
-
-    .node {
-      rect, circle {
-        stroke: $color-accent;
-        fill: $background-color;
-      }
-
-      &.network > circle{
-        stroke: blue;
-      }
-
-      &.tenant, &.serviceinstance > rect{
-        stroke: green;
-      }
-
-      &.subscriber > rect,
-      &.tenantroot > rect{
-        stroke: red;
-      }
-    }
-
-    .node > text {
-      fill: #fff;
-      font-size: 20px;
-    }
-  }
-
-  .link-group {
-    line {
-      stroke: $color-accent;
-
-      &.ext-service-instance {
-        stroke: green;
-      }
-
-      &.ext-owner {
-        stroke: green;
-        stroke-dasharray: 5;
-      }
-    }
-  }
-  .arrow-marker {
-    stroke: $color-accent;
-    fill: $color-accent;
-  }
-}
\ No newline at end of file
diff --git a/src/app/service-graph/components/fine-grained/fine-grained.component.ts b/src/app/service-graph/components/fine-grained/fine-grained.component.ts
deleted file mode 100644
index 7d21131..0000000
--- a/src/app/service-graph/components/fine-grained/fine-grained.component.ts
+++ /dev/null
@@ -1,388 +0,0 @@
-
-/*
- * Copyright 2017-present Open Networking Foundation
-
- * 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.
- */
-
-
-import './fine-grained.component.scss';
-import * as d3 from 'd3';
-import * as $ from 'jquery';
-import * as _ from 'lodash';
-import {Subscription} from 'rxjs';
-import {XosServiceGraphConfig as config} from '../../graph.config';
-import {IXosDebouncer} from '../../../core/services/helpers/debounce.helper';
-import {IXosServiceGraph, IXosServiceGraphLink, IXosServiceGraphNode} from '../../interfaces';
-import {IXosSidePanelService} from '../../../core/side-panel/side-panel.service';
-import {IXosGraphHelpers} from '../../services/d3-helpers/graph.helpers';
-import {IXosServiceGraphExtender, IXosServiceGraphReducer} from '../../services/graph.extender';
-import {IXosServiceInstanceGraphStore} from '../../services/service-instance.graph.store';
-import {IXosModeldefsCache} from '../../../datasources/helpers/modeldefs.service';
-
-class XosFineGrainedTenancyGraphCtrl {
-  static $inject = [
-    '$log',
-    'XosServiceInstanceGraphStore',
-    'XosDebouncer',
-    'XosModelDiscoverer',
-    'XosSidePanel',
-    'XosGraphHelpers',
-    'XosServiceGraphExtender'
-  ];
-
-  public graph: IXosServiceGraph;
-
-  private GraphSubscription: Subscription;
-  private svg;
-  private forceLayout;
-  private linkGroup;
-  private nodeGroup;
-  private defs;
-  private textSize = 20;
-  private textOffset = this.textSize / 4;
-
-  // debounced functions
-  private renderGraph;
-
-  constructor(
-    private $log: ng.ILogService,
-    private XosServiceInstanceGraphStore: IXosServiceInstanceGraphStore,
-    private XosDebouncer: IXosDebouncer,
-    private XosModeldefsCache: IXosModeldefsCache,
-    private XosSidePanel: IXosSidePanelService,
-    private XosGraphHelpers: IXosGraphHelpers,
-    private XosServiceGraphExtender: IXosServiceGraphExtender
-  ) {
-    this.handleSvg();
-    this.loadDefs();
-    this.setupForceLayout();
-    this.renderGraph = this.XosDebouncer.debounce(this._renderGraph, 1000, this);
-
-    $(window).on('resize', () => {
-      this.setupForceLayout();
-      this.renderGraph();
-    });
-
-    this.GraphSubscription = this.XosServiceInstanceGraphStore.get()
-      .subscribe(
-        (graph) => {
-          this.$log.debug(`[XosServiceInstanceGraphStore] Fine-Grained Event and render`, graph);
-
-          if (!graph || !graph.nodes || !graph.links) {
-            return;
-          }
-
-          _.forEach(this.XosServiceGraphExtender.getFinegrained(), (r: IXosServiceGraphReducer) => {
-            graph = r.reducer(graph);
-          });
-
-          this.graph = graph;
-          this.renderGraph();
-        },
-        (err) => {
-          this.$log.error(`[XosFineGrainedTenancyGraphCtrl] Error: `, err);
-        }
-      );
-  }
-
-  $onDestroy() {
-    this.GraphSubscription.unsubscribe();
-  }
-
-  private _renderGraph() {
-    if (!angular.isDefined(this.graph) || !angular.isDefined(this.graph.nodes) || !angular.isDefined(this.graph.links)) {
-      return;
-    }
-    this.addNodeLinksToForceLayout(this.graph);
-    this.renderNodes(this.graph.nodes);
-    this.renderLinks(this.graph.links);
-  }
-
-  private getSvgDimensions(): {width: number, height: number} {
-    return {
-      width: $('xos-fine-grained-tenancy-graph svg').width(),
-      height: $('xos-fine-grained-tenancy-graph svg').height()
-    };
-  }
-
-  private handleSvg() {
-    this.svg = d3.select('svg');
-
-    this.defs = this.svg.append('defs');
-
-    this.linkGroup = this.svg.append('g')
-      .attr({
-        class: 'link-group'
-      });
-
-    this.nodeGroup = this.svg.append('g')
-      .attr({
-        class: 'node-group'
-      });
-  }
-
-  private loadDefs() {
-      const cloud = {
-          vbox: '0 0 303.8 185.8',
-          path: `M88.6,44.3c31.7-45.5,102.1-66.7,135-3
-             M37.8,142.9c-22.5,3.5-60.3-32.4-16.3-64.2
-             M101.8,154.2c-15.6,59.7-121.4,18.8-77.3-13
-             M194.6,150c-35.4,51.8-85.7,34.3-98.8-9.5
-             M274.4,116.4c29.4,73.2-81.9,80.3-87.7,44.3
-             M28.5,89.2C3.7,77.4,55.5,4.8,95.3,36.1
-             M216.1,28.9C270.9-13,340.8,91,278.4,131.1`,
-          bgpath: `M22,78.3C21.5,55.1,62.3,10.2,95.2,36
-             h0c31.9-33.4,88.1-50.5,120.6-7.2l0.3,0.2
-             C270.9-13,340.8,91,278.4,131.1v-0.5
-             c10.5,59.8-86.4,63.7-91.8,30.1h-0.4
-             c-30.2,33.6-67.6,24-84.6-6v-0.4
-             c-15.6,59.7-121.4,18.8-77.3-13
-             l-0.2-.2c-20.2-7.9-38.6-36.5-2.8-62.3Z`
-      };
-
-      this.defs.append('symbol')
-          .attr({ id: 'cloud', viewBox: cloud.vbox })
-          .append('path').attr('d', cloud.path);
-
-      this.defs.append('symbol')
-          .attr({ id: 'cloud_bg', viewBox: cloud.vbox })
-          .append('path').attr('d', cloud.bgpath);
-  }
-
-  private setupForceLayout() {
-    this.$log.debug(`[XosFineGrainedTenancyGraphCtrl] Setup Force Layout`);
-    const tick = () => {
-      this.nodeGroup.selectAll('g.node')
-        .attr({
-          transform: d => `translate(${d.x}, ${d.y})`
-        });
-
-      this.linkGroup.selectAll('line')
-        .attr({
-          x1: l => l.source.x || 0,
-          y1: l => l.source.y || 0,
-          x2: l => l.target.x || 0,
-          y2: l => l.target.y || 0,
-        });
-    };
-    const getLinkStrenght = (l: IXosServiceGraphLink) => {
-      return 1;
-    };
-    const svgDim = this.getSvgDimensions();
-    this.forceLayout = d3.layout.force()
-      .size([svgDim.width, svgDim.height])
-      .linkDistance(config.force.linkDistance)
-      .linkStrength(l => getLinkStrenght(l))
-      .charge(config.force.charge)
-      .gravity(config.force.gravity)
-      .on('tick', tick);
-  }
-
-  private addNodeLinksToForceLayout(data: IXosServiceGraph) {
-    this.forceLayout
-      .nodes(data.nodes)
-      .links(data.links)
-      .start();
-  }
-
-  private renderServiceNodes(nodes: any) {
-
-    const self = this;
-
-    nodes.append('rect')
-    .attr({
-      rx: config.node.radius,
-      ry: config.node.radius
-    });
-
-    nodes.append('text')
-      .attr({
-        'text-anchor': 'middle',
-        'transform': `translate(0,${this.textOffset})`
-      })
-      .text(n => n.label);
-    // .text(n => `${n.id} - ${n.label}`);
-
-    const existing = nodes.selectAll('rect');
-
-    // resize node > rect as contained text
-    existing.each(function() {
-      const textBBox = self.XosGraphHelpers.getSiblingTextBBox(this);
-      const rect = d3.select(this);
-      rect.attr({
-        width: textBBox.width + config.node.padding,
-        height: textBBox.height + config.node.padding,
-        x: textBBox.x - (config.node.padding / 2),
-        y: (textBBox.y + self.textOffset) - (config.node.padding / 2)
-      });
-    });
-  }
-
-  private renderTenantNodes(nodes: any) {
-    nodes.append('rect')
-      .attr({
-        width: 40,
-        height: 40,
-        x: -20,
-        y: -20,
-        transform: `rotate(45)`
-      });
-
-    nodes.append('text')
-      .attr({
-        'text-anchor': 'middle',
-        'transform': `translate(0,${this.textOffset})`
-      })
-      .text(n => n.label);
-  }
-
-  private renderNetworkNodes(nodes: any) {
-    const self = this;
-
-    nodes.append('use')
-        .attr({
-            class: 'symbol-bg',
-            'xlink:href': '#cloud_bg'
-        });
-
-    nodes.append('use')
-        .attr({
-            class: 'symbol',
-            'xlink:href': '#cloud'
-        });
-
-    nodes.append('text')
-      .attr({
-          'text-anchor': 'middle',
-          'transform': `translate(0,${this.textOffset})`
-      })
-      .text(n => n.label);
-
-    const existing = nodes.selectAll('use');
-
-    // resize node > rect as contained text
-    existing.each(function() {
-      const textBBox = self.XosGraphHelpers.getSiblingTextBBox(this);
-      const useElem = d3.select(this);
-      const w = textBBox.width + config.node.padding * 2;
-      const h = w;
-      const xoff = -(w / 2);
-      const yoff = -(h / 2);
-
-      useElem.attr({
-          width: w,
-          height: h,
-          transform: 'translate(' + xoff + ',' + yoff + ')'
-      });
-    });
-  }
-
-  private renderSubscriberNodes(nodes: any) {
-    const self = this;
-    nodes.append('rect');
-
-    nodes.append('text')
-      .attr({
-        'text-anchor': 'middle',
-        'transform': `translate(0,${this.textOffset})`
-      })
-      .text(n => n.label);
-
-    const existing = nodes.selectAll('rect');
-
-    // resize node > rect as contained text
-    existing.each(function() {
-      const textBBox = self.XosGraphHelpers.getSiblingTextBBox(this);
-      const rect = d3.select(this);
-      rect.attr({
-        width: textBBox.width + config.node.padding,
-        height: textBBox.height + config.node.padding,
-        x: textBBox.x - (config.node.padding / 2),
-        y: (textBBox.y + self.textOffset) - (config.node.padding / 2)
-      });
-    });
-  }
-
-  private renderNodes(nodes: IXosServiceGraphNode[]) {
-    const node = this.nodeGroup
-      .selectAll('g.node')
-      .data(nodes, n => n.id);
-
-    let mouseEventsTimer, selectedModel;
-    const svgDim = this.getSvgDimensions();
-    const hStep = svgDim.width / (nodes.length - 1);
-    const vStep = svgDim.height / (nodes.length - 1);
-    const entering = node.enter()
-      .append('g')
-      .attr({
-        id: n => n.id,
-        class: n => `node ${n.type} ${this.XosGraphHelpers.parseElemClasses(n.d3Class)}`,
-        transform: (n, i) => `translate(${hStep * i}, ${vStep * i})`
-      })
-      .call(this.forceLayout.drag)
-      .on('mousedown', () => {
-        mouseEventsTimer = new Date().getTime();
-        d3.event.stopPropagation();
-      })
-      .on('mouseup', (n) => {
-        mouseEventsTimer = new Date().getTime() - mouseEventsTimer;
-        n.fixed = true;
-      })
-      .on('click', (n: IXosServiceGraphNode) => {
-        if (mouseEventsTimer > 100) {
-          // it is a drag
-          return;
-        }
-        if (selectedModel === n.id) {
-          // this model is already selected, so close the panel
-          this.XosSidePanel.removeInjectedComponents();
-          selectedModel = null;
-          return;
-        }
-        selectedModel = n.id;
-        const modelName = n.model['class_names'].split(',')[0];
-        const formConfig = this.XosModeldefsCache.get(modelName).formCfg;
-        const model = angular.copy(n.model);
-        delete model.d3Id;
-        this.XosSidePanel.injectComponent('xosForm', {config: formConfig, ngModel: model});
-      });
-
-    this.renderServiceNodes(entering.filter('.service'));
-    this.renderTenantNodes(entering.filter('.serviceinstance'));
-    this.renderNetworkNodes(entering.filter('.network'));
-    this.renderSubscriberNodes(entering.filter('.subscriber'));
-    // this.renderSubscriberNodes(entering.filter('.tenantroot'));
-  }
-
-  private renderLinks(links: IXosServiceGraphLink[]) {
-    const link = this.linkGroup
-      .selectAll('line')
-      .data(links, l => l.id);
-
-    const entering = link.enter();
-
-    entering.append('line')
-      .attr({
-        id: n => n.id,
-        class: n => `link ${this.XosGraphHelpers.parseElemClasses(n.d3Class)}`,
-        'marker-start': 'url(#arrow)'
-      });
-  }
-}
-
-export const XosFineGrainedTenancyGraph: angular.IComponentOptions = {
-  template: require('./fine-grained.component.html'),
-  controllerAs: 'vm',
-  controller: XosFineGrainedTenancyGraphCtrl,
-};
diff --git a/src/app/service-graph/components/coarse/coarse.component.html b/src/app/service-graph/components/graph/graph.component.html
similarity index 69%
rename from src/app/service-graph/components/coarse/coarse.component.html
rename to src/app/service-graph/components/graph/graph.component.html
index c0bb4e5..6510a9f 100644
--- a/src/app/service-graph/components/coarse/coarse.component.html
+++ b/src/app/service-graph/components/graph/graph.component.html
@@ -1,4 +1,3 @@
-
 <!--
 Copyright 2017-present Open Networking Foundation
 
@@ -15,8 +14,12 @@
 limitations under the License.
 -->
 
+<h1>Service Graph</h1>
 
-<h1>Service Dependency Graph</h1>
-
-<svg>
-</svg>
+<div class="graph-container">
+  <div class="loader-container" ng-if="vm.loader">
+    <div class="loader"></div>
+  </div>
+  <a ng-click="vm.closeFullscreen()" class="close-btn"><i class="fa fa-times"></i></a>
+  <svg></svg>
+</div>
diff --git a/src/app/service-graph/components/graph/graph.component.scss b/src/app/service-graph/components/graph/graph.component.scss
new file mode 100644
index 0000000..40b6f11
--- /dev/null
+++ b/src/app/service-graph/components/graph/graph.component.scss
@@ -0,0 +1,129 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+
+ * 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.
+ */
+
+
+@import './../../../style/vars.scss';
+@import '../../../../../node_modules/bootstrap-sass/assets/stylesheets/bootstrap/variables';
+
+$svg-size: 600px;
+
+xos-service-graph {
+  display: block;
+  // background: $color-accent;
+
+  .graph-container {
+    position: relative;
+
+    .loader-container {
+      position: absolute;
+      left: 0;
+      top: 0;
+      height: $svg-size;
+      width: 100%;
+    }
+  }
+
+  svg {
+    height: $svg-size;
+    width: 100%;
+    background-color: $panel-filled-bg;
+    border-radius: 3px;
+  }
+
+  .close-btn {
+    display: none;
+  }
+
+  .fullscreen {
+    svg {
+      z-index: 1040;
+      width: 100%;
+      height: 100%;
+      position: fixed;
+      top: 0;
+      left: 0;
+      background-color: $background-color;
+      transition: all .5s;
+    }
+
+    .close-btn {
+      cursor: pointer;
+      display: block;
+      position: fixed;
+      top: 10px;
+      right: 10px;
+      z-index: 1041;
+    }
+  }
+
+  .node-group {
+
+    .node {
+      cursor: pointer;
+    }
+
+    .node.service {
+      > rect {
+        stroke: $color-accent;
+        fill: $background-color;
+      }
+      > .icon {
+        fill: $color-accent;
+      }
+    }
+
+    .node.serviceinstance {
+      > rect {
+        stroke: green;
+        fill: $background-color;
+      }
+      > .icon {
+        fill: green;
+      }
+    }
+
+    .node {
+      >.label {
+        >text {
+          fill: #fff;
+        }
+        >rect {
+          fill: $background-color;
+          stroke: #fff;
+        }
+      }
+    }
+  }
+
+  .link-group {
+    line {
+      stroke: $color-accent;
+    }
+
+    line.ownership {
+      stroke: green;
+      stroke-dasharray: 5;
+    }
+
+    line.serviceinstancelink {
+      stroke: green;
+    }
+  }
+  .arrow-marker {
+    stroke: $color-accent;
+    fill: $color-accent;
+  }
+}
\ No newline at end of file
diff --git a/src/app/service-graph/components/graph/graph.component.ts b/src/app/service-graph/components/graph/graph.component.ts
new file mode 100644
index 0000000..5769b6f
--- /dev/null
+++ b/src/app/service-graph/components/graph/graph.component.ts
@@ -0,0 +1,192 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+
+ * 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.
+ */
+
+import './graph.component.scss';
+
+import * as d3 from 'd3';
+import * as $ from 'jquery';
+
+import {IXosGraphStore} from '../../services/graph.store';
+import {Subscription} from 'rxjs/Subscription';
+import {XosServiceGraphConfig as config} from '../../graph.config';
+import {IXosGraphHelpers} from '../../services/d3-helpers/graph-elements.helpers';
+import {IXosServiceGraphIcons} from '../../services/d3-helpers/graph-icons.service';
+import {IXosNodePositioner} from '../../services/node-positioner.service';
+import {IXosNodeRenderer} from '../../services/renderer/node.renderer';
+import {IXosSgNode} from '../../interfaces';
+import {IXosGraphConfig} from '../../services/graph.config';
+
+class XosServiceGraphCtrl {
+  static $inject = [
+    '$log',
+    '$scope',
+    'XosGraphStore',
+    'XosGraphHelpers',
+    'XosServiceGraphIcons',
+    'XosNodePositioner',
+    'XosNodeRenderer',
+    'XosGraphConfig'
+  ];
+
+  public loader: boolean = true;
+
+  private GraphSubscription: Subscription;
+  private graph: any; // this is the Graph instance
+
+  // graph element
+  private svg;
+  private linkGroup;
+  private nodeGroup;
+  private forceLayout;
+
+  constructor (
+    private $log: ng.ILogService,
+    private $scope: ng.IScope,
+    private XosGraphStore: IXosGraphStore,
+    private XosGraphHelpers: IXosGraphHelpers,
+    private XosServiceGraphIcons: IXosServiceGraphIcons,
+    private XosNodePositioner: IXosNodePositioner,
+    private XosNodeRenderer: IXosNodeRenderer,
+    private XosGraphConfig: IXosGraphConfig
+  ) {
+    this.$log.info('[XosServiceGraph] Component setup');
+
+    this.XosGraphConfig.setupKeyboardShortcuts();
+
+    this.setupSvg();
+    this.setupForceLayout();
+
+    this.GraphSubscription = this.XosGraphStore.get()
+      .subscribe(
+        graph => {
+          this.graph = graph;
+          if (this.graph.nodes().length > 0) {
+            this.loader = false;
+            this.renderGraph(this.graph);
+          }
+        },
+        error => {
+          this.$log.error('[XosServiceGraph] XosGraphStore observable error: ', error);
+        }
+      );
+
+    this.$scope.$on('xos.sg.update', () => {
+      this.$log.info(`[XosServiceGraph] Received event: xos.sg.update`);
+      this.renderGraph(this.graph);
+    });
+  }
+
+  $onDestroy() {
+    this.GraphSubscription.unsubscribe();
+  }
+
+  public closeFullscreen() {
+    this.XosGraphConfig.toggleFullscreen();
+  }
+
+  private setupSvg() {
+    this.svg = d3.select('xos-service-graph svg');
+
+    this.linkGroup = this.svg.append('g')
+      .attr({
+        class: 'link-group'
+      });
+
+    this.nodeGroup = this.svg.append('g')
+      .attr({
+        class: 'node-group'
+      });
+  }
+
+  private setupForceLayout() {
+    this.$log.debug(`[XosServiceGraph] Setup Force Layout`);
+    const tick = () => {
+      this.nodeGroup.selectAll('g.node')
+        .attr({
+          transform: d => `translate(${d.x}, ${d.y})`
+        });
+
+      this.linkGroup.selectAll('line')
+        .attr({
+          x1: l => l.source.x || 0,
+          y1: l => l.source.y || 0,
+          x2: l => l.target.x || 0,
+          y2: l => l.target.y || 0,
+        });
+    };
+
+    const svgDim = this.getSvgDimensions();
+
+    this.forceLayout =
+      d3.layout.force()
+      .size([svgDim.width, svgDim.height])
+      .on('tick', tick);
+  }
+
+  private getSvgDimensions(): {width: number, height: number} {
+    return {
+      width: $('xos-service-graph svg').width(),
+      height: $('xos-service-graph svg').height()
+    };
+  }
+
+  private renderGraph(graph: any) {
+    let nodes: IXosSgNode[] = this.XosGraphStore.nodesFromGraph(graph);
+    let links = this.XosGraphStore.linksFromGraph(graph);
+    const svgDim = this.getSvgDimensions();
+
+    this.XosNodePositioner.positionNodes(svgDim, nodes)
+      .then((nodes: IXosSgNode[]) => {
+
+        this.forceLayout
+          .nodes(nodes)
+          .links(links)
+          .size([svgDim.width, svgDim.height])
+          .linkDistance(config.force.linkDistance)
+          .charge(config.force.charge)
+          .gravity(config.force.gravity)
+          .start();
+
+        // render nodes
+        this.XosNodeRenderer.renderNodes(this.forceLayout, this.nodeGroup, nodes);
+        this.renderLinks(links);
+      });
+  }
+
+  private renderLinks(links: any[]) {
+
+    const link = this.linkGroup
+      .selectAll('line')
+      .data(links, l => l.id);
+
+    const entering = link.enter();
+
+    entering.append('line')
+      .attr({
+        id: n => n.id,
+        class: n => n.type
+      });
+
+    link.exit().remove();
+  }
+
+}
+
+export const XosServiceGraph: angular.IComponentOptions = {
+  template: require('./graph.component.html'),
+  controllerAs: 'vm',
+  controller: XosServiceGraphCtrl,
+};
diff --git a/src/app/service-graph/graph.config.ts b/src/app/service-graph/graph.config.ts
index abfd415..13a8939 100644
--- a/src/app/service-graph/graph.config.ts
+++ b/src/app/service-graph/graph.config.ts
@@ -27,6 +27,7 @@
 }
 
 export interface IXosServiceGraphConfig {
+  duration: number;
   force: {
     linkDistance: number;
     charge: number;
@@ -35,11 +36,13 @@
   node: {
     padding: number;
     radius: number;
+    text: number;
   };
   markers: ISvgMarker[];
 }
 
 export const XosServiceGraphConfig: IXosServiceGraphConfig = {
+  duration: 750,
   force: {
     linkDistance: 80,
     charge: -60,
@@ -47,7 +50,8 @@
   },
   node: {
     padding: 10,
-    radius: 2
+    radius: 2,
+    text: 14
   },
   markers: [
     {
diff --git a/src/app/service-graph/index.ts b/src/app/service-graph/index.ts
index 2acb259..770862d 100644
--- a/src/app/service-graph/index.ts
+++ b/src/app/service-graph/index.ts
@@ -1,4 +1,3 @@
-
 /*
  * Copyright 2017-present Open Networking Foundation
 
@@ -15,32 +14,30 @@
  * limitations under the License.
  */
 
-
-import {xosDataSources} from '../datasources/index';
-import {XosServiceGraphStore} from './services/service-graph.store';
-import {xosCore} from '../core/index';
-import {XosCoarseTenancyGraph} from './components/coarse/coarse.component';
-import {XosFineGrainedTenancyGraph} from './components/fine-grained/fine-grained.component';
 import {XosServiceGraphExtender, IXosServiceGraphExtender} from './services/graph.extender';
-import {XosGraphHelpers} from './services/d3-helpers/graph.helpers';
-import {XosServiceInstanceGraphStore} from './services/service-instance.graph.store';
+import {XosGraphHelpers} from './services/d3-helpers/graph-elements.helpers';
+import {XosServiceGraph} from './components/graph/graph.component';
+import {XosGraphStore} from './services/graph.store';
+import {XosServiceGraphIcons} from './services/d3-helpers/graph-icons.service';
+import {XosNodePositioner} from './services/node-positioner.service';
+import {XosGraphConfig} from './services/graph.config';
+import {XosNodeRenderer} from './services/renderer/node.renderer';
+
 export const xosServiceGraph = 'xosServiceGraph';
 
 angular
-  .module(xosServiceGraph, [xosDataSources, xosCore])
-  .service('XosServiceGraphStore', XosServiceGraphStore)
-  .service('XosServiceInstanceGraphStore', XosServiceInstanceGraphStore)
+  .module(xosServiceGraph, [])
   .service('XosServiceGraphExtender', XosServiceGraphExtender)
   .service('XosGraphHelpers', XosGraphHelpers)
-  .component('xosCoarseTenancyGraph', XosCoarseTenancyGraph)
-  .component('xosFineGrainedTenancyGraph', XosFineGrainedTenancyGraph)
-  .config(($stateProvider) => {
-    $stateProvider
-      .state('xos.fine-grained-graph', {
-        url: 'tenancy-graph',
-        component: 'xosFineGrainedTenancyGraph',
-      });
-  })
-  .run(($log: ng.ILogService, XosServiceGraphExtender: IXosServiceGraphExtender) => {
+  .service('XosGraphStore', XosGraphStore)
+  .service('XosServiceGraphIcons', XosServiceGraphIcons)
+  .service('XosNodePositioner', XosNodePositioner)
+  .service('XosGraphConfig', XosGraphConfig)
+  .service('XosNodeRenderer', XosNodeRenderer)
+  .component('xosServiceGraph', XosServiceGraph)
+  .run((
+    $log: ng.ILogService,
+    XosServiceGraphExtender: IXosServiceGraphExtender
+  ) => {
     $log.info(`[${xosServiceGraph}] Module Setup`);
   });
diff --git a/src/app/service-graph/interfaces.ts b/src/app/service-graph/interfaces.ts
index af55c54..861ba75 100644
--- a/src/app/service-graph/interfaces.ts
+++ b/src/app/service-graph/interfaces.ts
@@ -1,4 +1,3 @@
-
 /*
  * Copyright 2017-present Open Networking Foundation
 
@@ -15,95 +14,42 @@
  * limitations under the License.
  */
 
-
 interface Id3Element {
-  d3Class?: string;
-  d3Id?: string;
-}
-
-export interface IXosServiceModel {
-  id: number;
-  d3Id?: string;
-  backend_status: string;
-  kind: string;
-  name: string;
-  class_names: string;
-  service_specific_attributes: string; // this is json stringified
-}
-
-export interface IXosTenantModel extends Id3Element {
-  id: number;
-  d3Id?: string;
-  backend_status: string;
-  kind: string;
-
-  // source
-  provider_service_id: number;
-
-  // destination
-  subscriber_service_id: number;
-  subscriber_tenant_id: number;
-  subscriber_root_id: number;
-  subscriber_network_id: number;
-
-  subscriber_user_id: number;
-
-  // extra informations
-  service_specific_id: string;
-  service_specific_attribute: string;
-  connect_method: string;
-
-  // reverse of subscriber tenants
-  subscribed_tenants_ids: number[];
-}
-
-export interface IXosCoarseGraphData {
-  services: IXosServiceModel[];
-  servicedependencies: any[];
-}
-
-// TODO outdated, remove
-export interface IXosFineGrainedGraphData extends IXosCoarseGraphData {
-  tenants: IXosTenantModel[];
-  subscribers: any[];
-  networks: any[];
-}
-
-export interface IXosServiceInstanceGraphData {
-  serviceGraph: IXosServiceGraph;
-  serviceInstances: any[];
-  serviceInstanceLinks: any[];
-  networks: any[];
-}
-
-export interface IXosServiceGraphNodeBadge {
-  type: 'info'|'success'|'warning'|'danger';
-  text: string;
-}
-
-export interface IXosServiceGraphNode extends Id3Element {
-  id: number | string;
-  label: string;
-  x?: number;
-  y?: number;
-  px?: number;
-  py?: number;
-  width?: number;
-  height?: number;
+  x: number;
+  y: number;
   fixed?: boolean;
-  badge?: IXosServiceGraphNodeBadge; // TODO implement badges
-  model: IXosServiceModel;
-  type: 'service' | 'tenant' | 'network' | 'subscriber';
 }
 
-export interface IXosServiceGraphLink extends Id3Element {
+export interface IXosSgNode extends Id3Element {
   id: string;
+  data: any; // this can be a Service, ServiceInstance or Instance
+
+  // do we need those?
+  type: string;
+  d3Class?: string;
+}
+
+export interface IXosSgLink {
+  id: string;
+  type: string;
   source: number;
   target: number;
-  model: IXosTenantModel;
+  data: any; // this can be a ServiceDependency, ServiceInstanceLink or a representation of ServiceInstance.owner_id
 }
 
-export interface IXosServiceGraph {
-  nodes: IXosServiceGraphNode[];
-  links: IXosServiceGraphLink[];
+export interface IXosSgConfig {
+  labels: boolean;
+}
+
+export interface IXosBaseModel {
+  id: number;
+  class_names: string;
+  name?: string;
+  [x: string]: any; // allow extra properties
+}
+
+export interface IXosOwnershipLink {
+  service: number;
+  service_instance: number;
+  type: 'ownership';
 }
diff --git a/src/app/service-graph/services/d3-helpers/graph-elements.helpers.ts b/src/app/service-graph/services/d3-helpers/graph-elements.helpers.ts
new file mode 100644
index 0000000..bbacbdc
--- /dev/null
+++ b/src/app/service-graph/services/d3-helpers/graph-elements.helpers.ts
@@ -0,0 +1,67 @@
+
+/*
+ * Copyright 2017-present Open Networking Foundation
+
+ * 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.
+ */
+
+
+import * as d3 from 'd3';
+import {XosServiceGraphConfig as config} from '../../graph.config';
+
+export interface Id3BBox {
+  x?: number;
+  y?: number;
+  width: number;
+  height: number;
+}
+
+export interface IXosGraphHelpers {
+  parseElemClasses (classes: string): string;
+  getBBox(context: any): Id3BBox;
+  getSiblingTextBBox(contex: any /* D3 this */): Id3BBox;
+  getSiblingIconBBox(contex: any /* D3 this */): Id3BBox;
+  getSiblingBBox(contex: any): Id3BBox;
+}
+
+export class XosGraphHelpers implements IXosGraphHelpers {
+  public parseElemClasses (classes: string): string {
+    return angular.isDefined(classes) ? classes.split(' ')
+      .map(c => `ext-${c}`)
+      .join(' ') : '';
+  }
+
+  public getBBox(context: any): Id3BBox {
+    return d3.select(context).node().getBBox();
+  }
+
+  public getSiblingTextBBox(contex: any): Id3BBox {
+    const text: d3.Selection<any> = d3.select(contex.parentNode).select('text');
+    return text.empty() ? {width: 0, height: 0} : text.node().getBBox();
+  }
+
+  public getSiblingIconBBox(contex: any): Id3BBox {
+    return d3.select(contex.parentNode).select('path').node().getBBox();
+  }
+
+  public getSiblingBBox(contex: any): Id3BBox {
+    // NOTE consider that inside a node we can have 1 text and 1 icon
+    const textBBox: Id3BBox = this.getSiblingTextBBox(contex);
+    const iconBBox: Id3BBox = this.getSiblingIconBBox(contex);
+
+    return {
+      width: iconBBox.width + (textBBox.width ? config.node.padding + textBBox.width : 0),
+      height: iconBBox.height
+    };
+  }
+}
diff --git a/src/app/service-graph/services/d3-helpers/graph-icons.service.ts b/src/app/service-graph/services/d3-helpers/graph-icons.service.ts
new file mode 100644
index 0000000..9baeb57
--- /dev/null
+++ b/src/app/service-graph/services/d3-helpers/graph-icons.service.ts
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+
+ * 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.
+ */
+
+import * as _ from 'lodash';
+
+export interface IXosServiceGraphIcon {
+  name: string;
+  path: string;
+  transform: string; // do we need it??
+}
+
+const icons: IXosServiceGraphIcon[] = [
+  {
+    name: 'service',
+    path: 'M.08,15.51V10.7h0L1.5,10.5,3,10.29s0,0,.06,0A10.13,10.13,0,0,1,3.9,8.05a.11.11,0,0,0,0-.12L2.24,5.66s0-.08,0-.12Q3.91,3.91,5.56,2.26a.08.08,0,0,1,.1,0L7.87,3.83a.21.21,0,0,0,.25,0A10,10,0,0,1,10.17,3s0,0,.05-.05l.09-.56c.11-.65.22-1.29.32-1.94a2.57,2.57,0,0,0,.06-.4h4.78a.11.11,0,0,0,0,.08c.15.92.31,1.84.46,2.76a.07.07,0,0,0,.06.06,11.76,11.76,0,0,1,2.11.88.09.09,0,0,0,.12,0l2.34-1.62a.05.05,0,0,1,.08,0l3.28,3.36a.05.05,0,0,1,0,.08L23.66,6c-.47.63-.93,1.27-1.39,1.91,0,0,0,.06,0,.1l.14.25a9.19,9.19,0,0,1,.74,1.88s0,.06.06.06l.8.13,1.76.3a1.17,1.17,0,0,0,.32,0v4.81H26l-1.41.22-1.26.19c-.14,0-.14,0-.18.15v0a10.33,10.33,0,0,1-.84,2,.1.1,0,0,0,0,.12L24,20.56c0,.05,0,.07,0,.11-1.09,1.1-2.18,2.19-3.26,3.29,0,0-.06,0-.09,0L18.3,22.31a.11.11,0,0,0-.16,0,11,11,0,0,1-2.07.86.11.11,0,0,0-.08.09c-.05.33-.11.66-.16,1-.1.59-.2,1.18-.29,1.77,0,.06,0,.07-.09.07H10.83c-.07,0-.09,0-.1-.08-.15-.91-.31-1.82-.46-2.72,0,0,0-.05,0-.06s-.2,0-.3-.09a10.59,10.59,0,0,1-1.87-.79.09.09,0,0,0-.11,0L5.62,24s-.08,0-.12,0L2.24,20.72s0,0,0-.1c.55-.78,1.1-1.56,1.66-2.33a.11.11,0,0,0,0-.12A9.87,9.87,0,0,1,3,16S3,16,3,16l-.72-.12-1.76-.3C.35,15.55.22,15.52.08,15.51Zm13,2.61a5,5,0,1,0-5-5A5,5,0,0,0,13.08,18.12Z',
+    transform: 'translate(-0.08 -0.04)'
+  },
+  {
+    name: 'serviceinstance',
+    path: 'M11.87,19.94v5.47c0,.61-.18.72-.69.42l-9.6-5.55a.62.62,0,0,1-.32-.64c0-3.64,0-7.29,0-10.94,0-.7.16-.79.79-.42,2.89,1.67,5.77,3.39,8.69,5a1.81,1.81,0,0,1,1.14,2C11.8,16.81,11.87,18.38,11.87,19.94Z\n' +
+    'M13,0a1,1,0,0,1,.53.2l9.4,5.45c.54.32.54.45,0,.78C19.78,8.2,16.7,10,13.63,11.74a1.12,1.12,0,0,1-1.24,0C9.28,9.92,6.15,8.12,3,6.31c-.55-.31-.55-.46,0-.78L12.45.19A.86.86,0,0,1,13,0Z\n' +
+    'M24.73,14.16c0,1.81,0,3.61,0,5.42a.8.8,0,0,1-.46.79l-9.36,5.41c-.64.38-.79.29-.79-.47,0-3.53,0-7.07,0-10.6a.92.92,0,0,1,.52-.94q4.63-2.65,9.26-5.35l.24-.14c.43-.2.58-.11.58.36Z',
+    transform: ''
+  }
+];
+
+export interface IXosServiceGraphIcons {
+  get(icon: string): IXosServiceGraphIcon;
+}
+
+export class XosServiceGraphIcons implements IXosServiceGraphIcons {
+  public get(icon: string): IXosServiceGraphIcon {
+    return _.find(icons, {name: icon});
+  }
+}
diff --git a/src/app/service-graph/services/d3-helpers/graph.helpers.ts b/src/app/service-graph/services/d3-helpers/graph.helpers.ts
deleted file mode 100644
index 15988cd..0000000
--- a/src/app/service-graph/services/d3-helpers/graph.helpers.ts
+++ /dev/null
@@ -1,43 +0,0 @@
-
-/*
- * Copyright 2017-present Open Networking Foundation
-
- * 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.
- */
-
-
-import * as d3 from 'd3';
-
-export interface Id3BBox {
-  x: number;
-  y: number;
-  width: number;
-  height: number;
-}
-
-export interface IXosGraphHelpers {
-  parseElemClasses (classes: string): string;
-  getSiblingTextBBox(contex: any /* D3 this */): Id3BBox;
-}
-
-export class XosGraphHelpers implements IXosGraphHelpers {
-  public parseElemClasses (classes: string): string {
-    return classes ? classes.split(' ')
-      .map(c => `ext-${c}`)
-      .join(' ') : '';
-  }
-
-  public getSiblingTextBBox(contex: any): Id3BBox {
-    return d3.select(contex.parentNode).select('text').node().getBBox();
-  }
-}
diff --git a/src/app/service-graph/services/graph.config.ts b/src/app/service-graph/services/graph.config.ts
new file mode 100644
index 0000000..6c58c3a
--- /dev/null
+++ b/src/app/service-graph/services/graph.config.ts
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+
+ * 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.
+ */
+
+import * as $ from 'jquery';
+import {IXosKeyboardShortcutService} from '../../core/services/keyboard-shortcut';
+import {IXosSgConfig} from '../interfaces';
+import {IXosGraphStore} from './graph.store';
+
+export interface IXosGraphConfig {
+  getUserConfig(): IXosSgConfig;
+  setupKeyboardShortcuts(): void;
+  toggleFullscreen(): void;
+}
+
+export class XosGraphConfig {
+
+  static $inject = [
+    '$log',
+    '$cookies',
+    '$rootScope',
+    '$timeout',
+    'XosKeyboardShortcut',
+    'XosGraphStore'
+  ];
+
+  private defaultUserConfig: IXosSgConfig = {
+    labels: false
+  };
+
+  private userConfig: IXosSgConfig = this.defaultUserConfig;
+
+  constructor (
+    private $log: ng.ILogService,
+    private $cookies: ng.cookies.ICookiesService,
+    private $rootScope: ng.IRootScopeService,
+    private $timeout: ng.ITimeoutService,
+    private XosKeyboardShortcut: IXosKeyboardShortcutService,
+    private XosGraphStore: IXosGraphStore
+  ) {
+    this.userConfig = this.getUserConfig();
+
+
+  }
+
+  public setupKeyboardShortcuts() {
+
+    this.$log.info(`[XosGraphConfig] Setting up keyboard shortcuts`);
+
+    // Setup keyboard shortcuts
+    this.XosKeyboardShortcut.registerKeyBinding({
+      key: 'f',
+      modifiers: ['shift'],
+      cb: () => {
+        this.toggleFullscreen();
+      },
+      label: 'f',
+      description: 'Toggle graph fullscreen'
+    });
+
+    this.XosKeyboardShortcut.registerKeyBinding({
+      key: 's',
+      modifiers: ['shift'],
+      cb: () => {
+        // NOTE anytime the graph change the observable is updated,
+        // no need to manually retrigger here
+        this.XosGraphStore.toggleServiceInstances();
+      },
+      label: 's',
+      description: 'Toggle ServiceInstances'
+    });
+  }
+
+  public toggleFullscreen() {
+    $('.graph-container').toggleClass('fullscreen');
+    this.$timeout(() => {
+      // NOTE wait for the CSS transition to complete before repositioning
+      this.$rootScope.$broadcast('xos.sg.update');
+    }, 500);
+  }
+
+  public getUserConfig(): IXosSgConfig {
+    let config = this.$cookies.get('xos-service-graph-user-config');
+    if (!config || config.length === 0) {
+      this.$cookies.put('xos-service-graph-user-config', JSON.stringify(this.defaultUserConfig));
+      config = this.$cookies.get('xos-service-graph-user-config');
+    }
+    return JSON.parse(config);
+  }
+}
diff --git a/src/app/service-graph/services/graph.extender.ts b/src/app/service-graph/services/graph.extender.ts
index a601e87..467e34b 100644
--- a/src/app/service-graph/services/graph.extender.ts
+++ b/src/app/service-graph/services/graph.extender.ts
@@ -16,7 +16,9 @@
  */
 
 
-import {IXosServiceGraph} from '../interfaces';
+
+
+import {Graph} from 'graphlib';
 
 export interface IXosServiceGraphReducers {
   coarse: IXosServiceGraphReducer[];
@@ -29,7 +31,7 @@
 }
 
 export interface IXosServiceGraphReducerFn {
-  (graph: IXosServiceGraph): IXosServiceGraph;
+  (graph: Graph): Graph;
 }
 
 export interface IXosServiceGraphExtender {
diff --git a/src/app/service-graph/services/graph.store.spec.ts b/src/app/service-graph/services/graph.store.spec.ts
new file mode 100644
index 0000000..a41809c
--- /dev/null
+++ b/src/app/service-graph/services/graph.store.spec.ts
@@ -0,0 +1,334 @@
+
+/*
+ * Copyright 2017-present Open Networking Foundation
+
+ * 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.
+ */
+
+import * as _ from 'lodash';
+import * as angular from 'angular';
+import 'angular-mocks';
+import {IXosGraphStore, XosGraphStore} from './graph.store';
+import {Subject} from 'rxjs/Subject';
+import {Graph} from 'graphlib';
+import {XosDebouncer} from '../../core/services/helpers/debounce.helper';
+
+interface ITestXosGraphStore extends IXosGraphStore {
+
+  // state
+  serviceGraph: Graph;
+  serviceInstanceShown: boolean;
+
+  // private methods
+  getNodeId: any;
+  getModelType: any;
+  addNode: any;
+  addEdge: any;
+  nodesFromGraph: any;
+  toggleServiceInstances: any;
+
+  // observables
+  ServiceInstanceSubscription: any;
+  ServiceInstanceLinkSubscription: any;
+}
+
+let service: ITestXosGraphStore;
+
+let scope: ng.IRootScopeService;
+
+const services = [
+  {
+    id: 1,
+    class_names: 'Service,XOSBase',
+    name: 'Service 1'
+  },
+  {
+    id: 2,
+    class_names: 'Service,XOSBase',
+    name: 'Service 2'
+  }
+];
+
+const servicedependencies = [
+  {
+    id: 1,
+    class_names: 'ServiceDependency,XOSBase',
+    provider_service_id: 2,
+    subscriber_service_id: 1
+  }
+];
+
+const serviceInstances = [
+  {
+    id: 1,
+    class_names: 'ServiceInstance,XOSBase',
+    name: 'ServiceInstance 1',
+    owner_id: 1
+  },
+  {
+    id: 2,
+    class_names: 'ServiceInstance,XOSBase',
+    name: 'ServiceInstance 2',
+    owner_id: 2
+  }
+];
+
+const serviceInstanceLinks = [
+  {
+    id: 1,
+    class_names: 'ServiceInstanceLink,XOSBase',
+    provider_service_instance_id: 1,
+    subscriber_service_instance_id: 2,
+  }
+];
+
+const subject_services = new Subject();
+const subject_servicedependency = new Subject();
+const subject_serviceinstances = new Subject();
+const subject_serviceinstancelinks = new Subject();
+
+let MockModelStore = {
+  query: jasmine.createSpy('XosModelStore.query')
+    .and.callFake((model) => {
+      if (model === 'Service') {
+        return subject_services.asObservable();
+      }
+      else if (model === 'ServiceDependency') {
+        return subject_servicedependency.asObservable();
+      }
+      else if (model === 'ServiceInstance') {
+        return subject_serviceinstances.asObservable();
+      }
+      else if (model === 'ServiceInstanceLink') {
+        return subject_serviceinstancelinks.asObservable();
+      }
+    })
+};
+
+
+describe('The XosGraphStore service', () => {
+
+  beforeEach(() => {
+    angular.module('XosGraphStore', [])
+      .service('XosGraphStore', XosGraphStore)
+      .value('XosModelStore', MockModelStore)
+      .service('XosDebouncer', XosDebouncer);
+
+    angular.mock.module('XosGraphStore');
+  });
+
+  beforeEach(angular.mock.inject((XosGraphStore: ITestXosGraphStore,
+                                  $rootScope: ng.IRootScopeService,
+                                  _$q_: ng.IQService) => {
+
+    service = XosGraphStore;
+    scope = $rootScope;
+
+  }));
+
+  it('should load services and service-dependency and add nodes to the graph', (done) => {
+    let event = 0;
+    service.get().subscribe(
+      (graph: Graph) => {
+        if (event === 1) {
+          expect(graph.nodes().length).toBe(services.length);
+          expect(graph.nodes()).toEqual(['service~1', 'service~2']);
+          expect(graph.edges().length).toBe(servicedependencies.length);
+          expect(graph.edges()).toEqual([{v: 'service~1', w: 'service~2'}]);
+          done();
+        }
+        else {
+          event = event + 1;
+        }
+      }
+    );
+    subject_services.next(services);
+    subject_servicedependency.next(servicedependencies);
+    scope.$apply();
+  });
+
+  describe(`the getModelType`, () => {
+    it('should return the node type', () => {
+      const res = service.getModelType(services[0]);
+      expect(res).toBe('service');
+    });
+
+    it('should return the node type', () => {
+      const res = service.getModelType(serviceInstances[0]);
+      expect(res).toBe('serviceinstance');
+    });
+  });
+
+  describe('the getNodeId method', () => {
+    it('should return the id for a Service', () => {
+      const res = service.getNodeId(services[0]);
+      expect(res).toBe(`service~1`);
+    });
+
+    it('should return the id for a ServiceInstance', () => {
+      const res = service.getNodeId(serviceInstances[0]);
+      expect(res).toBe(`serviceinstance~1`);
+    });
+  });
+
+  describe('the addNode method', () => {
+
+    beforeEach(() => {
+      spyOn(service.serviceGraph, 'setNode');
+      spyOn(service.serviceGraph, 'setEdge');
+    });
+
+    it(`should a service to the graph`, () => {
+      service.addNode(services[0]);
+      expect(service.serviceGraph.setNode).toHaveBeenCalledWith('service~1', services[0]);
+    });
+
+    it('should add a service instance to the graph', () => {
+      service.addNode(serviceInstances[0]);
+      expect(service.serviceGraph.setNode).toHaveBeenCalledWith('serviceinstance~1', serviceInstances[0]);
+    });
+
+    it('should add an "ownership" edge to the graph', () => {
+      service.addNode(serviceInstances[0]);
+      expect(service.serviceGraph.setEdge).toHaveBeenCalledWith('serviceinstance~1', 'service~1', {service: 1, service_instance: 1, type: 'ownership'});
+    });
+  });
+
+  describe('the addEdge method', () => {
+
+    beforeEach(() => {
+      spyOn(service.serviceGraph, 'setEdge');
+    });
+
+    it('should add a ServiceDependency to the graph', () => {
+      service.addEdge(servicedependencies[0]);
+      expect(service.serviceGraph.setEdge).toHaveBeenCalledWith('service~1', 'service~2', servicedependencies[0]);
+    });
+
+    it('should add a ServiceInstanceLink to the graph', () => {
+      service.addEdge(serviceInstanceLinks[0]);
+      expect(service.serviceGraph.setEdge).toHaveBeenCalledWith('serviceinstance~1', 'serviceinstance~2', serviceInstanceLinks[0]);
+    });
+  });
+
+  describe('the nodesFromGraph and linksFromGraph methods', () => {
+    let graph: Graph;
+
+    beforeEach(() => {
+      graph = new Graph();
+      services.forEach(s => {
+        graph.setNode(`service~${s.id}`, s);
+      });
+
+      servicedependencies.forEach(sd => {
+        graph.setEdge('service~1', 'service~2', sd);
+      });
+    });
+
+    it('should add id and type to the nodes', () => {
+      const nodes = service.nodesFromGraph(graph);
+      expect(nodes[0].id).toBe('service~1');
+      expect(nodes[0].type).toBe('service');
+      expect(nodes[0].data).toBeDefined();
+    });
+
+    it('should add id and type to the links', () => {
+      const links = service.linksFromGraph(graph);
+      expect(links[0].id).toBe('service~1-service~2');
+      expect(links[0].type).toBe('servicedependency');
+      expect(links[0].data).toBeDefined();
+    });
+
+    it('should handle ownership links', () => {
+      graph.setNode(`serviceinstance~1`, serviceInstances[0]);
+      graph.setEdge('service~1', 'serviceinstance~1', {type: 'ownership', service: 1, service_instance: 1});
+      const links = service.linksFromGraph(graph);
+      expect(links[1].source).toBe(0);
+      expect(links[1].target).toBe(2);
+    });
+
+    it('should handle serviceinstancelink links', () => {
+      graph.setNode(`serviceinstance~1`, serviceInstances[0]);
+      graph.setNode(`serviceinstance~2`, serviceInstances[1]);
+      graph.setEdge('serviceinstance~1', 'serviceinstance~2', serviceInstanceLinks[0]);
+      const links = service.linksFromGraph(graph);
+      const targetLink = _.find(links, {id: `serviceinstance~1-serviceinstance~2`});
+      expect(targetLink).toBeDefined();
+      expect(targetLink.source).toBe(3);
+      expect(targetLink.target).toBe(2);
+    });
+  });
+
+  describe(`the toggleServiceInstances method`, () => {
+    describe('when they are disabled', () => {
+
+      beforeEach(() => {
+        MockModelStore.query.calls.reset();
+      });
+
+      it('should fetch them', () => {
+        service.toggleServiceInstances();
+        expect(service.serviceInstanceShown).toBeTruthy();
+        expect(MockModelStore.query).toHaveBeenCalledWith(`ServiceInstance`, '/core/serviceinstances');
+        expect(MockModelStore.query).toHaveBeenCalledWith(`ServiceInstanceLink`, '/core/serviceinstancelinks');
+        expect(service.ServiceInstanceSubscription).toBeDefined();
+        expect(service.ServiceInstanceLinkSubscription).toBeDefined();
+      });
+    });
+
+    describe('when they are enabled', () => {
+      beforeEach(() => {
+        service.ServiceInstanceSubscription = {
+          unsubscribe: jasmine.createSpy('ServiceInstanceSubscription')
+        };
+        service.ServiceInstanceLinkSubscription = {
+          unsubscribe: jasmine.createSpy('ServiceInstanceLinkSubscription')
+        };
+        service.serviceInstanceShown = true;
+      });
+
+      it('should cancel subscriptions', () => {
+        service.toggleServiceInstances();
+        expect(service.serviceInstanceShown).toBeFalsy();
+        expect(service.ServiceInstanceSubscription.unsubscribe).toHaveBeenCalled();
+        expect(service.ServiceInstanceLinkSubscription.unsubscribe).toHaveBeenCalled();
+      });
+
+      describe('and loaded in the graph', () => {
+        beforeEach(() => {
+          service.serviceGraph = new Graph();
+
+          services.forEach(s => {
+            service.addNode(s);
+          });
+
+          serviceInstances.forEach(si => {
+            service.addNode(si);
+          });
+
+          serviceInstanceLinks.forEach(sil => {
+            service.addEdge(sil);
+          });
+        });
+        it('should remove ServiceInstance and related nodes/edges from the graph', () => {
+          let filteredGraph = service.toggleServiceInstances();
+          expect(service.serviceInstanceShown).toBeFalsy();
+          expect(filteredGraph.nodes().length).toBe(2);
+          expect(filteredGraph.edges().length).toBe(0);
+          expect(service.serviceGraph.nodes().length).toBe(2);
+          expect(service.serviceGraph.edges().length).toBe(0);
+        });
+      });
+    });
+  });
+});
diff --git a/src/app/service-graph/services/graph.store.ts b/src/app/service-graph/services/graph.store.ts
new file mode 100644
index 0000000..4d46c88
--- /dev/null
+++ b/src/app/service-graph/services/graph.store.ts
@@ -0,0 +1,309 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+
+ * 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.
+ */
+
+
+import * as _ from 'lodash';
+import {Graph} from 'graphlib';
+import {IXosModelStoreService} from '../../datasources/stores/model.store';
+import {IXosDebouncer} from '../../core/services/helpers/debounce.helper';
+import {Subscription} from 'rxjs/Subscription';
+import {BehaviorSubject} from 'rxjs/BehaviorSubject';
+import {Observable} from 'rxjs/Observable';
+import {IXosBaseModel, IXosSgLink, IXosSgNode} from '../interfaces';
+
+
+export interface IXosGraphStore {
+  get(): Observable<Graph>;
+  nodesFromGraph(graph: Graph): IXosSgNode[];
+  linksFromGraph(graph: Graph): IXosSgLink[];
+  toggleServiceInstances(): Graph;
+}
+
+export class XosGraphStore implements IXosGraphStore {
+  static $inject = [
+    '$log',
+    'XosModelStore',
+    'XosDebouncer'
+  ];
+
+  // state
+  private serviceInstanceShown: boolean = false;
+
+  // graphs
+  private serviceGraph: any;
+  private ServiceGraphSubject: BehaviorSubject<any>;
+
+  // datastore
+  private ServiceSubscription: Subscription;
+  private ServiceDependencySubscription: Subscription;
+  private ServiceInstanceSubscription: Subscription;
+  private ServiceInstanceLinkSubscription: Subscription;
+
+  // debounced
+  private efficientNext = this.XosDebouncer.debounce(this.callNext, 500, this, false);
+
+  constructor (
+    private $log: ng.ILogService,
+    private XosModelStore: IXosModelStoreService,
+    private XosDebouncer: IXosDebouncer
+  ) {
+    this.$log.info('[XosGraphStore] Setup');
+
+    this.serviceGraph = new Graph();
+    this.ServiceGraphSubject = new BehaviorSubject(this.serviceGraph);
+
+    this.loadData();
+  }
+
+  $onDestroy() {
+    this.ServiceSubscription.unsubscribe();
+    this.ServiceDependencySubscription.unsubscribe();
+  }
+
+  public nodesFromGraph(graph: Graph): IXosSgNode[] {
+    return _.map(graph.nodes(), (n: string) => {
+      const nodeData = graph.node(n);
+      return {
+        id: n,
+        type: this.getModelType(nodeData),
+        data: nodeData
+      };
+    });
+  }
+
+  public linksFromGraph(graph: Graph): IXosSgLink[] {
+    const nodes = this.nodesFromGraph(graph);
+
+    // NOTE we'll need some intelligence here to differentiate between:
+    // - ServiceDependency
+    // - ServiceInstanceLinks
+    // - Owners
+
+    return _.map(graph.edges(), l => {
+      const link = graph.edge(l);
+      const linkType = this.getModelType(link);
+
+      // FIXME consider ownership links
+      let sourceId, targetId;
+
+      switch (linkType) {
+        case 'servicedependency':
+          sourceId = this.getServiceId(link.subscriber_service_id);
+          targetId = this.getServiceId(link.provider_service_id);
+          break;
+        case 'serviceinstancelink':
+          sourceId = this.getServiceInstanceId(link.subscriber_service_instance_id);
+          targetId = this.getServiceInstanceId(link.provider_service_instance_id);
+          break;
+        case 'ownership':
+          sourceId = this.getServiceId(link.service);
+          targetId = this.getServiceInstanceId(link.service_instance);
+      }
+
+      // NOTE help while debugging
+      if (!sourceId || !targetId) {
+        this.$log.warn(`Link ${l.v}-${l.w} has missing source or target:`, l, link);
+      }
+
+      return {
+        id: `${l.v}-${l.w}`,
+        type: this.getModelType(link),
+        source: _.findIndex(nodes, {id: sourceId}),
+        target: _.findIndex(nodes, {id: targetId}),
+        data: link
+      };
+    });
+  }
+
+  public toggleServiceInstances(): Graph {
+    if (this.serviceInstanceShown) {
+      // NOTE remove subscriptions
+      this.ServiceInstanceSubscription.unsubscribe();
+      this.ServiceInstanceLinkSubscription.unsubscribe();
+
+      // remove nodes from the graph
+      this.removeElementsFromGraph('serviceinstance'); // NOTE links are automatically removed by the graph library
+    }
+    else {
+      // NOTE subscribe to ServiceInstance and ServiceInstanceLink observables
+      this.loadServiceInstances();
+      this.loadServiceInstanceLinks();
+    }
+    this.serviceInstanceShown = !this.serviceInstanceShown;
+    return this.serviceGraph;
+  }
+
+  public get(): Observable<Graph> {
+    return this.ServiceGraphSubject.asObservable();
+  }
+
+  private loadData() {
+    this.loadServices();
+    this.loadServiceDependencies();
+  }
+
+  // graph operations
+  private addNode(node: IXosBaseModel) {
+    const nodeId = this.getNodeId(node);
+    this.serviceGraph.setNode(nodeId, node);
+
+    const nodeType = this.getModelType(node);
+    if (nodeType === 'serviceinstance') {
+      // NOTE adding owner link
+      this.addOwnershipEdge({
+        service: node.owner_id,
+        service_instance: node.id,
+        type: 'ownership'
+      });
+    }
+  }
+
+  private addEdge(link: IXosBaseModel) {
+    const linkType = this.getModelType(link);
+    if (linkType === 'servicedependency') {
+      const sourceId = this.getServiceId(link.subscriber_service_id);
+      const targetId = this.getServiceId(link.provider_service_id);
+      this.serviceGraph.setEdge(sourceId, targetId, link);
+    }
+    if (linkType === 'serviceinstancelink') {
+      // NOTE serviceinstancelink can point also to services, networks, ...
+      const sourceId = this.getServiceInstanceId(link.provider_service_instance_id);
+      if (angular.isDefined(link.subscriber_service_instance_id)) {
+        const targetId = this.getServiceInstanceId(link.subscriber_service_instance_id);
+        this.serviceGraph.setEdge(sourceId, targetId, link);
+      }
+    }
+  }
+
+  private addOwnershipEdge(link: any) {
+    const sourceId = this.getServiceInstanceId(link.service_instance);
+    const targetId = this.getServiceId(link.service);
+    this.serviceGraph.setEdge(sourceId, targetId, link);
+  }
+
+  private removeElementsFromGraph(type: string) {
+    _.forEach(this.serviceGraph.nodes(), (n: string) => {
+      const node = this.serviceGraph.node(n);
+      const nodeType = this.getModelType(node);
+      if (nodeType === type) {
+        this.serviceGraph.removeNode(n);
+      }
+    });
+    // NOTE update the observable
+    this.efficientNext(this.ServiceGraphSubject, this.serviceGraph);
+  }
+
+  // helpers
+  private getModelType(node: IXosBaseModel): string {
+    if (node.type) {
+      // NOTE we'll add "ownership" links
+      return node.type;
+    }
+    return node.class_names.split(',')[0].toLowerCase();
+  }
+
+  private getServiceId(id: number): string {
+    return `service~${id}`;
+  }
+
+  private getServiceInstanceId(id: number): string {
+    return `serviceinstance~${id}`;
+  }
+
+  private getNodeId(node: IXosBaseModel): string {
+
+    const nodeType = this.getModelType(node);
+    switch (nodeType) {
+      case 'service':
+        return this.getServiceId(node.id);
+      case 'serviceinstance':
+        return this.getServiceInstanceId(node.id);
+    }
+  }
+
+  // data loaders
+  private loadServices() {
+    this.ServiceSubscription = this.XosModelStore.query('Service', '/core/services')
+      .subscribe(
+        (res) => {
+          if (res.length > 0) {
+            _.forEach(res, n => {
+              this.addNode(n);
+            });
+            this.efficientNext(this.ServiceGraphSubject, this.serviceGraph);
+          }
+        },
+        (err) => {
+          this.$log.error(`[XosServiceGraphStore] Service Observable: `, err);
+        }
+      );
+  }
+
+  private loadServiceDependencies() {
+    this.ServiceDependencySubscription = this.XosModelStore.query('ServiceDependency', '/core/servicedependencys')
+      .subscribe(
+        (res) => {
+          if (res.length > 0) {
+            _.forEach(res, l => {
+              this.addEdge(l);
+            });
+            this.efficientNext(this.ServiceGraphSubject, this.serviceGraph);
+          }
+        },
+        (err) => {
+          this.$log.error(`[XosServiceGraphStore] Service Observable: `, err);
+        }
+      );
+  }
+
+  private loadServiceInstances() {
+    this.ServiceInstanceSubscription = this.XosModelStore.query('ServiceInstance', '/core/serviceinstances')
+      .subscribe(
+        (res) => {
+          if (res.length > 0) {
+            _.forEach(res, n => {
+              this.addNode(n);
+            });
+            this.efficientNext(this.ServiceGraphSubject, this.serviceGraph);
+          }
+        },
+        (err) => {
+          this.$log.error(`[XosServiceGraphStore] ServiceInstance Observable: `, err);
+        }
+      );
+  }
+
+  private loadServiceInstanceLinks() {
+    this.ServiceInstanceLinkSubscription = this.XosModelStore.query('ServiceInstanceLink', '/core/serviceinstancelinks')
+      .subscribe(
+        (res) => {
+          if (res.length > 0) {
+            _.forEach(res, l => {
+              this.addEdge(l);
+            });
+            this.efficientNext(this.ServiceGraphSubject, this.serviceGraph);
+          }
+        },
+        (err) => {
+          this.$log.error(`[XosServiceGraphStore] ServiceInstanceLinks Observable: `, err);
+        }
+      );
+  }
+
+  private callNext(subject: BehaviorSubject<any>, data: any) {
+    subject.next(data);
+  }
+}
diff --git a/src/app/service-graph/services/node-positioner.service.spec.ts b/src/app/service-graph/services/node-positioner.service.spec.ts
new file mode 100644
index 0000000..14fb9c4
--- /dev/null
+++ b/src/app/service-graph/services/node-positioner.service.spec.ts
@@ -0,0 +1,128 @@
+
+/*
+ * Copyright 2017-present Open Networking Foundation
+
+ * 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.
+ */
+
+
+import * as angular from 'angular';
+import 'angular-mocks';
+import 'angular-ui-router';
+import {IXosNodePositioner, XosNodePositioner} from './node-positioner.service';
+
+let service: IXosNodePositioner;
+
+let scope: ng.IRootScopeService;
+
+let constraints: string = '';
+
+let mockResource = {
+  query: () => {
+    return;
+  }
+};
+
+const mockModelRest = {
+  getResource: jasmine.createSpy('ModelRest.getResource')
+    .and.returnValue(mockResource)
+};
+
+describe('The XosNodePositioner service', () => {
+
+  beforeEach(() => {
+    angular.module('XosNodePositioner', [])
+      .service('XosNodePositioner', XosNodePositioner)
+      .value('ModelRest', mockModelRest);
+
+    angular.mock.module('XosNodePositioner');
+  });
+
+  beforeEach(angular.mock.inject((
+    XosNodePositioner: IXosNodePositioner,
+    $rootScope: ng.IRootScopeService,
+    _$q_: ng.IQService) => {
+
+    service = XosNodePositioner;
+    scope = $rootScope;
+
+    spyOn(mockResource, 'query').and.callFake(() => {
+      const d = _$q_.defer();
+      d.resolve([{constraints}]);
+      return {$promise: d.promise};
+    });
+  }));
+
+  it('should position the nodes on the svg', (done) => {
+    const svg = {width: 300, height: 100};
+    const nodes = [
+      {data: {name: 'a'}},
+      {data: {name: 'b'}}
+    ];
+    constraints = '["a", "b"]';
+    service.positionNodes(svg, nodes)
+      .then((positioned) => {
+        expect(positioned[0].x).toBe(100);
+        expect(positioned[0].y).toBe(50);
+        expect(positioned[1].x).toBe(200);
+        expect(positioned[1].y).toBe(50);
+        done();
+      });
+
+    scope.$apply();
+  });
+
+  it('should position the nodes on the svg in vertical bundles', (done) => {
+    const svg = {width: 300, height: 90};
+    const nodes = [
+      {data: {name: 'a'}},
+      {data: {name: 'b'}},
+      {data: {name: 'c'}}
+    ];
+    constraints = '["a", ["b", "c"]]';
+    service.positionNodes(svg, nodes)
+      .then((positioned) => {
+        expect(positioned[0].x).toBe(100);
+        expect(positioned[0].y).toBe(45);
+        expect(positioned[1].x).toBe(200);
+        expect(positioned[1].y).toBe(30);
+        expect(positioned[2].x).toBe(200);
+        expect(positioned[2].y).toBe(60);
+        done();
+      });
+
+    scope.$apply();
+  });
+
+  it('should accept null as constraint to leave an empty space', (done) => {
+    const svg = {width: 300, height: 90};
+    const nodes = [
+      {data: {name: 'a'}},
+      {data: {name: 'b'}},
+      {data: {name: 'c'}}
+    ];
+    constraints = '[[null, "a"], ["b", "c"]]';
+    service.positionNodes(svg, nodes)
+      .then((positioned) => {
+        expect(positioned[0].x).toBe(100);
+        expect(positioned[0].y).toBe(60);
+        expect(positioned[1].x).toBe(200);
+        expect(positioned[1].y).toBe(30);
+        expect(positioned[2].x).toBe(200);
+        expect(positioned[2].y).toBe(60);
+        done();
+      });
+
+    scope.$apply();
+  });
+});
diff --git a/src/app/service-graph/services/node-positioner.service.ts b/src/app/service-graph/services/node-positioner.service.ts
new file mode 100644
index 0000000..499afd0
--- /dev/null
+++ b/src/app/service-graph/services/node-positioner.service.ts
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+
+ * 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.
+ */
+
+
+import * as _ from 'lodash';
+import {IXosResourceService} from '../../datasources/rest/model.rest';
+import {IXosSgNode} from '../interfaces';
+
+export interface IXosNodePositioner {
+  positionNodes(svg: {width: number, height: number}, nodes: any[]): ng.IPromise<IXosSgNode[]>;
+}
+
+export class XosNodePositioner implements IXosNodePositioner {
+  static $inject = [
+    '$log',
+    '$q',
+    'ModelRest'
+  ];
+
+  constructor (
+    private $log: ng.ILogService,
+    private $q: ng.IQService,
+    private ModelRest: IXosResourceService,
+  ) {
+    this.$log.info('[XosNodePositioner] Setup');
+  }
+
+  public positionNodes(svg: {width: number, height: number}, nodes: any[]): ng.IPromise<IXosSgNode[]> {
+
+    // TODO refactor naming in this loop to make it clearer
+    const d =  this.$q.defer();
+
+    this.getConstraints()
+      .then(constraints => {
+        const hStep = this.getHorizontalStep(svg.width, constraints);
+        const positionConstraints = _.reduce(constraints, (all: any, c: string | string[], i: number) => {
+          let pos: {x: number, y: number, fixed: boolean} = {
+            x: svg.width / 2,
+            y: svg.height / 2,
+            fixed: true
+          };
+          // NOTE it's a single element, leave it in the middle
+          if (angular.isString(c)) {
+            pos.x = (i + 1) * hStep;
+            all[c] = pos;
+          }
+          else {
+            const verticalConstraints = c;
+            const vStep = this.getVerticalStep(svg.height, verticalConstraints);
+            _.forEach(verticalConstraints, (c: string, v: number) => {
+              if (angular.isString(c)) {
+                let p = angular.copy(pos);
+                p.x = (i + 1) * hStep;
+                p.y = (v + 1) * vStep;
+                all[c] = p;
+              }
+            });
+          }
+          return all;
+        }, {});
+
+        d.resolve(_.map(nodes, n => {
+          return angular.merge(n, positionConstraints[n.data.name]);
+        }));
+      })
+      .catch(e => {
+        this.$log.error(`[XosNodePositioner] Error retrieving constraints`, e);
+      });
+
+    return d.promise;
+  }
+
+  private getConstraints(): ng.IPromise<any[]> {
+    const d = this.$q.defer();
+    this.ModelRest.getResource('/core/servicegraphconstraints').query().$promise
+      .then(res => {
+        d.resolve(JSON.parse(res[0].constraints));
+      })
+      .catch(e => {
+        d.reject(e);
+      });
+    return d.promise;
+  }
+
+  private getHorizontalStep(svgWidth: number, constraints: any[]) {
+    return svgWidth / (constraints.length + 1);
+  }
+
+  private getVerticalStep(svgHeight: number, verticalConstraints: string[]) {
+    // NOTE verticalConstraints represent the vertical part (the nested array)
+    return svgHeight / (verticalConstraints.length + 1);
+  }
+}
diff --git a/src/app/service-graph/services/renderer/node.renderer.ts b/src/app/service-graph/services/renderer/node.renderer.ts
new file mode 100644
index 0000000..17bcf70
--- /dev/null
+++ b/src/app/service-graph/services/renderer/node.renderer.ts
@@ -0,0 +1,239 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+
+ * 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.
+ */
+
+import * as d3 from 'd3';
+import * as _ from 'lodash';
+import {IXosSgNode} from '../../interfaces';
+import {XosServiceGraphConfig as config} from '../../graph.config';
+import {IXosServiceGraphIcons} from '../d3-helpers/graph-icons.service';
+import {IXosGraphHelpers} from '../d3-helpers/graph-elements.helpers';
+
+export interface IXosNodeRenderer {
+  renderNodes(forceLayout: d3.forceLayout, nodeContainer: d3.Selection, nodes: IXosSgNode[]): void;
+}
+
+export class XosNodeRenderer {
+
+  static $inject = [
+    'XosServiceGraphIcons',
+    'XosGraphHelpers'
+  ];
+
+  private drag;
+
+  constructor (
+    private XosServiceGraphIcons: IXosServiceGraphIcons,
+    private XosGraphHelpers: IXosGraphHelpers
+  ) {}
+
+  public renderNodes(forceLayout: any, nodeContainer: any, nodes: IXosSgNode[]): void {
+
+    this.drag = forceLayout.drag()
+      .on('dragstart', (n: IXosSgNode) => {
+        n.fixed =  true;
+      });
+
+    const node = nodeContainer
+      .selectAll('g.node')
+      .data(nodes, n => n.id);
+
+    node
+      .call(this.drag);
+
+    const entering = node.enter()
+      .append('g')
+      .attr({
+        id: n => n.id,
+        class: n => `node ${n.type} ${this.XosGraphHelpers.parseElemClasses(n.d3Class)}`,
+      });
+
+    this.renderServiceNodes(entering.filter('.service'));
+    this.renderServiceInstanceNodes(entering.filter('.serviceinstance'));
+
+    node.exit().remove();
+  }
+
+  private renderServiceNodes(nodes: d3.selection) {
+
+    nodes
+      .append('rect')
+      .attr({
+        rx: config.node.radius,
+        ry: config.node.radius
+      });
+
+    nodes
+      .append('path')
+      .attr({
+        d: this.XosServiceGraphIcons.get('service').path,
+        transform: this.XosServiceGraphIcons.get('service').transform,
+        class: 'icon'
+      });
+
+    this.positionServiceNodeGroup(nodes);
+    this.handleLabels(nodes);
+  }
+
+  private renderServiceInstanceNodes(nodes: d3.selection) {
+    nodes.append('rect')
+      .attr({
+        width: 40,
+        height: 40,
+        x: -20,
+        y: -20,
+        transform: `rotate(45)`
+      });
+
+    nodes
+      .append('path')
+      .attr({
+        d: this.XosServiceGraphIcons.get('serviceinstance').path,
+        class: 'icon'
+      });
+
+    this.positionServiceInstanceNodeGroup(nodes);
+    this.handleLabels(nodes); // eventually improve, padding top is wrong
+  }
+
+  private positionServiceNodeGroup(nodes: d3.selection) {
+    const self = this;
+    nodes.each(function (d: IXosSgNode) {
+      const node = d3.select(this);
+      const rect = node.select('rect');
+      const icon = node.select('path');
+      const bbox = self.XosGraphHelpers.getSiblingIconBBox(rect.node());
+
+      rect
+        .attr({
+          width: bbox.width + config.node.padding,
+          height: bbox.height + config.node.padding,
+          x: - (config.node.padding / 2),
+          y: - (config.node.padding / 2),
+          transform: `translate(${-bbox.width / 2}, ${-bbox.height / 2})`
+        });
+
+      icon
+        .attr({
+          transform: `translate(${-bbox.width / 2}, ${-bbox.height / 2})`
+        });
+    });
+  }
+
+  private positionServiceInstanceNodeGroup(nodes: d3.selection) {
+    const self = this;
+    nodes.each(function (d: IXosSgNode) {
+      const node = d3.select(this);
+      const rect = node.select('rect');
+      const icon = node.select('path');
+      const bbox = self.XosGraphHelpers.getSiblingIconBBox(rect.node());
+      const size = _.max([bbox.width, bbox.height]); // NOTE we need it to be a square
+      rect
+        .attr({
+          width: size + config.node.padding,
+          height: size + config.node.padding,
+          x: - (config.node.padding / 2),
+          y: - (config.node.padding / 2),
+          transform: `rotate(45), translate(${-bbox.width / 2}, ${-bbox.height / 2})`
+        });
+
+      icon
+        .attr({
+          transform: `translate(${-bbox.width / 2}, ${-bbox.height / 2})`
+        });
+    });
+  }
+
+  private handleLabels(nodes: d3.selection) {
+    const self = this;
+    // if (this.userConfig.labels) {
+
+      // group to contain label text and wrapper
+      const label = nodes.append('g')
+        .attr({
+          class: 'label'
+        });
+
+      // setting up the wrapper
+      label
+        .append('rect')
+        .attr({
+          class: 'label-wrapper',
+          rx: config.node.radius,
+          ry: config.node.radius
+        });
+
+      // adding text
+      label
+        .append('text')
+        .text(n => this.getNodeLabel(n))
+        .attr({
+          'opacity': 0,
+          'text-anchor': 'left',
+          'alignment-baseline': 'bottom',
+          'font-size': config.node.text,
+          y: config.node.text * 0.78
+        })
+        .transition()
+        .duration(config.duration)
+        .attr({
+          opacity: 1
+        });
+
+      // resize and position label
+      label.each(function() {
+        const text = d3.select(this).select('text').node();
+        const rect = d3.select(this).select('rect');
+        const iconRect = d3.select(this.parentNode).select('rect').node();
+        const icon = self.XosGraphHelpers.getBBox(iconRect);
+        const bbox = self.XosGraphHelpers.getBBox(text);
+
+        // scale the rectangle around the label to fit the text
+        rect
+          .attr({
+            width: bbox.width + config.node.padding,
+            height: config.node.text - 2 + config.node.padding,
+            x: -(config.node.padding / 2),
+            y: -(config.node.padding / 2),
+          });
+
+        // translate the lable group to the correct position
+        d3.select(this)
+          .attr({
+            transform: function() {
+              const label = self.XosGraphHelpers.getBBox(this);
+              const x = - (label.width - config.node.padding) / 2;
+              const y = (icon.height / 2) + config.node.padding;
+              return `translate(${x}, ${y})`;
+            }
+          });
+      });
+    // }
+    // else {
+    //   node.selectAll('text')
+    //     .transition()
+    //     .duration(this.duration)
+    //     .attr({
+    //       opacity: 0
+    //     })
+    //     .remove();
+    // }
+  }
+
+  private getNodeLabel(n: any): string {
+    return n.data.name ? n.data.name.toUpperCase() : n.data.id;
+    // return n.data.name ? n.data.name.toUpperCase() + ` - ${n.data.id}` : n.data.id;
+  }
+}
diff --git a/src/app/service-graph/services/service-graph.store.spec.ts b/src/app/service-graph/services/service-graph.store.spec.ts
deleted file mode 100644
index 91c7dd0..0000000
--- a/src/app/service-graph/services/service-graph.store.spec.ts
+++ /dev/null
@@ -1,158 +0,0 @@
-
-/*
- * Copyright 2017-present Open Networking Foundation
-
- * 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.
- */
-
-
-import * as angular from 'angular';
-import 'angular-mocks';
-import 'angular-ui-router';
-import {IXosServiceGraphStore, XosServiceGraphStore} from './service-graph.store';
-import {Subject} from 'rxjs';
-import {XosDebouncer} from '../../core/services/helpers/debounce.helper';
-import {IXosServiceGraph} from '../interfaces';
-import {XosServiceGraphExtender, IXosServiceGraphExtender} from './graph.extender';
-
-let service: IXosServiceGraphStore, extender: IXosServiceGraphExtender;
-
-const subjects = {
-  service: new Subject<any>(),
-  tenant: new Subject<any>(),
-  subscriber: new Subject<any>(),
-  tenantroot: new Subject<any>(),
-  network: new Subject<any>(),
-  servicedependency: new Subject<any>()
-};
-
-// COARSE data
-const coarseServices = [
-  {
-    id: 1,
-    name: 'Service A',
-    class_names: 'Service, XOSBase'
-  },
-  {
-    id: 2,
-    name: 'Service B',
-    class_names: 'Service, XOSBase'
-  }
-];
-
-const coarseTenants = [
-  {
-    id: 1,
-    provider_service_id: 2,
-    subscriber_service_id: 1,
-    kind: 'coarse',
-    class_names: 'Tenant, XOSBase'
-  }
-];
-
-const mockModelStore = {
-  query: (modelName: string) => {
-    return subjects[modelName.toLowerCase()].asObservable();
-  }
-};
-
-describe('The XosServiceGraphStore service', () => {
-
-  beforeEach(() => {
-    angular.module('xosServiceGraphStore', [])
-      .service('XosServiceGraphStore', XosServiceGraphStore)
-      .value('XosModelStore', mockModelStore)
-      .service('XosServiceGraphExtender', XosServiceGraphExtender)
-      .service('XosDebouncer', XosDebouncer);
-
-    angular.mock.module('xosServiceGraphStore');
-  });
-
-  beforeEach(angular.mock.inject((
-    XosServiceGraphStore: IXosServiceGraphStore,
-    XosServiceGraphExtender: IXosServiceGraphExtender
-  ) => {
-    service = XosServiceGraphStore;
-    extender = XosServiceGraphExtender;
-  }));
-
-  describe('when subscribing for the COARSE service graph', () => {
-    beforeEach((done) => {
-      subjects.service.next(coarseServices);
-      subjects.servicedependency.next(coarseTenants);
-      setTimeout(done, 500);
-    });
-
-    it('should return an observer for the Coarse Service Graph', (done) => {
-      service.getCoarse()
-        .subscribe(
-          (res: IXosServiceGraph) => {
-            expect(res.nodes.length).toBe(2);
-            expect(res.nodes[0].d3Class).toBeUndefined();
-            expect(res.links.length).toBe(1);
-            expect(res.links[0].d3Class).toBeUndefined();
-            done();
-          },
-          (err) => {
-            done(err);
-          }
-        );
-    });
-
-    xdescribe('when a reducer is registered', () => {
-      // NOTE the reducer appliance has been moved in the component
-      beforeEach((done) => {
-        extender.register('coarse', 'test', (graph: IXosServiceGraph) => {
-          graph.nodes = graph.nodes.map(n => {
-            n.d3Class = `testNode`;
-            return n;
-          });
-
-          graph.links = graph.links.map(n => {
-            n.d3Class = `testLink`;
-            return n;
-          });
-
-          return graph;
-        });
-
-        // triggering another next cycle to apply the reducer
-        subjects.service.next(coarseServices);
-        subjects.tenant.next(coarseTenants);
-        setTimeout(done, 500);
-      });
-
-      it('should transform the result', (done) => {
-        service.getCoarse()
-          .subscribe(
-            (res: IXosServiceGraph) => {
-              expect(res.nodes.length).toBe(2);
-              expect(res.nodes[0].d3Class).toEqual('testNode');
-              expect(res.links.length).toBe(1);
-              expect(res.links[0].d3Class).toEqual('testLink');
-              done();
-            },
-            (err) => {
-              done(err);
-            }
-          );
-      });
-    });
-  });
-
-  describe('when subscribing for the Fine-grained service graph', () => {
-    xit('should have a test', () => {
-      expect(true).toBeTruthy();
-    });
-  });
-});
diff --git a/src/app/service-graph/services/service-graph.store.ts b/src/app/service-graph/services/service-graph.store.ts
deleted file mode 100644
index 92b9e6d..0000000
--- a/src/app/service-graph/services/service-graph.store.ts
+++ /dev/null
@@ -1,205 +0,0 @@
-
-/*
- * Copyright 2017-present Open Networking Foundation
-
- * 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.
- */
-
-
-import * as _ from 'lodash';
-import {Observable, BehaviorSubject, Subscription} from 'rxjs';
-import {IXosModelStoreService} from '../../datasources/stores/model.store';
-import {
-  IXosServiceGraph, IXosServiceModel, IXosTenantModel, IXosCoarseGraphData,
-  IXosServiceGraphNode, IXosServiceGraphLink, IXosFineGrainedGraphData
-} from '../interfaces';
-import {IXosDebouncer} from '../../core/services/helpers/debounce.helper';
-export interface IXosServiceGraphStore {
-  // TODO remove, moved in a new service
-  get(): Observable<IXosServiceGraph>;
-  // TODO rename in get()
-  getCoarse(): Observable<IXosServiceGraph>;
-}
-
-export class XosServiceGraphStore implements IXosServiceGraphStore {
-  static $inject = [
-    '$log',
-    'XosModelStore',
-    'XosDebouncer'
-  ];
-
-  // graph data store
-  private graphData: BehaviorSubject<IXosFineGrainedGraphData> = new BehaviorSubject({
-    services: [],
-    tenants: [],
-    networks: [],
-    subscribers: [],
-    servicedependencies: []
-  });
-
-  private emptyGraph: IXosServiceGraph = {
-    nodes: [],
-    links: []
-  };
-
-  // representation of the graph as D3 requires
-  private d3CoarseGraph = new BehaviorSubject(this.emptyGraph);
-  private d3FineGrainedGraph = new BehaviorSubject(this.emptyGraph);
-
-  // storing locally reference to the data model
-  private services;
-  private tenants;
-  private subscribers;
-  private networks;
-  private servicedependencys;
-
-  // debounced functions
-  private handleData;
-
-  // datastore
-  private ServiceSubscription: Subscription;
-  private NetworkSubscription: Subscription;
-  private ServiceDependencySubscription: Subscription;
-
-  constructor (
-    private $log: ng.ILogService,
-    private XosModelStore: IXosModelStoreService,
-    private XosDebouncer: IXosDebouncer
-  ) {
-
-    this.$log.info(`[XosServiceGraphStore] Setup`);
-
-    // we want to have a quiet period of 500ms from the last event before doing anything
-    this.handleData = this.XosDebouncer.debounce(this._handleData, 500, this, false);
-
-    // observe models and populate graphData
-    this.ServiceSubscription = this.XosModelStore.query('Service', '/core/services')
-      .subscribe(
-        (res) => {
-          this.combineData(res, 'services');
-        },
-        (err) => {
-          this.$log.error(`[XosServiceGraphStore] Service Observable: `, err);
-        }
-      );
-
-    this.ServiceDependencySubscription = this.XosModelStore.query('ServiceDependency', '/core/servicedependencys')
-      .subscribe(
-        (res) => {
-          this.combineData(res, 'servicedependencies');
-        },
-        (err) => {
-          this.$log.error(`[XosServiceGraphStore] Service Observable: `, err);
-        }
-      );
-
-    this.NetworkSubscription = this.XosModelStore.query('Network', '/core/networks')
-      .subscribe(
-        (res) => {
-          this.combineData(res, 'networks');
-        },
-        (err) => {
-          this.$log.error(`[XosServiceGraphStore] graphData Observable: `, err);
-        }
-      );
-
-    // observe graphData and build Coarse and FineGrained graphs
-    this.graphData
-      .subscribe(
-        (res: IXosFineGrainedGraphData) => {
-          this.$log.debug(`[XosServiceGraphStore] New graph data received`, res);
-          this.graphDataToCoarseGraph(res);
-          // this.graphDataToFineGrainedGraph(res);
-        },
-        (err) => {
-          this.$log.error(`[XosServiceGraphStore] graphData Observable: `, err);
-        }
-      );
-  }
-
-  public get() {
-    return this.d3FineGrainedGraph.asObservable();
-  }
-
-  public getCoarse() {
-    return this.d3CoarseGraph.asObservable();
-  }
-
-  private combineData(data: any, type: 'services'|'tenants'|'subscribers'|'networks'|'servicedependencies') {
-    switch (type) {
-      case 'services':
-        this.services = data;
-        break;
-      case 'tenants':
-        this.tenants = data;
-        break;
-      case 'subscribers':
-        this.subscribers = data;
-        break;
-      case 'networks':
-        this.networks = data;
-        break;
-      case 'servicedependencies':
-        this.servicedependencys = data;
-        break;
-    }
-    this.handleData(this.services, this.tenants);
-  }
-
-  private _handleData(services: IXosServiceModel[], tenants: IXosTenantModel[]) {
-    this.graphData.next({
-      services: this.services,
-      tenants: this.tenants,
-      subscribers: this.subscribers,
-      networks: this.networks,
-      servicedependencies: this.servicedependencys
-    });
-  }
-
-  private getNodeIndexById(id: number | string, nodes: IXosServiceModel[]) {
-    return _.findIndex(nodes, {id: id});
-  }
-
-  private graphDataToCoarseGraph(data: IXosCoarseGraphData) {
-
-    try {
-      const links: IXosServiceGraphLink[] = _.chain(data.servicedependencies)
-        .map((t: IXosTenantModel) => {
-          return {
-            id: t.id,
-            source: this.getNodeIndexById(t.provider_service_id, data.services),
-            target: this.getNodeIndexById(t.subscriber_service_id, data.services),
-            model: t
-          };
-        })
-        .value();
-
-      const nodes: IXosServiceGraphNode[] = _.map(data.services, (s: IXosServiceModel) => {
-        return {
-          id: s.id,
-          label: s.name,
-          model: s
-        };
-      });
-
-      let graph: IXosServiceGraph = {
-        nodes,
-        links
-      };
-
-      this.d3CoarseGraph.next(graph);
-    } catch (e) {
-      this.d3CoarseGraph.error(e);
-    }
-  }
-}
diff --git a/src/app/service-graph/services/service-instance.graph.store.ts b/src/app/service-graph/services/service-instance.graph.store.ts
deleted file mode 100644
index b8220b9..0000000
--- a/src/app/service-graph/services/service-instance.graph.store.ts
+++ /dev/null
@@ -1,281 +0,0 @@
-
-/*
- * Copyright 2017-present Open Networking Foundation
-
- * 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.
- */
-
-
-import * as _ from 'lodash';
-import {Observable, BehaviorSubject, Subscription} from 'rxjs';
-import {
-  IXosServiceGraph, IXosServiceInstanceGraphData, IXosServiceGraphNode
-} from '../interfaces';
-import {IXosDebouncer} from '../../core/services/helpers/debounce.helper';
-import {IXosModelStoreService} from '../../datasources/stores/model.store';
-import {IXosServiceGraphStore} from './service-graph.store';
-
-export interface IXosServiceInstanceGraphStore {
-  get(): Observable<IXosServiceGraph>;
-}
-
-export class XosServiceInstanceGraphStore implements IXosServiceInstanceGraphStore {
-  static $inject = [
-    '$log',
-    'XosServiceGraphStore',
-    'XosModelStore',
-    'XosDebouncer'
-  ];
-
-  private CoarseGraphSubscription: Subscription;
-  private ServiceInstanceSubscription: Subscription;
-  private ServiceInstanceLinkSubscription: Subscription;
-  private NetworkSubscription: Subscription;
-
-  // debounced functions
-  private handleData;
-
-
-  // FIXME this is declared also in ServiceGraphStore
-  private emptyGraph: IXosServiceGraph = {
-    nodes: [],
-    links: []
-  };
-
-  // graph data store
-  private graphData: BehaviorSubject<IXosServiceInstanceGraphData> = new BehaviorSubject({
-    serviceGraph: this.emptyGraph,
-    serviceInstances: [],
-    serviceInstanceLinks: [],
-    networks: []
-  });
-
-  private d3ServiceInstanceGraph = new BehaviorSubject(this.emptyGraph);
-
-  private serviceGraph: IXosServiceGraph = this.emptyGraph;
-  private serviceInstances: any[] = [];
-  private serviceInstanceLinks: any[] = [];
-  private networks: any[] = [];
-
-  constructor (
-    private $log: ng.ILogService,
-    private XosServiceGraphStore: IXosServiceGraphStore,
-    private XosModelStore: IXosModelStoreService,
-    private XosDebouncer: IXosDebouncer
-  ) {
-    this.$log.info(`[XosServiceInstanceGraphStore] Setup`);
-
-    // we want to have a quiet period of 500ms from the last event before doing anything
-    this.handleData = this.XosDebouncer.debounce(this._handleData, 500, this, false);
-
-    this.CoarseGraphSubscription = this.XosServiceGraphStore.getCoarse()
-      .subscribe(
-        (graph: IXosServiceGraph) => {
-          this.combineData(graph, 'serviceGraph');
-        }
-      );
-
-    this.ServiceInstanceSubscription = this.XosModelStore.query('ServiceInstance', '/core/serviceinstances')
-      .subscribe(
-        (res) => {
-          this.combineData(res, 'serviceInstance');
-        },
-        (err) => {
-          this.$log.error(`[XosServiceInstanceGraphStore] Service Observable: `, err);
-        }
-      );
-
-    this.ServiceInstanceLinkSubscription = this.XosModelStore.query('ServiceInstanceLink', '/core/serviceinstancelinks')
-      .subscribe(
-        (res) => {
-          this.combineData(res, 'serviceInstanceLink');
-        },
-        (err) => {
-          this.$log.error(`[XosServiceInstanceGraphStore] Service Observable: `, err);
-        }
-      );
-
-    this.NetworkSubscription = this.XosModelStore.query('Network', '/core/networks')
-      .subscribe(
-        (res) => {
-          this.combineData(res, 'networks');
-        },
-        (err) => {
-          this.$log.error(`[XosServiceGraphStore] graphData Observable: `, err);
-        }
-      );
-
-    // observe graphData and build ServiceInstance graph
-    this.graphData
-      .subscribe(
-        (res: IXosServiceInstanceGraphData) => {
-          this.$log.debug(`[XosServiceInstanceGraphStore] New graph data received`, res);
-
-          this.graphDataToD3(res);
-        },
-        (err) => {
-          this.$log.error(`[XosServiceInstanceGraphStore] graphData Observable: `, err);
-        }
-      );
-  }
-
-  public get(): Observable<IXosServiceGraph> {
-    return this.d3ServiceInstanceGraph;
-  }
-
-  // called by all the observables, combine the data in a globla graph observable
-  private combineData(data: any, type: 'serviceGraph' | 'serviceInstance' | 'serviceInstanceLink' | 'serviceInterface' | 'networks') {
-    switch (type) {
-      case 'serviceGraph':
-        this.serviceGraph = angular.copy(data);
-        break;
-      case 'serviceInstance':
-        this.serviceInstances = data;
-        break;
-      case 'serviceInstanceLink':
-        this.serviceInstanceLinks = data;
-        break;
-      case 'networks':
-        this.networks = data;
-        break;
-    }
-    this.handleData();
-  }
-
-  private _handleData() {
-    this.graphData.next({
-      serviceGraph: this.serviceGraph,
-      serviceInstances: this.serviceInstances,
-      serviceInstanceLinks: this.serviceInstanceLinks,
-      networks: this.networks
-    });
-  }
-
-  private getNodeType(n: any) {
-    return n.class_names.split(',')[0].toLowerCase();
-  }
-
-  private getNodeLabel(n: any) {
-    if (this.getNodeType(n) === 'serviceinstance') {
-      return n.name ? n.name : n.id;
-    }
-    return n.humanReadableName ? n.humanReadableName : n.name;
-  }
-
-  private d3Id(type: string, id: number) {
-    return `${type.toLowerCase()}~${id}`;
-  }
-
-  private toD3Node(n: any): IXosServiceGraphNode {
-    return {
-      id: this.d3Id(this.getNodeType(n), n.id),
-      label: this.getNodeLabel(n),
-      model: n,
-      type: this.getNodeType(n)
-    };
-  }
-
-  private getServiceInstanceIndexById(l: any, nodes: any[], where: 'source' | 'target'): string {
-    if (where === 'source') {
-      return _.find(nodes, {id: `serviceinstance~${l.provider_service_instance_id}`});
-    }
-    else {
-      if (l.subscriber_service_id) {
-        return _.find(nodes, {id: `service~${l.subscriber_service_id}`});
-      }
-      else if (l.subscriber_network_id) {
-        return _.find(nodes, {id: `network~${l.subscriber_network_id}`});
-      }
-      else if (l.subscriber_service_instance_id) {
-        return _.find(nodes, {id: `serviceinstance~${l.subscriber_service_instance_id}`});
-      }
-    }
-  }
-
-  private getOwnerById(id: number, nodes: any[]): any {
-    return _.find(nodes, {id: `service~${id}`});
-  }
-
-  private graphDataToD3(data: IXosServiceInstanceGraphData) {
-    try {
-      // get all the nodes
-      let nodes = _.chain(data.serviceGraph.nodes)
-        .map(n => {
-          // HACK we are receiving node as d3 models
-          return n.model;
-        })
-        .map(n => {
-          return this.toD3Node(n);
-        })
-        .value();
-
-      data.serviceInstances = _.chain(data.serviceInstances)
-        .map(n => {
-          return this.toD3Node(n);
-        })
-        .value();
-      nodes = nodes.concat(data.serviceInstances);
-
-      data.networks = _.chain(data.networks)
-        .filter(n => {
-          const subscriber = _.findIndex(data.serviceInstanceLinks, {subscriber_network_id: n.id});
-          return subscriber > -1;
-        })
-        .map(n => {
-          return this.toD3Node(n);
-        })
-        .value();
-      nodes = nodes.concat(data.networks);
-
-      let links = data.serviceGraph.links;
-
-      // create the links starting from the coarse ones
-      links = _.reduce(data.serviceInstanceLinks, (links, l) => {
-        let link =  {
-          id: `service_instance_link~${l.id}`,
-          source: this.getServiceInstanceIndexById(l, nodes, 'source'),
-          target: this.getServiceInstanceIndexById(l, nodes, 'target'),
-          model: l,
-          d3Class: 'service-instance'
-        };
-        links.push(link);
-        return links;
-      }, data.serviceGraph.links);
-
-      const linksToService = _.reduce(data.serviceInstances, (links, n) => {
-        if (angular.isDefined(n.model.owner_id)) {
-          let link =  {
-            id: `owner~${n.id}`,
-            source: n,
-            target: this.getOwnerById(n.model.owner_id, nodes),
-            model: n,
-            d3Class: 'owner'
-          };
-          links.push(link);
-        }
-        return links;
-      }, []);
-
-      links = links.concat(linksToService);
-
-      let graph: IXosServiceGraph = {
-        nodes,
-        links
-      };
-
-      this.d3ServiceInstanceGraph.next(graph);
-    } catch (e) {
-      this.d3ServiceInstanceGraph.error(e);
-    }
-  }
-}
