diff --git a/database/client.go b/database/client.go
index ecd24e25c13eb8af4d0522f4bfe00958041cabb3..10e5414835fb523e273eecb87bf011535617f955 100644
--- a/database/client.go
+++ b/database/client.go
@@ -7,19 +7,20 @@ import (
 	"github.com/spf13/viper"
 )
 
-//Database is a database
+// Database is a database
+// deprecated
 type Database struct {
 	driver neo4j.Driver
 }
 
-//PND is a principle network domain
+// PND is a principle network domain
 type PND struct {
 	name        string
 	description string
 	interfaces  []string
 }
 
-//NewDatabaseClient creates a database ciena
+// NewDatabaseClient creates a database ciena
 func NewDatabaseClient() Database {
 	uri := viper.GetString("db.socket")
 	username := viper.GetString("db.user")
@@ -32,7 +33,7 @@ func NewDatabaseClient() Database {
 	}
 }
 
-//createDriver creates a neo4j.Driver instance
+// createDriver creates a neo4j.Driver instance
 func createDriver(uri, username, password string, encrypted bool) neo4j.Driver {
 	driver, err := neo4j.NewDriver(
 		uri,
@@ -49,7 +50,7 @@ func createDriver(uri, username, password string, encrypted bool) neo4j.Driver {
 	return driver
 }
 
-//createSession creates a neo4j.Session
+// createSession creates a neo4j.Session
 func createSession(driver neo4j.Driver, write bool) neo4j.Session {
 	var sessionConfig neo4j.SessionConfig
 
@@ -68,7 +69,7 @@ func createSession(driver neo4j.Driver, write bool) neo4j.Session {
 	return session
 }
 
-//storePndTxFunc transaction to store a pnd in the database
+// storePndTxFunc transaction to store a pnd in the database
 func storePndTxFunc(name, description string, interfaces []string) neo4j.TransactionWork {
 	return func(tx neo4j.Transaction) (interface{}, error) {
 		query :=
@@ -98,7 +99,7 @@ func storePndTxFunc(name, description string, interfaces []string) neo4j.Transac
 	}
 }
 
-//StorePND stores the given principle network domain
+// StorePND stores the given principle network domain
 func (d Database) StorePND(pnd *PND) neo4j.Node {
 	session := createSession(d.driver, true)
 	defer session.Close()
@@ -170,8 +171,8 @@ func storeNodesTxFunc(json string, id int64) neo4j.TransactionWork {
 	}
 }
 
-//StoreNodes stores the given nodes to the database and adds them to a
-//principle networt domain (PND). It is required for a node to belong to a PND.
+// StoreNodes stores the given nodes to the database and adds them to a
+// principle networt domain (PND). It is required for a node to belong to a PND.
 func (d Database) StoreNodes(json string) []neo4j.Node {
 	//TODO: remove this after testing and add own gRPC call for it
 	testPND := PND{name: "test_PND", description: "very interesting", interfaces: []string{"TAPI", "RESTCONF"}}
@@ -189,15 +190,15 @@ func (d Database) StoreNodes(json string) []neo4j.Node {
 	return result.([]neo4j.Node)
 }
 
-//RemoveNodes removes the given nodes and their relationships
+// RemoveNodes removes the given nodes and their relationships
 func (d Database) RemoveNodes(json string) {}
 
-//RemoveSingleNode removes the given node and their relationship by id.
+// RemoveSingleNode removes the given node and their relationship by id.
 func (d Database) RemoveSingleNode(id string) {}
 
-//storeLinksTxFunc transaction to store links from a json.
-//creates relation between different devices.
-//returns a slice of those created relations.
+// storeLinksTxFunc transaction to store links from a json.
+// creates relation between different devices.
+// returns a slice of those created relations.
 func storeLinksTxFunc(json string) neo4j.TransactionWork {
 	return func(tx neo4j.Transaction) (interface{}, error) {
 		var relationsList []neo4j.Relationship
@@ -235,7 +236,7 @@ func storeLinksTxFunc(json string) neo4j.TransactionWork {
 	}
 }
 
-//StoreLinks stores the links between nodes
+// StoreLinks stores the links between nodes
 func (d Database) StoreLinks(json string) []neo4j.Relationship {
 	session := createSession(d.driver, true)
 	defer session.Close()
@@ -250,8 +251,8 @@ func (d Database) StoreLinks(json string) []neo4j.Relationship {
 	return result.([]neo4j.Relationship)
 }
 
-//storeNodeEdgePointsTxFunc transaction to store interfaces from a json.
-//returns count of added/updated interfaces
+// storeNodeEdgePointsTxFunc transaction to store interfaces from a json.
+// returns count of added/updated interfaces
 func storeNodeEdgePointsTxFunc(json string) neo4j.TransactionWork {
 	return func(tx neo4j.Transaction) (interface{}, error) {
 		query :=
@@ -287,8 +288,8 @@ func storeNodeEdgePointsTxFunc(json string) neo4j.TransactionWork {
 //TODO: currently this goes over each and every device/interface and adds
 //		a interface_of relation. -> do it only for the newly added interfaces
 
-//storeNodeEdgePointsRelationTxFunc transaction to create relations between interfaces and devices
-//returns count of added/updated relations
+// storeNodeEdgePointsRelationTxFunc transaction to create relations between interfaces and devices
+// returns count of added/updated relations
 func storeNodeEdgePointsRelationTxFunc() neo4j.TransactionWork {
 	return func(tx neo4j.Transaction) (interface{}, error) {
 		query :=
@@ -314,7 +315,7 @@ func storeNodeEdgePointsRelationTxFunc() neo4j.TransactionWork {
 	}
 }
 
-//StoreNodeEdgePoints stores the given node edge points (interfaces)
+// StoreNodeEdgePoints stores the given node edge points (interfaces)
 func (d Database) StoreNodeEdgePoints(json string) {
 	session := createSession(d.driver, true)
 	defer session.Close()
@@ -332,27 +333,27 @@ func (d Database) StoreNodeEdgePoints(json string) {
 	log.Info("added/updated nodeEdgePoints (count): ", result)
 }
 
-//StoreConnections stores relations between nodes
+// StoreConnections stores relations between nodes
 func (d Database) StoreConnections(json string) {}
 
-//StoreTopology creates a new network topology node. Can also create a relation
+// StoreTopology creates a new network topology node. Can also create a relation
 //the new node and a existing one if desired
 func StoreTopology() {}
 
-//RemoveTopology removes the given network topology. This includes the node itself
+// RemoveTopology removes the given network topology. This includes the node itself
 //aswell as the containing links and relations
 func RemoveTopology() {}
 
-//CreateTopologyRelation creates a relation between two given topologies
+// CreateTopologyRelation creates a relation between two given topologies
 func CreateTopologyRelation() {}
 
-//CreateLink creates a link between two network elements
+// CreateLink creates a link between two network elements
 func CreateLink() {}
 
-//RemoveLink removes a link between two network elements
+// RemoveLink removes a link between two network elements
 func RemoveLink() {}
 
-//Shutdown closes the connection to the database
+// Shutdown closes the connection to the database
 func (d Database) Shutdown() error {
 	return d.driver.Close()
 }
diff --git a/nucleus/controller.go b/nucleus/controller.go
index a02b55424f458f6977a0b93849d8741b1056e384..21ef57b7b79cc5ded87b628e287dfe5ce30ee673 100644
--- a/nucleus/controller.go
+++ b/nucleus/controller.go
@@ -1,7 +1,6 @@
 package nucleus
 
 import (
-	"fmt"
 	"os"
 
 	"code.fbi.h-da.de/cocsn/gosdn/database"
@@ -12,14 +11,27 @@ import (
 
 // Core is the representation of the controllers core
 type Core struct {
-	southboundInterfaces    map[string]SouthboundInterface
+	// deprecated, use sbiStore instead
+	southboundInterfaces map[string]SouthboundInterface
+	// deprecated, use pndStore instead
 	principalNetworkDomains map[uuid.UUID]PrincipalNetworkDomain
-	database                database.Database
-	IsRunning               chan bool
+	// deprecated
+	database database.Database
+
+	pndStore  pndStorage
+	sbiStore  sbiStorage
+	IsRunning chan bool
 }
 
 //Initialize does start-up housekeeping like reading controller config files
-func (c *Core) Initialize(IsRunningChannel chan bool) {
+func (c *Core) Initialize(IsRunningChannel chan bool) error {
+	c.sbiStore = sbiStorage{}
+	c.pndStore = pndStorage{}
+
+	// TODO: Just for compatability remove once deprecated code is cleaned up
+	c.southboundInterfaces = c.sbiStore
+	c.principalNetworkDomains = c.pndStore
+
 	// Set config defaults
 	viper.SetDefault("socket", "localhost:55055")
 
@@ -30,25 +42,32 @@ func (c *Core) Initialize(IsRunningChannel chan bool) {
 	viper.AddConfigPath("./configs/")
 	err := viper.ReadInConfig()
 	if err != nil {
-		log.Fatal(fmt.Errorf("Fatal error config file: %s \n", err))
+		return err
 	}
 	c.AttachDatabase()
-	c.CreateSouthboundInterfaces()
+	if err := c.CreateSouthboundInterfaces(); err != nil {
+		return err
+	}
 
 	c.IsRunning = IsRunningChannel
+	return nil
 }
 
+// deprecated
 // AttachDatabase connects to the database and passes the connection to the controller core
 func (c *Core) AttachDatabase() {
 	c.database = database.NewDatabaseClient()
 }
 
-// CreateSouthboundInterfaces initializes the controller with his supported SBIs
-func (c *Core) CreateSouthboundInterfaces() {
-	arista := &AristaOC{}
-	c.southboundInterfaces[arista.SbiIdentifier()] = arista
-	openconfig := &OpenConfig{}
-	c.southboundInterfaces[openconfig.SbiIdentifier()] = openconfig
+// CreateSouthboundInterfaces initializes the controller with its supported SBIs
+func (c *Core) CreateSouthboundInterfaces() error {
+	if err := c.sbiStore.add(&AristaOC{}); err != nil {
+		return err
+	}
+	if err := c.sbiStore.add(&OpenConfig{}); err != nil {
+		return err
+	}
+	return nil
 }
 
 // Shutdown waits for the shutdown signal and gracefully shuts down once it arrived
diff --git a/nucleus/controller_test.go b/nucleus/controller_test.go
index 0fa4ffa903a1f894325aaf5211341e19a2df754a..dd2a0175a06427bdea0d74e83fcd95cc5ff8b28f 100644
--- a/nucleus/controller_test.go
+++ b/nucleus/controller_test.go
@@ -1 +1,86 @@
 package nucleus
+
+import (
+	"code.fbi.h-da.de/cocsn/gosdn/database"
+	"github.com/google/uuid"
+	"testing"
+)
+
+func TestCore_CreateSouthboundInterfaces(t *testing.T) {
+	type fields struct {
+		southboundInterfaces    map[string]SouthboundInterface
+		principalNetworkDomains map[uuid.UUID]PrincipalNetworkDomain
+		database                database.Database
+		IsRunning               chan bool
+	}
+	tests := []struct {
+		name   string
+		fields fields
+	}{
+		// TODO: Add test cases.
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			_ = &Core{
+				southboundInterfaces:    tt.fields.southboundInterfaces,
+				principalNetworkDomains: tt.fields.principalNetworkDomains,
+				database:                tt.fields.database,
+				IsRunning:               tt.fields.IsRunning,
+			}
+		})
+	}
+}
+
+func TestCore_Initialize(t *testing.T) {
+	type fields struct {
+		southboundInterfaces    map[string]SouthboundInterface
+		principalNetworkDomains map[uuid.UUID]PrincipalNetworkDomain
+		database                database.Database
+		IsRunning               chan bool
+	}
+	type args struct {
+		IsRunningChannel chan bool
+	}
+	tests := []struct {
+		name   string
+		fields fields
+		args   args
+	}{
+		// TODO: Add test cases.
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			_ = &Core{
+				southboundInterfaces:    tt.fields.southboundInterfaces,
+				principalNetworkDomains: tt.fields.principalNetworkDomains,
+				database:                tt.fields.database,
+				IsRunning:               tt.fields.IsRunning,
+			}
+		})
+	}
+}
+
+func TestCore_Shutdown(t *testing.T) {
+	type fields struct {
+		southboundInterfaces    map[string]SouthboundInterface
+		principalNetworkDomains map[uuid.UUID]PrincipalNetworkDomain
+		database                database.Database
+		IsRunning               chan bool
+	}
+	tests := []struct {
+		name   string
+		fields fields
+	}{
+		// TODO: Add test cases.
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			_ = &Core{
+				southboundInterfaces:    tt.fields.southboundInterfaces,
+				principalNetworkDomains: tt.fields.principalNetworkDomains,
+				database:                tt.fields.database,
+				IsRunning:               tt.fields.IsRunning,
+			}
+		})
+	}
+}
diff --git a/nucleus/errors.go b/nucleus/errors.go
index 5da9172dea497aac52183fb0233edef178d21295..67ebde4edd448263b1adaf0ac66cd05c94ccc6e9 100644
--- a/nucleus/errors.go
+++ b/nucleus/errors.go
@@ -9,10 +9,18 @@ func (e *ErrNilClient) Error() string {
 	return fmt.Sprintf("client cannot be nil")
 }
 
-type ErrDeviceNotFound struct {
+type ErrNotFound struct {
 	id interface{}
 }
 
-func (e *ErrDeviceNotFound) Error() string {
-	return fmt.Sprintf("device not found. requested id: %v", e.id)
+func (e *ErrNotFound) Error() string {
+	return fmt.Sprintf("%v not found", e.id)
+}
+
+type ErrAlreadyExists struct {
+	item interface{}
+}
+
+func (e *ErrAlreadyExists) Error() string {
+	return fmt.Sprintf("%v already exists", e.item)
 }
diff --git a/nucleus/nucleus-core.go b/nucleus/nucleus-core.go
index ae6d78056beb1e9c7d19e9385026f0117d033a91..cb21c84458485f492800bdd382128122e94a50dd 100644
--- a/nucleus/nucleus-core.go
+++ b/nucleus/nucleus-core.go
@@ -3,8 +3,6 @@ package nucleus
 import (
 	"time"
 
-	"code.fbi.h-da.de/cocsn/gosdn/database"
-	"github.com/google/uuid"
 	log "github.com/sirupsen/logrus"
 )
 
@@ -14,12 +12,10 @@ func StartAndRun(IsRunningChannel chan bool) {
 	log.Info("Starting my ducks")
 
 	// Initialize the Core
-	core := Core{
-		principalNetworkDomains: make(map[uuid.UUID]PrincipalNetworkDomain),
-		southboundInterfaces:    make(map[string]SouthboundInterface),
-		database:                database.Database{},
+	core := Core{}
+	if err := core.Initialize(IsRunningChannel); err != nil {
+		log.Fatal(err)
 	}
-	core.Initialize(IsRunningChannel)
 	// Start the GRCP CLI
 	go getCLIGoing(&core)
 	go core.Shutdown()
diff --git a/nucleus/principalNetworkDomain.go b/nucleus/principalNetworkDomain.go
index bda39a39ad088e5ddf298b1a3c514144a0f4d9f6..2ed3301151c1c1843a16ef7ff814b040df863851 100644
--- a/nucleus/principalNetworkDomain.go
+++ b/nucleus/principalNetworkDomain.go
@@ -29,6 +29,7 @@ type pndImplementation struct {
 	description string
 	sbi         map[string]SouthboundInterface
 	devices     map[uuid.UUID]*Device
+	id          uuid.UUID
 }
 
 // NewPND creates a Principle Network Domain
@@ -117,7 +118,7 @@ func (pnd *pndImplementation) addDevice(device *Device) error {
 func (pnd *pndImplementation) getDevice(uuid uuid.UUID) (*Device, error) {
 	d, ok := pnd.devices[uuid]
 	if !ok {
-		return nil, &ErrDeviceNotFound{id: uuid}
+		return nil, &ErrNotFound{id: uuid}
 	}
 	return d, nil
 }
@@ -167,3 +168,31 @@ func (pnd *pndImplementation) RequestAll(path string) error {
 	}
 	return nil
 }
+
+type pndStorage map[uuid.UUID]PrincipalNetworkDomain
+
+func (p pndStorage) exists(id uuid.UUID) bool {
+	_, ok := p[id]
+	return ok
+}
+
+func (p pndStorage) add(pnd PrincipalNetworkDomain) error {
+	// TODO: Implement duplicate detection. Changes PrincipalNetworkDomain API
+	p[uuid.New()] = pnd
+	return nil
+}
+
+func (p pndStorage) Sbi(id uuid.UUID) (PrincipalNetworkDomain, error) {
+	if !p.exists(id) {
+		return nil, &ErrNotFound{id: id}
+	}
+	return p[id], nil
+}
+
+func (p pndStorage) delete(id uuid.UUID) error {
+	if !p.exists(id) {
+		return &ErrNotFound{id: id}
+	}
+	delete(p, id)
+	return nil
+}
diff --git a/nucleus/southbound.go b/nucleus/southbound.go
index 2a31d78f270f01e0cb153cdca907ee9422cfbc25..7f22d24c89de3232c218aea8c79096d926bf3fbd 100644
--- a/nucleus/southbound.go
+++ b/nucleus/southbound.go
@@ -95,3 +95,33 @@ func (oc *AristaOC) SetNode() func(schema *yang.Entry, root interface{}, path *g
 		return nil
 	}
 }
+
+type sbiStorage map[string]SouthboundInterface
+
+func (s sbiStorage) exists(name string) bool {
+	_, ok := s[name]
+	return ok
+}
+
+func (s sbiStorage) add(sbi SouthboundInterface) error {
+	if s.exists(sbi.SbiIdentifier()) {
+		return &ErrAlreadyExists{item: sbi}
+	}
+	s[sbi.SbiIdentifier()] = sbi
+	return nil
+}
+
+func (s sbiStorage) Sbi(name string) (SouthboundInterface, error) {
+	if !s.exists(name) {
+		return nil, &ErrNotFound{id: name}
+	}
+	return s[name], nil
+}
+
+func (s sbiStorage) delete(name string) error {
+	if !s.exists(name) {
+		return &ErrNotFound{id: name}
+	}
+	delete(s, name)
+	return nil
+}