diff --git a/Programming.md b/Programming.md
deleted file mode 100644
index 1f2cfa542ff47e019dac01647d0c5da8cca1f72a..0000000000000000000000000000000000000000
--- a/Programming.md
+++ /dev/null
@@ -1,33 +0,0 @@
-# Collection of programming stuff
-
-## Dependencies
-
-* github.com/spf13/cobra: used for basic cli of gosdn, such as starting the daemon, get versioning info etc
-* grpc
-* ygot
-
-## Structure of the code
-
-main.go: main() function
-nucleus/: core functionality of gosdn 
-
-ygot (yang for go tools).
-Checkout this in go: go get github.com/openconfig/ygot/ygot
-
-## Usefull things to know
-
-Regenerate gRPC code (https://grpc.io/docs/languages/go/quickstart/#regenerate-grpc-code)
-
-* ( cd  ~/go/src/github.com/grpc-go/cmd/protoc-gen-go-grpc/ && go install . )
-*
-protoc \
-  --go_out=Mgrpc/service_config/service_config.proto=/internal/proto/grpc_service_config:. \
-  --go-grpc_out=Mgrpc/service_config/service_config.proto=/internal/proto/grpc_service_config:. \
-  --go_opt=paths=source_relative \
-  --go-grpc_opt=paths=source_relative \
-  cliInterface/gosdnCLI.proto
-  
-Generate the ygot code:
-
-just type: go generate
-
diff --git a/build/cd/deploy.go b/build/cd/deploy.go
index 7f61e2db03aa957787167eb5112399771b6b33d9..85bbeee80f276f8a9428e71eff125a0e14f60dbd 100644
--- a/build/cd/deploy.go
+++ b/build/cd/deploy.go
@@ -4,7 +4,7 @@ import (
 	"context"
 	"os"
 
-	"code.fbi.h-da.de/cocsn/gosdn/nucleus"
+	nucleus "code.fbi.h-da.de/cocsn/gosdn/nucleus/errors"
 	log "github.com/sirupsen/logrus"
 	appv1 "k8s.io/api/apps/v1"
 	corev1 "k8s.io/api/core/v1"
diff --git a/build/ci/.golangci-config/.golangci.yml b/build/ci/.golangci-config/.golangci.yml
index a25219bf493cf95a8d43c16df09d72bc3479b83c..17861c02518faca8181ceef7fc03b3115922ae6a 100644
--- a/build/ci/.golangci-config/.golangci.yml
+++ b/build/ci/.golangci-config/.golangci.yml
@@ -7,7 +7,7 @@ run:
     - test
   skip-dirs-default: true
   skip-files:
-      - nucleus/http.go
+    - http.go
 # output settings -> code-climate for GitLab
 output:
   format: code-climate
diff --git a/build/ci/.test.yml b/build/ci/.test.yml
index dd4f07a0a70490c2ce539a91081ad3c196d73f3e..e4209b3bb7773f44ee961cfd6379ad9554645963 100644
--- a/build/ci/.test.yml
+++ b/build/ci/.test.yml
@@ -44,6 +44,5 @@ unit-test:
 
 controller-test:
   script:
-    - cd ./nucleus
     - go test -race -v -run TestRun
   <<: *test
\ No newline at end of file
diff --git a/cli/get.go b/cli/get.go
index 23406cde6824ef4915c76dfaee510543c2634e12..9b21ed48f24b7d256014cadf0cd50f3ab98f312f 100644
--- a/cli/get.go
+++ b/cli/get.go
@@ -3,6 +3,8 @@ package cli
 import (
 	"context"
 
+	"code.fbi.h-da.de/cocsn/gosdn/nucleus/errors"
+
 	"code.fbi.h-da.de/cocsn/gosdn/forks/goarista/gnmi"
 	"code.fbi.h-da.de/cocsn/gosdn/nucleus"
 	gpb "github.com/openconfig/gnmi/proto/gnmi"
@@ -32,7 +34,7 @@ func Get(a, u, p string, args ...string) (*gpb.GetResponse, error) {
 	log.Debug(resp)
 	r, ok := resp.(*gpb.GetResponse)
 	if !ok {
-		return nil, &nucleus.ErrInvalidTypeAssertion{}
+		return nil, &errors.ErrInvalidTypeAssertion{}
 	}
 	return r, nil
 }
diff --git a/cli/subscribe.go b/cli/subscribe.go
index ba56bf9cb6a42f20dcc27d955af7ab77d2169748..284a74d89de56df7c667fd813b4ecd7ef92037f7 100644
--- a/cli/subscribe.go
+++ b/cli/subscribe.go
@@ -8,6 +8,8 @@ import (
 	"syscall"
 	"time"
 
+	"code.fbi.h-da.de/cocsn/gosdn/nucleus/types"
+
 	"code.fbi.h-da.de/cocsn/gosdn/forks/goarista/gnmi"
 	"code.fbi.h-da.de/cocsn/gosdn/nucleus"
 	gpb "github.com/openconfig/gnmi/proto/gnmi"
@@ -48,7 +50,7 @@ func Subscribe(a, u, p string, sample, heartbeat int64, args ...string) error {
 	}
 	done := make(chan os.Signal, 1)
 	signal.Notify(done, syscall.SIGILL, syscall.SIGTERM)
-	ctx := context.WithValue(context.Background(), nucleus.CtxKeyOpts, opts) //nolint
+	ctx := context.WithValue(context.Background(), types.CtxKeyOpts, opts) //nolint
 	go func() {
 		if err := device.Transport.Subscribe(ctx); err != nil {
 			log.Fatal(err)
diff --git a/cmd/root.go b/cmd/root.go
index 61b1e153fba0a4294eb7a18ff2538186739d5143..6cd3ea8457455237f38a789131cf59c25f87ab3b 100644
--- a/cmd/root.go
+++ b/cmd/root.go
@@ -35,7 +35,8 @@ import (
 	"context"
 	"os"
 
-	"code.fbi.h-da.de/cocsn/gosdn/nucleus"
+	"code.fbi.h-da.de/cocsn/gosdn"
+
 	log "github.com/sirupsen/logrus"
 	"github.com/spf13/cobra"
 
@@ -60,7 +61,7 @@ for REST API calls.`,
 	RunE: func(cmd *cobra.Command, args []string) error {
 		ctx, cancel := context.WithCancel(context.Background())
 		defer cancel()
-		return nucleus.Run(ctx)
+		return gosdn.Run(ctx)
 	},
 }
 
diff --git a/nucleus/controller.go b/controller.go
similarity index 78%
rename from nucleus/controller.go
rename to controller.go
index accd0b8885711474e714c0e3c38e462f27a832e5..9500225308f97fcddf863d0ee8b3decb417fbcb0 100644
--- a/nucleus/controller.go
+++ b/controller.go
@@ -1,4 +1,4 @@
-package nucleus
+package gosdn
 
 import (
 	"context"
@@ -8,7 +8,10 @@ import (
 	"sync"
 	"time"
 
+	"code.fbi.h-da.de/cocsn/gosdn/nucleus/types"
+
 	"code.fbi.h-da.de/cocsn/gosdn/database"
+	"code.fbi.h-da.de/cocsn/gosdn/nucleus"
 	"github.com/google/uuid"
 	log "github.com/sirupsen/logrus"
 )
@@ -21,8 +24,8 @@ type Core struct {
 	// deprecated
 	database database.Database
 
-	pndc       pndStore
-	sbic       sbiStore
+	pndc       *nucleus.PndStore
+	sbic       *nucleus.SbiStore
 	httpServer *http.Server
 	stopChan   chan os.Signal
 }
@@ -32,8 +35,8 @@ var c *Core
 func init() {
 	c = &Core{
 		database: database.Database{},
-		pndc:     pndStore{store{}},
-		sbic:     sbiStore{store{}},
+		pndc:     nucleus.NewPndStore(),
+		sbic:     nucleus.NewSbiStore(),
 		stopChan: make(chan os.Signal, 1),
 	}
 
@@ -50,25 +53,26 @@ func initialize() error {
 	// TODO: Start grpc listener here
 	coreLock.Lock()
 	defer coreLock.Unlock()
-	return httpAPI()
+	startHttpServer()
+	return nil
 }
 
 // createSouthboundInterfaces initializes the controller with its supported SBIs
 func createSouthboundInterfaces() error {
-	sbi := &OpenConfig{id: uuid.New()}
-	if err := c.sbic.add(sbi); err != nil {
+	sbi := nucleus.NewSBI(types.Openconfig)
+	if err := c.sbic.Add(sbi); err != nil {
 		return err
 	}
 	return createPrincipalNetworkDomain(sbi)
 }
 
 // createPrincipalNetworkDomain initializes the controller with an initial PND
-func createPrincipalNetworkDomain(sbi SouthboundInterface) error {
-	pnd, err := NewPND("base", "gosdn base pnd", uuid.New(), sbi)
+func createPrincipalNetworkDomain(s nucleus.SouthboundInterface) error {
+	pnd, err := nucleus.NewPND("base", "gosdn base pnd", uuid.New(), s)
 	if err != nil {
 		return err
 	}
-	err = c.pndc.add(pnd)
+	err = c.pndc.Add(pnd)
 	if err != nil {
 		return err
 	}
diff --git a/nucleus/controller_test.go b/controller_test.go
similarity index 98%
rename from nucleus/controller_test.go
rename to controller_test.go
index 1dc5b8bd001270ace098c39a81e027263df7869c..27546454382200f60e86a664c185d4871a1ce8b2 100644
--- a/nucleus/controller_test.go
+++ b/controller_test.go
@@ -1,4 +1,4 @@
-package nucleus
+package gosdn
 
 import (
 	"context"
diff --git a/gosdn.png b/gosdn.png
deleted file mode 100644
index b16c83696fe11f6b983da0bf923457ecf59add8d..0000000000000000000000000000000000000000
Binary files a/gosdn.png and /dev/null differ
diff --git a/gosdn.puml b/gosdn.puml
deleted file mode 100644
index 1dc2379006cdef8990adf2f73dc4fe5ddd414c51..0000000000000000000000000000000000000000
--- a/gosdn.puml
+++ /dev/null
@@ -1,118 +0,0 @@
-@startuml
-namespace nucleus {
-    class ClientConfig << (S,Aquamarine) >> {
-        + Identifier string
-        + Endpoint string
-        + Username string
-        + Password string
-        + GjsonDefaultPath string
-        + GjsonConnectionsPath string
-
-    }
-    class Core << (S,Aquamarine) >> {
-        - devices <font color=blue>map</font>[string]Device
-        - southboundInterfaces <font color=blue>map</font>[string]interfaces.SouthboundInterface
-        - prinipalNetworkDomains <font color=blue>map</font>[uuid.UUID]interfaces.PrincipalNetworkDomain
-        - database database.Database
-        - config controllerConfig
-
-        + IsRunning <font color=blue>chan</font> bool
-
-        - readControllerConfig(configFileController string) error
-
-        + Init(socket string, configFileController string, configFileClient string, IsRunningChannel <font color=blue>chan</font> bool) 
-        + AttachDatabase() 
-        + Shutdown() 
-
-    }
-    class Device << (S,Aquamarine) >> {
-        - device ygot.GoStruct
-
-        + SBI interfaces.SouthboundInterface
-        + Config DeviceConfig
-
-    }
-    class DeviceConfig << (S,Aquamarine) >> {
-        + Identifier uuid.UUID
-        + Endpoint string
-        + Username string
-        + Password string
-
-    }
-    interface PrincipalNetworkDomain  {
-        + Destroy() error
-        + AddSbi() error
-        + RemoveSbi() error
-        + AddDevice( interfaces.Device) error
-        + RemoveDevice(uuid uuid.UUID) error
-
-    }
-    interface SouthboundInterface  {
-    }
-    class buf << (S,Aquamarine) >> {
-        + Write(p []byte) (int, error)
-
-    }
-    class controllerConfig << (S,Aquamarine) >> {
-        + CliSocket string
-        + DatabaseSocket string
-        + DatabaseUser string
-        + DatabasePassword string
-        + DatabaseCrypto bool
-        + ConfigPath string
-
-    }
-    class logConnection << (S,Aquamarine) >> {
-        - stream proto.GrpcCli_CreateLogStreamServer
-        - id string
-        - active bool
-        - error <font color=blue>chan</font> error
-
-    }
-    class nucleus.buf << (T, #FF7700) >>  {
-    }
-    class pndImplementation << (S,Aquamarine) >> {
-        - name string
-        - sbiContainer <font color=blue>map</font>[string]*interfaces.SouthboundInterface
-        - devices <font color=blue>map</font>[uuid.UUID]Device
-
-        + Destroy() error
-        + AddSbi() error
-        + RemoveSbi() error
-        + AddDevice(device Device) error
-        + RemoveDevice(uuid uuid.UUID) error
-
-    }
-    class server << (S,Aquamarine) >> {
-        - core *Core
-        - logConnections []*logConnection
-
-        + SayHello(ctx context.Context, in *proto.HelloRequest) (*proto.HelloReply, error)
-        + CreateLogStream(req *emptypb.Empty, stream proto.GrpcCli_CreateLogStreamServer) error
-        + BroadcastLog(log *proto.LogReply) 
-        + Shutdown(ctx context.Context, in *proto.ShutdownRequest) (*proto.ShutdownReply, error)
-        + TAPIGetEdge(ctx context.Context, in *proto.TAPIRequest) (*proto.TAPIReply, error)
-        + TAPIGetEdgeNode(ctx context.Context, in *proto.TAPIRequest) (*proto.TAPIReply, error)
-        + TAPIGetLink(ctx context.Context, in *proto.TAPIRequest) (*proto.TAPIReply, error)
-
-    }
-}
-"proto.UnimplementedGrpcCliServer" *-- "nucleus.server"
-
-
-namespace sbi {
-    class OpenConfig << (S,Aquamarine) >> {
-        - name string
-        - clientContainer []Client
-
-        + AddClient() error
-        + RemoveClient() error
-        + CollectHeartbeats() error
-        + ListClients() <font color=blue>map</font>[int]interfaces.Client
-
-    }
-}
-
-
-"__builtin__.[]byte" #.. "nucleus.buf"
-@enduml
diff --git a/nucleus/http.go b/http.go
similarity index 76%
rename from nucleus/http.go
rename to http.go
index ee0590e4e5645ff665417c9be7ec3d6b1542d220..92ce1890a2a0d5585d0093f6614fa727d919184c 100644
--- a/nucleus/http.go
+++ b/http.go
@@ -1,7 +1,10 @@
-package nucleus
+package gosdn
 
 import (
 	"code.fbi.h-da.de/cocsn/gosdn/forks/goarista/gnmi"
+	"code.fbi.h-da.de/cocsn/gosdn/nucleus"
+	"code.fbi.h-da.de/cocsn/gosdn/nucleus/errors"
+	"code.fbi.h-da.de/cocsn/gosdn/nucleus/types"
 	"context"
 	"fmt"
 	"github.com/google/uuid"
@@ -13,10 +16,10 @@ import (
 	"time"
 )
 
-var apiOpmap = map[string]Operation{
-	"update":  TransportUpdate,
-	"replace": TransportReplace,
-	"delete":  TransportDelete,
+var apiOpmap = map[string]types.Operation{
+	"update":  types.TransportUpdate,
+	"replace": types.TransportReplace,
+	"delete":  types.TransportDelete,
 }
 
 func stopHttpServer() error {
@@ -32,19 +35,17 @@ func registerHttpHandler() {
 			fmt.Println("Recovered in f", r)
 		}
 	}()
-	http.HandleFunc("/api", httpHandler)
+	http.HandleFunc("/api", httpApi)
 	http.HandleFunc("/livez", healthCheck)
 	http.HandleFunc("/readyz", readynessCheck)
 }
 
-// deprecated
-func httpAPI() error {
+func startHttpServer() {
 	registerHttpHandler()
 	c.httpServer = &http.Server{Addr: ":8080"}
 	go func() {
 		log.Info(c.httpServer.ListenAndServe())
 	}()
-	return nil
 }
 
 func healthCheck(writer http.ResponseWriter, request *http.Request) {
@@ -55,8 +56,9 @@ func readynessCheck(writer http.ResponseWriter, request *http.Request) {
 	writer.WriteHeader(http.StatusOK)
 }
 
+// deprecated
 // nolint
-func httpHandler(writer http.ResponseWriter, request *http.Request) {
+func httpApi(writer http.ResponseWriter, request *http.Request) {
 	log.WithFields(log.Fields{
 		"request": request,
 	}).Debug("incoming request")
@@ -89,16 +91,16 @@ func httpHandler(writer http.ResponseWriter, request *http.Request) {
 		}
 	}
 
-	var pnd PrincipalNetworkDomain
-	var sbi SouthboundInterface
+	var httpPnd nucleus.PrincipalNetworkDomain
+	var httpSbi nucleus.SouthboundInterface
 	if query.Get("q") != "init" && query.Get("q") != "getIDs" {
-		pnd, err = c.pndc.get(pid)
+		httpPnd, err = c.pndc.Get(pid)
 		if err != nil {
 			handleServerError(writer, err)
 			return
 		}
-		sbic := pnd.GetSBIs()
-		sbi, err = sbic.(*sbiStore).get(sid)
+		sbic := httpPnd.GetSBIs()
+		httpSbi, err = sbic.(*nucleus.SbiStore).Get(sid)
 		if err != nil {
 			handleServerError(writer, err)
 			return
@@ -107,18 +109,18 @@ func httpHandler(writer http.ResponseWriter, request *http.Request) {
 
 	switch q := query.Get("q"); q {
 	case "addDevice":
-		d, err := NewDevice(sbi, &GnmiTransportOptions{
+		d, err := nucleus.NewDevice(httpSbi, &nucleus.GnmiTransportOptions{
 			Config: gnmi.Config{
 				Addr:     query.Get("address"),
 				Password: query.Get("password"),
 				Username: query.Get("username"),
 				Encoding: gpb.Encoding_JSON_IETF,
 			},
-			SetNode:   sbi.SetNode(),
-			Unmarshal: sbi.(*OpenConfig).Unmarshal(),
+			SetNode:   httpSbi.SetNode(),
+			Unmarshal: httpSbi.(*nucleus.OpenConfig).Unmarshal(),
 			RespChan:  make(chan *gpb.SubscribeResponse),
 		})
-		err = pnd.AddDevice(d)
+		err = httpPnd.AddDevice(d)
 		if err != nil {
 			writer.WriteHeader(http.StatusInternalServerError)
 			log.Error(err)
@@ -128,10 +130,10 @@ func httpHandler(writer http.ResponseWriter, request *http.Request) {
 		fmt.Fprintf(writer, "device added\n")
 		fmt.Fprintf(writer, "UUID: %v\n", d.UUID)
 	case "request":
-		err = pnd.Request(id, query.Get("path"))
+		err = httpPnd.Request(id, query.Get("path"))
 		if err != nil {
 			switch err.(type) {
-			case *ErrNotFound:
+			case *errors.ErrNotFound:
 				writer.WriteHeader(http.StatusNotFound)
 			default:
 				writer.WriteHeader(http.StatusInternalServerError)
@@ -141,10 +143,10 @@ func httpHandler(writer http.ResponseWriter, request *http.Request) {
 		}
 		writer.WriteHeader(http.StatusOK)
 	case "requestAll":
-		err = pnd.RequestAll(query.Get("path"))
+		err = httpPnd.RequestAll(query.Get("path"))
 		if err != nil {
 			switch err.(type) {
-			case *ErrNotFound:
+			case *errors.ErrNotFound:
 				writer.WriteHeader(http.StatusNotFound)
 			default:
 				writer.WriteHeader(http.StatusInternalServerError)
@@ -154,10 +156,10 @@ func httpHandler(writer http.ResponseWriter, request *http.Request) {
 		}
 		writer.WriteHeader(http.StatusOK)
 	case "getDevice":
-		device, err := pnd.MarshalDevice(id)
+		device, err := httpPnd.MarshalDevice(id)
 		if err != nil {
 			switch err.(type) {
-			case *ErrNotFound:
+			case *errors.ErrNotFound:
 				writer.WriteHeader(http.StatusNotFound)
 			default:
 				writer.WriteHeader(http.StatusInternalServerError)
@@ -173,7 +175,7 @@ func httpHandler(writer http.ResponseWriter, request *http.Request) {
 		writeIDs(writer, "PNDs", pnds)
 		writeIDs(writer, "SBIs", c.sbic.UUIDs())
 		for _, id := range pnds {
-			p, err := c.pndc.get(id)
+			p, err := c.pndc.Get(id)
 			if err != nil {
 				handleServerError(writer, err)
 				return
@@ -184,22 +186,22 @@ func httpHandler(writer http.ResponseWriter, request *http.Request) {
 		writeIDs(writer, "PNDs", c.pndc.UUIDs())
 		writeIDs(writer, "SBIs", c.sbic.UUIDs())
 	case "update", "replace":
-		if err := pnd.ChangeOND(id, apiOpmap[q], query.Get("path"), query.Get("value")); err != nil {
+		if err := httpPnd.ChangeOND(id, apiOpmap[q], query.Get("path"), query.Get("value")); err != nil {
 			handleServerError(writer, err)
 			return
 		}
 		writer.WriteHeader(http.StatusOK)
 	case "delete":
-		if err := pnd.ChangeOND(id, TransportDelete, query.Get("path")); err != nil {
+		if err := httpPnd.ChangeOND(id, types.TransportDelete, query.Get("path")); err != nil {
 			handleServerError(writer, err)
 			return
 		}
 		writer.WriteHeader(http.StatusOK)
 	case "change-list":
-		changes := pnd.Committed()
+		changes := httpPnd.Committed()
 		writeIDs(writer, "Tentative changes", changes)
 	case "change-list-pending":
-		changes := pnd.Pending()
+		changes := httpPnd.Pending()
 		writeIDs(writer, "Pending changes", changes)
 	case "change-commit":
 		cuid, err := uuid.Parse(query.Get("cuid"))
@@ -207,7 +209,7 @@ func httpHandler(writer http.ResponseWriter, request *http.Request) {
 			handleServerError(writer, err)
 			return
 		}
-		if err := pnd.Commit(cuid); err != nil {
+		if err := httpPnd.Commit(cuid); err != nil {
 			handleServerError(writer, err)
 			return
 		}
@@ -218,7 +220,7 @@ func httpHandler(writer http.ResponseWriter, request *http.Request) {
 			handleServerError(writer, err)
 			return
 		}
-		if err := pnd.Confirm(cuid); err != nil {
+		if err := httpPnd.Confirm(cuid); err != nil {
 			handleServerError(writer, err)
 			return
 		}
diff --git a/nucleus/http_test.go b/http_test.go
similarity index 93%
rename from nucleus/http_test.go
rename to http_test.go
index 49405d29d40da981b9fccc159430654a3f75d77f..47a7a3e12ecc20da64c1f5476ea938d6783c44d7 100644
--- a/nucleus/http_test.go
+++ b/http_test.go
@@ -1,21 +1,25 @@
-package nucleus
+package gosdn
 
 import (
 	"errors"
 	"net/http"
 	"testing"
 
+	"code.fbi.h-da.de/cocsn/gosdn/nucleus/types"
+
 	"code.fbi.h-da.de/cocsn/gosdn/mocks"
+	"code.fbi.h-da.de/cocsn/gosdn/nucleus"
 	"github.com/google/uuid"
 	log "github.com/sirupsen/logrus"
 	"github.com/stretchr/testify/mock"
 )
 
 func testSetupHTTP() {
-	sbi = &OpenConfig{id: defaultSbiID}
+	sbi = nucleus.NewSBI(types.Openconfig)
 	sbi.Schema()
+	defaultSbiID = sbi.ID()
 	var err error
-	httpTestPND, err = NewPND("test", "test pnd", defaultPndID, sbi)
+	httpTestPND, err = nucleus.NewPND("test", "test pnd", defaultPndID, sbi)
 	if err != nil {
 		log.Fatal(err)
 	}
@@ -31,10 +35,10 @@ func testSetupHTTP() {
 	}
 	args = "&uuid=" + mdid.String() + "&pnd=" + defaultPndID.String() + "&sbi=" + defaultSbiID.String()
 	argsNotFound = "&uuid=" + uuid.New().String() + "&pnd=" + defaultPndID.String() + "&sbi=" + defaultSbiID.String()
-	if err := c.sbic.add(sbi); err != nil {
+	if err := c.sbic.Add(sbi); err != nil {
 		log.Fatal(err)
 	}
-	if err := c.pndc.add(httpTestPND); err != nil {
+	if err := c.pndc.Add(httpTestPND); err != nil {
 		log.Fatal(err)
 	}
 }
@@ -183,10 +187,7 @@ func Test_httpApi(t *testing.T) {
 		},
 	}
 	coreLock.Lock()
-	if err := httpAPI(); err != nil {
-		t.Errorf("httpApi() error = %v", err)
-		return
-	}
+	startHttpServer()
 	coreLock.Unlock()
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
@@ -199,7 +200,7 @@ func Test_httpApi(t *testing.T) {
 				t.Errorf("httpApi() got: %v, want %v", got.StatusCode, tt.want.StatusCode)
 			}
 			if tt.name == "add-device" {
-				for k := range httpTestPND.(*pndImplementation).devices.store {
+				for _, k := range httpTestPND.Devices() {
 					if k != mdid {
 						if err := httpTestPND.RemoveDevice(k); err != nil {
 							t.Error(err)
diff --git a/initialise_test.go b/initialise_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..5fbb298a7aa6a4cbc30aff8a80695aa1647eb34a
--- /dev/null
+++ b/initialise_test.go
@@ -0,0 +1,88 @@
+package gosdn
+
+import (
+	"context"
+	"os"
+	"testing"
+
+	"code.fbi.h-da.de/cocsn/gosdn/mocks"
+	"code.fbi.h-da.de/cocsn/gosdn/nucleus"
+	"code.fbi.h-da.de/cocsn/gosdn/nucleus/util/proto"
+	"github.com/google/uuid"
+	gpb "github.com/openconfig/gnmi/proto/gnmi"
+	log "github.com/sirupsen/logrus"
+	"github.com/stretchr/testify/mock"
+	pb "google.golang.org/protobuf/proto"
+)
+
+const apiEndpoint = "http://localhost:8080"
+
+// UUIDs for test cases
+var mdid uuid.UUID
+var defaultSbiID uuid.UUID
+var defaultPndID uuid.UUID
+var cuid uuid.UUID
+
+var sbi nucleus.SouthboundInterface
+var httpTestPND nucleus.PrincipalNetworkDomain
+var gnmiMessages map[string]pb.Message
+var httpTestDevice nucleus.Device
+
+var args string
+var argsNotFound string
+
+var mockContext = mock.MatchedBy(func(ctx context.Context) bool { return true })
+
+// TestMain bootstraps all tests. Humongous beast
+// TODO: Move somewhere more sensible
+func TestMain(m *testing.M) {
+	log.SetReportCaller(true)
+
+	if os.Getenv("GOSDN_LOG") == "nolog" {
+		log.SetLevel(log.PanicLevel)
+	}
+
+	gnmiMessages = map[string]pb.Message{
+		"./test/proto/cap-resp-arista-ceos":                  &gpb.CapabilityResponse{},
+		"./test/proto/req-full-node":                         &gpb.GetRequest{},
+		"./test/proto/req-full-node-arista-ceos":             &gpb.GetRequest{},
+		"./test/proto/req-interfaces-arista-ceos":            &gpb.GetRequest{},
+		"./test/proto/req-interfaces-interface-arista-ceos":  &gpb.GetRequest{},
+		"./test/proto/req-interfaces-wildcard":               &gpb.GetRequest{},
+		"./test/proto/resp-full-node":                        &gpb.GetResponse{},
+		"./test/proto/resp-full-node-arista-ceos":            &gpb.GetResponse{},
+		"./test/proto/resp-interfaces-arista-ceos":           &gpb.GetResponse{},
+		"./test/proto/resp-interfaces-interface-arista-ceos": &gpb.GetResponse{},
+		"./test/proto/resp-interfaces-wildcard":              &gpb.GetResponse{},
+		"./test/proto/resp-set-system-config-hostname":       &gpb.SetResponse{},
+	}
+	for k, v := range gnmiMessages {
+		if err := proto.Read(k, v); err != nil {
+			log.Fatalf("error parsing %v: %v", k, err)
+		}
+	}
+	readTestUUIDs()
+
+	testSetupHTTP()
+	os.Exit(m.Run())
+}
+
+func readTestUUIDs() {
+	var err error
+	mdid, err = uuid.Parse("688a264e-5f85-40f8-bd13-afc42fcd5c7a")
+	defaultPndID, err = uuid.Parse("b4016412-eec5-45a1-aa29-f59915357bad")
+	cuid, err = uuid.Parse("3e8219b0-e926-400d-8660-217f2a25a7c6")
+	if err != nil {
+		log.Fatal(err)
+	}
+}
+
+func mockDevice() nucleus.Device {
+	sbi := &nucleus.OpenConfig{}
+	return nucleus.Device{
+		UUID:      mdid,
+		GoStruct:  sbi.Schema().Root,
+		SBI:       sbi,
+		Transport: &mocks.Transport{},
+	}
+}
diff --git a/nucleus/pnd/change.go b/nucleus/change.go
similarity index 99%
rename from nucleus/pnd/change.go
rename to nucleus/change.go
index a6e550c9cf52786cfe9d507d216ba57d3b9af773..a8743b1abfc63efbc5c3cbcb7c3e8dd7dcc2f628 100644
--- a/nucleus/pnd/change.go
+++ b/nucleus/change.go
@@ -1,4 +1,4 @@
-package pnd
+package nucleus
 
 import (
 	"errors"
diff --git a/nucleus/pnd/change_test.go b/nucleus/change_test.go
similarity index 96%
rename from nucleus/pnd/change_test.go
rename to nucleus/change_test.go
index 71f648557214b91c4c5ee059943954883725367b..b58598b33356c9ce8fae3e032afb78c5b1441f96 100644
--- a/nucleus/pnd/change_test.go
+++ b/nucleus/change_test.go
@@ -1,4 +1,4 @@
-package pnd
+package nucleus
 
 import (
 	"context"
@@ -33,7 +33,7 @@ func TestChange_CommitRollback(t *testing.T) {
 	want := rollback
 	callback := make(chan string)
 	c := &Change{
-		cuid:          changeUUID,
+		cuid:          cuid,
 		duid:          did,
 		timestamp:     time.Now(),
 		previousState: rollbackDevice,
@@ -67,7 +67,7 @@ func TestChange_CommitRollbackError(t *testing.T) {
 	wantErr := false
 	want := errors.New("this is an expected error")
 	c := &Change{
-		cuid:          changeUUID,
+		cuid:          cuid,
 		duid:          did,
 		timestamp:     time.Now(),
 		previousState: rollbackDevice,
@@ -101,7 +101,7 @@ func TestChange_CommitRollbackError(t *testing.T) {
 func TestChange_CommitError(t *testing.T) {
 	wantErr := true
 	c := &Change{
-		cuid:          changeUUID,
+		cuid:          cuid,
 		duid:          did,
 		timestamp:     time.Now(),
 		previousState: rollbackDevice,
@@ -129,7 +129,7 @@ func TestChange_Commit(t *testing.T) {
 	callback := make(chan string)
 
 	c := &Change{
-		cuid:          changeUUID,
+		cuid:          cuid,
 		duid:          did,
 		timestamp:     time.Now(),
 		previousState: rollbackDevice,
@@ -228,8 +228,8 @@ func TestChange_ID(t *testing.T) {
 	}{
 		{
 			name:   "default",
-			fields: fields{cuid: changeUUID},
-			want:   changeUUID,
+			fields: fields{cuid: cuid},
+			want:   cuid,
 		},
 	}
 	for _, tt := range tests {
diff --git a/nucleus/device.go b/nucleus/device.go
index 4318f72420a10e61aa36f1bc7680452e0f640ff9..0c03706fc2c1866784b58d9689b25283f70f5465 100644
--- a/nucleus/device.go
+++ b/nucleus/device.go
@@ -1,6 +1,7 @@
 package nucleus
 
 import (
+	"code.fbi.h-da.de/cocsn/gosdn/nucleus/errors"
 	"github.com/google/uuid"
 	"github.com/openconfig/ygot/ygot"
 )
@@ -25,14 +26,14 @@ type Device struct {
 func NewDevice(sbi SouthboundInterface, opts TransportOptions) (*Device, error) {
 	var transport Transport
 	var err error
-	switch opts.(type) {
+	switch o := opts.(type) {
 	case *GnmiTransportOptions:
-		transport, err = NewGnmiTransport(opts.(*GnmiTransportOptions))
+		transport, err = NewGnmiTransport(o)
 		if err != nil {
 			return nil, err
 		}
 	default:
-		return nil, &ErrInvalidTransportOptions{opts}
+		return nil, &errors.ErrInvalidTransportOptions{Opt: o}
 
 	}
 	return &Device{
diff --git a/nucleus/errors.go b/nucleus/errors/errors.go
similarity index 82%
rename from nucleus/errors.go
rename to nucleus/errors/errors.go
index 7466b3ec10d37bf51b5f5605643882c359664f74..3aad202118e0bceb2b4e91dd34ce075c1ed454e5 100644
--- a/nucleus/errors.go
+++ b/nucleus/errors/errors.go
@@ -1,4 +1,4 @@
-package nucleus
+package errors
 
 import (
 	"fmt"
@@ -24,42 +24,42 @@ func (e *ErrNil) Error() string {
 // ErrNotFound implements the Error interface and is called if a specific ID
 // of a storable item could not be found.
 type ErrNotFound struct {
-	id interface{}
+	ID interface{}
 }
 
 func (e *ErrNotFound) Error() string {
-	return fmt.Sprintf("%v not found", e.id)
+	return fmt.Sprintf("%v not found", e.ID)
 }
 
 // ErrAlreadyExists implements the Error interface and is called if a specific ID
 // of a storable item already exists.
 type ErrAlreadyExists struct {
-	item interface{}
+	Item interface{}
 }
 
 func (e *ErrAlreadyExists) Error() string {
-	return fmt.Sprintf("%v already exists", e.item)
+	return fmt.Sprintf("%v already exists", e.Item)
 }
 
 // ErrInvalidTypeAssertion implements the Error interface and is called if the
 // type of a storable item does not correspond to the expected type.
 type ErrInvalidTypeAssertion struct {
-	v interface{}
-	t interface{}
+	Value interface{}
+	Type  interface{}
 }
 
 func (e ErrInvalidTypeAssertion) Error() string {
-	return fmt.Sprintf("%v does not implement %v", e.v, e.t)
+	return fmt.Sprintf("%v does not implement %v", e.Value, e.Type)
 }
 
 // ErrUnsupportedPath implements the Error interface and is called if the
 // given path is not supported.
 type ErrUnsupportedPath struct {
-	p interface{}
+	Path interface{}
 }
 
 func (e ErrUnsupportedPath) Error() string {
-	return fmt.Sprintf("path %v is not supported", e.p)
+	return fmt.Sprintf("path %v is not supported", e.Path)
 }
 
 // ErrNotYetImplemented implements the Error interface and is called if a function
@@ -73,30 +73,30 @@ func (e ErrNotYetImplemented) Error() string {
 // ErrInvalidParameters implements the Error interface and is called if the wrong
 // or no parameters have been provided.
 type ErrInvalidParameters struct {
-	f interface{}
-	r interface{}
+	Func  interface{}
+	Param interface{}
 }
 
 func (e ErrInvalidParameters) Error() string {
-	return fmt.Sprintf("invalid parameters for %v: %v", e.f, e.r)
+	return fmt.Sprintf("invalid parameters for %v: %v", e.Func, e.Param)
 }
 
 // ErrInvalidTransportOptions implements the Error interface and is called if the
 // wrong TransportOptions have been provided.
 type ErrInvalidTransportOptions struct {
-	t interface{}
+	Opt interface{}
 }
 
 func (e ErrInvalidTransportOptions) Error() string {
-	return fmt.Sprintf("invalid transport options: %v", reflect.TypeOf(e.t))
+	return fmt.Sprintf("invalid transport options: %v", reflect.TypeOf(e.Opt))
 }
 
 // ErrOperationNotSupported implements the Error interface and is called if the
 // wrong Operation has been provided.
 type ErrOperationNotSupported struct {
-	o interface{}
+	Op interface{}
 }
 
 func (e ErrOperationNotSupported) Error() string {
-	return fmt.Sprintf("transport operation not supported: %v", reflect.TypeOf(e.o))
+	return fmt.Sprintf("transport operation not supported: %v", reflect.TypeOf(e.Op))
 }
diff --git a/nucleus/gnmi_transport.go b/nucleus/gnmi_transport.go
index fb0c18f6f11bf3a01fe42ce4f46e18f92e3fb7c5..d5f7c369d40eb384de23049ea771e474d7d0a7fe 100644
--- a/nucleus/gnmi_transport.go
+++ b/nucleus/gnmi_transport.go
@@ -5,6 +5,8 @@ import (
 	"reflect"
 
 	"code.fbi.h-da.de/cocsn/gosdn/forks/goarista/gnmi"
+	"code.fbi.h-da.de/cocsn/gosdn/nucleus/errors"
+	"code.fbi.h-da.de/cocsn/gosdn/nucleus/types"
 	pathutils "code.fbi.h-da.de/cocsn/gosdn/nucleus/util/path"
 	gpb "github.com/openconfig/gnmi/proto/gnmi"
 	"github.com/openconfig/gnmi/proto/gnmi_ext"
@@ -14,25 +16,10 @@ import (
 	log "github.com/sirupsen/logrus"
 )
 
-// CtxKeyType is a custom type to be used as key in a context.WithValue() or
-// context.Value() call. For more information see:
-// https://www.calhoun.io/pitfalls-of-context-values-and-how-to-avoid-or-mitigate-them/
-// TODO: Unexport to comply with best practice
-type CtxKeyType string
-
-const (
-	// CtxKeyOpts context key for gnmi.SubscribeOptions
-	CtxKeyOpts CtxKeyType = "opts"
-	// CtxKeyConfig is a context key for gnmi.Config
-	CtxKeyConfig = "config"
-	// CtxKeyOperation is a context key for a gNMI operation (update, replace, delete)
-	CtxKeyOperation = "op"
-)
-
-var opmap = map[Operation]string{
-	TransportUpdate:  "update",
-	TransportReplace: "replace",
-	TransportDelete:  "delete",
+var opmap = map[types.Operation]string{
+	types.TransportUpdate:  "update",
+	types.TransportReplace: "replace",
+	types.TransportDelete:  "delete",
 }
 
 // Gnmi implements the Transport interface and provides an SBI with the
@@ -78,7 +65,7 @@ func (g *Gnmi) GetOptions() interface{} {
 // Get takes a slice of gnmi paths, splits them and calls get for each one of them.
 func (g *Gnmi) Get(ctx context.Context, params ...string) (interface{}, error) {
 	if g.client == nil {
-		return nil, &ErrNilClient{}
+		return nil, &errors.ErrNilClient{}
 	}
 	paths := gnmi.SplitPaths(params)
 	return g.get(ctx, paths, "")
@@ -88,12 +75,12 @@ func (g *Gnmi) Get(ctx context.Context, params ...string) (interface{}, error) {
 // It can contain an additional arbitrary amount of operations and extensions.
 func (g *Gnmi) Set(ctx context.Context, args ...interface{}) error {
 	if g.client == nil {
-		return &ErrNilClient{}
+		return &errors.ErrNilClient{}
 	}
 	if len(args) == 0 {
-		return &ErrInvalidParameters{
-			f: "gnmi.Set()",
-			r: "no parameters provided",
+		return &errors.ErrInvalidParameters{
+			Func:  "gnmi.Set()",
+			Param: "no parameters provided",
 		}
 	}
 
@@ -110,19 +97,19 @@ func (g *Gnmi) Set(ctx context.Context, args ...interface{}) error {
 	for _, o := range args {
 		attrs, ok := o.([]string)
 		if !ok {
-			return &ErrInvalidTypeAssertion{
-				v: o,
-				t: reflect.TypeOf("placeholder"),
+			return &errors.ErrInvalidTypeAssertion{
+				Value: o,
+				Type:  reflect.TypeOf("placeholder"),
 			}
 		} else if attrs == nil || len(attrs) == 0 {
-			return &ErrInvalidParameters{
-				f: "gnmi.Set()",
-				r: "no parameters provided",
+			return &errors.ErrInvalidParameters{
+				Func:  "gnmi.Set()",
+				Param: "no parameters provided",
 			}
 		}
 		opts = append(opts, &gnmi.Operation{
 			// Hardcoded TransportUpdate until multiple operations are supported
-			Type:   opmap[TransportUpdate],
+			Type:   opmap[types.TransportUpdate],
 			Origin: "",
 			Target: "",
 			Path:   gnmi.SplitPath(attrs[0]),
@@ -145,16 +132,16 @@ func (g *Gnmi) Set(ctx context.Context, args ...interface{}) error {
 		case *gnmi_ext.Extension:
 			exts = append(exts, p.(*gnmi_ext.Extension))
 		default:
-			return &ErrInvalidParameters{
-				f: "gnmi.Set()",
-				r: "args contain invalid type",
+			return &errors.ErrInvalidParameters{
+				Func:  "gnmi.Set()",
+				Param: "args contain invalid type",
 			}
 		}
 	}
 	if len(ops) == 0 {
-		return &ErrInvalidParameters{
-			f: "gnmi.Set()",
-			r: "no operations provided",
+		return &errors.ErrInvalidParameters{
+			Func:  "gnmi.Set()",
+			Param: "no operations provided",
 		}
 	}
 	resp, err := g.set(ctx, ops, exts...)
@@ -167,21 +154,21 @@ func (g *Gnmi) Set(ctx context.Context, args ...interface{}) error {
 
 func (g *Gnmi) applyDiff(ctx context.Context, payload ...interface{}) error {
 	if len(payload) != 2 {
-		return &ErrInvalidParameters{}
+		return &errors.ErrInvalidParameters{}
 	}
-	op := ctx.Value(CtxKeyOperation)
+	op := ctx.Value(types.CtxKeyOperation)
 	oldstate, ok := payload[0].(ygot.GoStruct)
 	if !ok {
-		return &ErrInvalidTypeAssertion{
-			v: payload[0],
-			t: reflect.TypeOf("ygot.GoStruct"),
+		return &errors.ErrInvalidTypeAssertion{
+			Value: payload[0],
+			Type:  reflect.TypeOf("ygot.GoStruct"),
 		}
 	}
 	newstate, ok := payload[1].(ygot.GoStruct)
 	if !ok {
-		return &ErrInvalidTypeAssertion{
-			v: payload[1],
-			t: reflect.TypeOf("ygot.GoStruct"),
+		return &errors.ErrInvalidTypeAssertion{
+			Value: payload[1],
+			Type:  reflect.TypeOf("ygot.GoStruct"),
 		}
 	}
 
@@ -192,12 +179,12 @@ func (g *Gnmi) applyDiff(ctx context.Context, payload ...interface{}) error {
 	req := &gpb.SetRequest{}
 	if diff.Update != nil {
 		switch op {
-		case TransportUpdate:
+		case types.TransportUpdate:
 			req.Update = diff.Update
-		case TransportReplace:
+		case types.TransportReplace:
 			req.Replace = diff.Update
 		default:
-			return &ErrOperationNotSupported{}
+			return &errors.ErrOperationNotSupported{}
 		}
 	} else if diff.Delete != nil {
 		req.Delete = diff.Delete
@@ -210,7 +197,7 @@ func (g *Gnmi) applyDiff(ctx context.Context, payload ...interface{}) error {
 //Subscribe subscribes to a gNMI target
 func (g *Gnmi) Subscribe(ctx context.Context, params ...string) error {
 	if g.client == nil {
-		return &ErrNilClient{}
+		return &errors.ErrNilClient{}
 	}
 	return g.subscribe(ctx)
 }
@@ -254,7 +241,7 @@ func (g *Gnmi) Capabilities(ctx context.Context) (interface{}, error) {
 		"target": g.Options.Addr,
 	}).Info("sending gNMI capabilities request")
 	ctx = gnmi.NewContext(ctx, &g.Options.Config)
-	ctx = context.WithValue(ctx, CtxKeyConfig, &g.Options.Config) //nolint
+	ctx = context.WithValue(ctx, types.CtxKeyConfig, &g.Options.Config) //nolint
 	resp, err := g.client.Capabilities(ctx, &gpb.CapabilityRequest{})
 	if err != nil {
 		return nil, err
@@ -266,7 +253,7 @@ func (g *Gnmi) Capabilities(ctx context.Context) (interface{}, error) {
 func (g *Gnmi) get(ctx context.Context, paths [][]string, origin string) (interface{}, error) {
 
 	ctx = gnmi.NewContext(ctx, &g.Options.Config)
-	ctx = context.WithValue(ctx, CtxKeyConfig, &g.Options.Config) //nolint
+	ctx = context.WithValue(ctx, types.CtxKeyConfig, &g.Options.Config) //nolint
 	req, err := gnmi.NewGetRequest(ctx, paths, origin)
 	if err != nil {
 		return nil, err
@@ -278,7 +265,7 @@ func (g *Gnmi) get(ctx context.Context, paths [][]string, origin string) (interf
 // and returns any response.
 func (g *Gnmi) getWithRequest(ctx context.Context, req *gpb.GetRequest) (interface{}, error) {
 	if req == nil {
-		return nil, &ErrNil{}
+		return nil, &errors.ErrNil{}
 	}
 	log.WithFields(log.Fields{
 		"target": g.Options.Addr,
@@ -315,11 +302,11 @@ func (g *Gnmi) set(ctx context.Context, setOps []*gnmi.Operation,
 // Subscribe calls GNMI subscribe
 func (g *Gnmi) subscribe(ctx context.Context) error {
 	ctx = gnmi.NewContext(ctx, &g.Options.Config)
-	opts, ok := ctx.Value(CtxKeyOpts).(*gnmi.SubscribeOptions)
+	opts, ok := ctx.Value(types.CtxKeyOpts).(*gnmi.SubscribeOptions)
 	if !ok {
-		return &ErrInvalidTypeAssertion{
-			v: reflect.TypeOf(ctx.Value(CtxKeyOpts)),
-			t: reflect.TypeOf(&gnmi.SubscribeOptions{}),
+		return &errors.ErrInvalidTypeAssertion{
+			Value: reflect.TypeOf(ctx.Value(types.CtxKeyOpts)),
+			Type:  reflect.TypeOf(&gnmi.SubscribeOptions{}),
 		}
 	}
 	go func() {
diff --git a/nucleus/initialise_test.go b/nucleus/initialise_test.go
index 4cb53d136315b294ac680ec6c81e760a964b7407..85b938a0d14aa442c196e020b9f413b8095bb9bb 100644
--- a/nucleus/initialise_test.go
+++ b/nucleus/initialise_test.go
@@ -16,8 +16,6 @@ import (
 	pb "google.golang.org/protobuf/proto"
 )
 
-const apiEndpoint = "http://localhost:8080"
-
 // UUIDs for test cases
 var did uuid.UUID
 var mdid uuid.UUID
@@ -28,16 +26,11 @@ var iid uuid.UUID
 var altIid uuid.UUID
 var cuid uuid.UUID
 
-var sbi SouthboundInterface
-var httpTestPND PrincipalNetworkDomain
 var gnmiMessages map[string]pb.Message
 var gnmiConfig *gnmi.Config
-var httpTestDevice Device
 
 var startGnmiTarget chan string
 var stopGnmiTarget chan bool
-var args string
-var argsNotFound string
 
 var mockContext = mock.MatchedBy(func(ctx context.Context) bool { return true })
 
@@ -72,7 +65,6 @@ func TestMain(m *testing.M) {
 	readTestUUIDs()
 
 	testSetupGnmi()
-	testSetupHTTP()
 	os.Exit(m.Run())
 }
 
@@ -136,11 +128,11 @@ func newPnd() pndImplementation {
 	return pndImplementation{
 		name:             "default",
 		description:      "default test pnd",
-		sbic:             sbiStore{store{}},
-		devices:          deviceStore{store{}},
-		pendingChanges:   changeStore{store{}},
-		committedChanges: changeStore{store{}},
-		confirmedChanges: changeStore{store{}},
+		sbic:             SbiStore{store{}},
+		devices:          DeviceStore{store{}},
+		pendingChanges:   ChangeStore{store{}},
+		committedChanges: ChangeStore{store{}},
+		confirmedChanges: ChangeStore{store{}},
 		id:               defaultPndID,
 		errChans:         make(map[uuid.UUID]chan error),
 	}
diff --git a/nucleus/pnd/initialise_test.go b/nucleus/pnd/initialise_test.go
deleted file mode 100644
index 7451bd565d99f38a5b23abae7bc93fbb4d001503..0000000000000000000000000000000000000000
--- a/nucleus/pnd/initialise_test.go
+++ /dev/null
@@ -1,23 +0,0 @@
-package pnd
-
-import (
-	"os"
-	"testing"
-
-	"github.com/google/uuid"
-	log "github.com/sirupsen/logrus"
-)
-
-// UUIDs for test cases
-var changeUUID uuid.UUID
-var did uuid.UUID
-
-func TestMain(m *testing.M) {
-	var err error
-	changeUUID, err = uuid.Parse("cfbb96cd-ecad-45d1-bebf-1851760f5087")
-	did, err = uuid.Parse("4d8246f8-e884-41d6-87f5-c2c784df9e44")
-	if err != nil {
-		log.Fatal(err)
-	}
-	os.Exit(m.Run())
-}
diff --git a/nucleus/principalNetworkDomain.go b/nucleus/principalNetworkDomain.go
index 375801125282b51c494b637165ab944918a1be44..e3d535d81d7dfee3557f6ce2f7d7bdd94ab7f6f1 100644
--- a/nucleus/principalNetworkDomain.go
+++ b/nucleus/principalNetworkDomain.go
@@ -3,8 +3,10 @@ package nucleus
 import (
 	"context"
 
+	"code.fbi.h-da.de/cocsn/gosdn/nucleus/errors"
+	"code.fbi.h-da.de/cocsn/gosdn/nucleus/types"
+
 	"code.fbi.h-da.de/cocsn/gosdn/forks/goarista/gnmi"
-	. "code.fbi.h-da.de/cocsn/gosdn/nucleus/pnd" //nolint
 	"github.com/openconfig/ygot/ygot"
 	"github.com/openconfig/ygot/ytypes"
 	log "github.com/sirupsen/logrus"
@@ -44,15 +46,15 @@ func NewPND(name, description string, id uuid.UUID, sbi SouthboundInterface) (Pr
 	pnd := &pndImplementation{
 		name:             name,
 		description:      description,
-		sbic:             sbiStore{store{}},
-		devices:          deviceStore{store{}},
-		pendingChanges:   changeStore{store{}},
-		committedChanges: changeStore{store{}},
-		confirmedChanges: changeStore{store{}},
+		sbic:             SbiStore{store{}},
+		devices:          DeviceStore{store{}},
+		pendingChanges:   ChangeStore{store{}},
+		committedChanges: ChangeStore{store{}},
+		confirmedChanges: ChangeStore{store{}},
 		id:               id,
 		errChans:         make(map[uuid.UUID]chan error),
 	}
-	if err := pnd.sbic.add(sbi); err != nil {
+	if err := pnd.sbic.Add(sbi); err != nil {
 		return nil, err
 	}
 	return pnd, nil
@@ -61,11 +63,11 @@ func NewPND(name, description string, id uuid.UUID, sbi SouthboundInterface) (Pr
 type pndImplementation struct {
 	name             string
 	description      string
-	sbic             sbiStore
-	devices          deviceStore
-	pendingChanges   changeStore
-	committedChanges changeStore
-	confirmedChanges changeStore
+	sbic             SbiStore
+	devices          DeviceStore
+	pendingChanges   ChangeStore
+	committedChanges ChangeStore
+	confirmedChanges ChangeStore
 	id               uuid.UUID
 	errChans         map[uuid.UUID]chan error
 }
@@ -79,7 +81,7 @@ func (pnd *pndImplementation) Committed() []uuid.UUID {
 }
 
 func (pnd *pndImplementation) Commit(u uuid.UUID) error {
-	change, err := pnd.pendingChanges.get(u)
+	change, err := pnd.pendingChanges.Get(u)
 	if err != nil {
 		return err
 	}
@@ -97,24 +99,24 @@ func (pnd *pndImplementation) Commit(u uuid.UUID) error {
 			}
 		}
 	}()
-	if err := pnd.committedChanges.add(change); err != nil {
+	if err := pnd.committedChanges.Add(change); err != nil {
 		return err
 	}
-	return pnd.pendingChanges.delete(u)
+	return pnd.pendingChanges.Delete(u)
 }
 
 func (pnd *pndImplementation) Confirm(u uuid.UUID) error {
-	change, err := pnd.committedChanges.get(u)
+	change, err := pnd.committedChanges.Get(u)
 	if err != nil {
 		return err
 	}
 	if err := change.Confirm(); err != nil {
 		return err
 	}
-	if err := pnd.confirmedChanges.add(change); err != nil {
+	if err := pnd.confirmedChanges.Add(change); err != nil {
 		return err
 	}
-	return pnd.committedChanges.delete(u)
+	return pnd.committedChanges.Delete(u)
 }
 
 func (pnd *pndImplementation) ID() uuid.UUID {
@@ -132,7 +134,7 @@ func (pnd *pndImplementation) GetName() string {
 
 // ContainsDevice checks if the given device uuid is registered for this PND
 func (pnd *pndImplementation) ContainsDevice(id uuid.UUID) bool {
-	return pnd.devices.exists(id)
+	return pnd.devices.Exists(id)
 }
 
 // GetDescription returns the current description of the PND
@@ -154,9 +156,9 @@ func (pnd *pndImplementation) Destroy() error {
 func (pnd *pndImplementation) AddSbi(sbi interface{}) error {
 	s, ok := sbi.(SouthboundInterface)
 	if !ok {
-		return &ErrInvalidTypeAssertion{
-			v: sbi,
-			t: "Device",
+		return &errors.ErrInvalidTypeAssertion{
+			Value: sbi,
+			Type:  "Device",
 		}
 	}
 	return pnd.addSbi(s)
@@ -174,16 +176,16 @@ func (pnd *pndImplementation) RemoveSbi(id uuid.UUID) error {
 func (pnd *pndImplementation) AddDevice(device interface{}) error {
 	d, ok := device.(*Device)
 	if !ok {
-		return &ErrInvalidTypeAssertion{
-			v: device,
-			t: "Device",
+		return &errors.ErrInvalidTypeAssertion{
+			Value: device,
+			Type:  "Device",
 		}
 	}
 	return pnd.addDevice(d)
 }
 
 func (pnd *pndImplementation) GetDevice(uuid uuid.UUID) (ygot.GoStruct, error) {
-	d, err := pnd.devices.get(uuid)
+	d, err := pnd.devices.Get(uuid)
 	if err != nil {
 		return nil, err
 	}
@@ -202,23 +204,23 @@ func destroy() error {
 }
 
 func (pnd *pndImplementation) addSbi(sbi SouthboundInterface) error {
-	return pnd.sbic.add(sbi)
+	return pnd.sbic.Add(sbi)
 }
 
 func (pnd *pndImplementation) removeSbi(id uuid.UUID) error {
-	return pnd.sbic.delete(id)
+	return pnd.sbic.Delete(id)
 }
 
 func (pnd *pndImplementation) addDevice(device *Device) error {
-	return pnd.devices.add(device)
+	return pnd.devices.Add(device)
 }
 
 func (pnd *pndImplementation) getDevice(id uuid.UUID) (*Device, error) {
-	return pnd.devices.get(id)
+	return pnd.devices.Get(id)
 }
 
 func (pnd *pndImplementation) removeDevice(id uuid.UUID) error {
-	return pnd.devices.delete(id)
+	return pnd.devices.Delete(id)
 }
 
 func (pnd *pndImplementation) MarshalDevice(uuid uuid.UUID) (string, error) {
@@ -283,25 +285,25 @@ func (pnd *pndImplementation) ChangeOND(uuid uuid.UUID, operation interface{}, p
 		return err
 	}
 
-	if operation != TransportDelete && len(value) != 1 {
-		return &ErrInvalidParameters{
-			f: pnd.ChangeOND,
-			r: value,
+	if operation != types.TransportDelete && len(value) != 1 {
+		return &errors.ErrInvalidParameters{
+			Func:  pnd.ChangeOND,
+			Param: value,
 		}
 	}
 
 	switch operation {
-	case TransportUpdate, TransportReplace:
+	case types.TransportUpdate, types.TransportReplace:
 		typedValue := gnmi.TypedValue(value[0])
 		if err := ytypes.SetNode(d.SBI.Schema().RootSchema(), cpy, p, typedValue); err != nil {
 			return err
 		}
-	case TransportDelete:
+	case types.TransportDelete:
 		if err := ytypes.DeleteNode(d.SBI.Schema().RootSchema(), cpy, p); err != nil {
 			return err
 		}
 	default:
-		return &ErrOperationNotSupported{o: operation}
+		return &errors.ErrOperationNotSupported{Op: operation}
 	}
 
 	callback := func(state ygot.GoStruct, change ygot.GoStruct) error {
@@ -313,7 +315,7 @@ func (pnd *pndImplementation) ChangeOND(uuid uuid.UUID, operation interface{}, p
 	change := NewChange(uuid, d.GoStruct, cpy, callback, errChan)
 	pnd.errChans[change.ID()] = errChan
 
-	return pnd.pendingChanges.add(change)
+	return pnd.pendingChanges.Add(change)
 }
 
 func handleRollbackError(id uuid.UUID, err error) {
diff --git a/nucleus/principalNetworkDomain_test.go b/nucleus/principalNetworkDomain_test.go
index 9daf8230a63a4a585580e65a5f348057837e1a0f..17d5c0a30232b69ec82e180fc2fa75706d3d66c5 100644
--- a/nucleus/principalNetworkDomain_test.go
+++ b/nucleus/principalNetworkDomain_test.go
@@ -5,6 +5,8 @@ import (
 	"reflect"
 	"testing"
 
+	"code.fbi.h-da.de/cocsn/gosdn/nucleus/types"
+
 	"code.fbi.h-da.de/cocsn/gosdn/mocks"
 	"code.fbi.h-da.de/cocsn/yang-models/generated/openconfig"
 	"github.com/google/uuid"
@@ -123,7 +125,7 @@ func Test_pndImplementation_AddDevice(t *testing.T) {
 						t.Errorf("AddDevice() Device %v not in device store %v",
 							tt.args.device, pnd.devices)
 					}
-					if err := pnd.devices.delete(did); err != nil {
+					if err := pnd.devices.Delete(did); err != nil {
 						t.Error(err)
 					}
 				}
@@ -186,7 +188,7 @@ func Test_pndImplementation_AddSbi(t *testing.T) {
 						t.Errorf("AddSbi() SBI %v not in device store %v",
 							tt.args.sbi, pnd.GetSBIs())
 					}
-					if err := pnd.sbic.delete(defaultSbiID); err != nil {
+					if err := pnd.sbic.Delete(defaultSbiID); err != nil {
 						t.Error(err)
 					}
 				}
@@ -222,14 +224,14 @@ func Test_pndImplementation_ContainsDevice(t *testing.T) {
 		t.Run(tt.name, func(t *testing.T) {
 			pnd := newPnd()
 			if tt.name != "fails empty" {
-				if err := pnd.devices.add(tt.args.device); err != nil {
+				if err := pnd.devices.Add(tt.args.device); err != nil {
 					t.Error(err)
 				}
 			}
 			if got := pnd.ContainsDevice(tt.args.uuid); got != tt.want {
 				t.Errorf("ContainsDevice() = %v, want %v", got, tt.want)
 			}
-			if err := pnd.devices.delete(did); err != nil && tt.name != "fails empty" {
+			if err := pnd.devices.Delete(did); err != nil && tt.name != "fails empty" {
 				t.Error(err)
 			}
 		})
@@ -240,8 +242,8 @@ func Test_pndImplementation_Destroy(t *testing.T) {
 	type fields struct {
 		name        string
 		description string
-		sbi         sbiStore
-		devices     deviceStore
+		sbi         SbiStore
+		devices     DeviceStore
 	}
 	tests := []struct {
 		name    string
@@ -303,7 +305,7 @@ func Test_pndImplementation_GetSBIs(t *testing.T) {
 	pnd := newPnd()
 	tests := []struct {
 		name string
-		want *sbiStore
+		want *SbiStore
 	}{
 		{name: "default", want: &pnd.sbic},
 	}
@@ -353,7 +355,7 @@ func Test_pndImplementation_MarshalDevice(t *testing.T) {
 			if got != tt.want {
 				t.Errorf("MarshalDevice() got = %v, want %v", got, tt.want)
 			}
-			if err := pnd.devices.delete(did); err != nil {
+			if err := pnd.devices.Delete(did); err != nil {
 				t.Error(err)
 			}
 		})
@@ -385,7 +387,7 @@ func Test_pndImplementation_RemoveDevice(t *testing.T) {
 			if err := pnd.RemoveDevice(tt.args.uuid); (err != nil) != tt.wantErr {
 				t.Errorf("RemoveDevice() error = %v, wantErr %v", err, tt.wantErr)
 			}
-			if pnd.devices.exists(did) && tt.name == "default" {
+			if pnd.devices.Exists(did) && tt.name == "default" {
 				t.Errorf("RemoveDevice() device still in device store %v", pnd.devices)
 			}
 		})
@@ -410,8 +412,8 @@ func Test_pndImplementation_RemoveSbi(t *testing.T) {
 			pnd := &pndImplementation{
 				name:        "test-remove-sbi",
 				description: "test-remove-sbi",
-				sbic:        sbiStore{store{}},
-				devices:     deviceStore{store{}},
+				sbic:        SbiStore{store{}},
+				devices:     DeviceStore{store{}},
 				id:          defaultPndID,
 			}
 			if tt.name != "fails empty" {
@@ -422,7 +424,7 @@ func Test_pndImplementation_RemoveSbi(t *testing.T) {
 			if err := pnd.RemoveSbi(tt.args.id); (err != nil) != tt.wantErr {
 				t.Errorf("RemoveSbi() error = %v, wantErr %v", err, tt.wantErr)
 			}
-			if pnd.sbic.exists(tt.args.id) {
+			if pnd.sbic.Exists(tt.args.id) {
 				t.Errorf("RemoveDevice() SBI still in SBI store %v", pnd.sbic)
 			}
 		})
@@ -470,7 +472,7 @@ func Test_pndImplementation_Request(t *testing.T) {
 			if err := pnd.Request(tt.args.uuid, tt.args.path); (err != nil) != tt.wantErr {
 				t.Errorf("Request() error = %v, wantErr %v", err, tt.wantErr)
 			}
-			if err := pnd.devices.delete(mdid); err != nil {
+			if err := pnd.devices.Delete(mdid); err != nil {
 				t.Error(err)
 			}
 		})
@@ -518,7 +520,7 @@ func Test_pndImplementation_RequestAll(t *testing.T) {
 			if err := pnd.RequestAll(tt.args.path); (err != nil) != tt.wantErr {
 				t.Errorf("RequestAll() error = %v, wantErr %v", err, tt.wantErr)
 			}
-			if err := pnd.devices.delete(mdid); err != nil {
+			if err := pnd.devices.Delete(mdid); err != nil {
 				t.Error(err)
 			}
 		})
@@ -545,7 +547,7 @@ func Test_pndImplementation_ChangeOND(t *testing.T) {
 			fields: fields{},
 			args: args{
 				uuid:      mdid,
-				operation: TransportUpdate,
+				operation: types.TransportUpdate,
 				path:      "/system/config/hostname",
 				value:     []string{"ceos3000"},
 			},
@@ -556,7 +558,7 @@ func Test_pndImplementation_ChangeOND(t *testing.T) {
 			fields: fields{},
 			args: args{
 				uuid:      mdid,
-				operation: TransportReplace,
+				operation: types.TransportReplace,
 				path:      "/system/config/hostname",
 				value:     []string{"ceos3000"},
 			},
@@ -567,7 +569,7 @@ func Test_pndImplementation_ChangeOND(t *testing.T) {
 			fields: fields{},
 			args: args{
 				uuid:      mdid,
-				operation: TransportDelete,
+				operation: types.TransportDelete,
 				path:      "/system/config/hostname",
 			},
 			wantErr: false,
@@ -577,7 +579,7 @@ func Test_pndImplementation_ChangeOND(t *testing.T) {
 			fields: fields{},
 			args: args{
 				uuid:      mdid,
-				operation: TransportDelete,
+				operation: types.TransportDelete,
 				path:      "/system/config/hostname",
 				value:     []string{"ceos3000"},
 			},
@@ -599,7 +601,7 @@ func Test_pndImplementation_ChangeOND(t *testing.T) {
 			fields: fields{},
 			args: args{
 				uuid:      mdid,
-				operation: TransportUpdate,
+				operation: types.TransportUpdate,
 				path:      "/system/config/hostname",
 				value:     []string{"ceos3000", "ceos3001"},
 			},
@@ -610,7 +612,7 @@ func Test_pndImplementation_ChangeOND(t *testing.T) {
 			fields: fields{},
 			args: args{
 				uuid:      mdid,
-				operation: TransportUpdate,
+				operation: types.TransportUpdate,
 				path:      "/system/config/hostname",
 			},
 			wantErr: true,
@@ -620,7 +622,7 @@ func Test_pndImplementation_ChangeOND(t *testing.T) {
 			fields: fields{},
 			args: args{
 				uuid:      mdid,
-				operation: TransportUpdate,
+				operation: types.TransportUpdate,
 				path:      "/system/config/hostname",
 			},
 			wantErr: true,
@@ -630,7 +632,7 @@ func Test_pndImplementation_ChangeOND(t *testing.T) {
 			fields: fields{},
 			args: args{
 				uuid:      did,
-				operation: TransportUpdate,
+				operation: types.TransportUpdate,
 			},
 			wantErr: true,
 		},
@@ -657,13 +659,14 @@ func Test_pndImplementation_ChangeOND(t *testing.T) {
 }
 
 func Test_pndImplementation_GetDevice(t *testing.T) {
-	p := newPnd()
+	pnd := newPnd()
+	sbi := NewSBI(types.Openconfig)
 	d, err := NewDevice(sbi, &GnmiTransportOptions{})
 	if err != nil {
 		t.Error(err)
 		return
 	}
-	if err = p.addDevice(d); err != nil {
+	if err = pnd.addDevice(d); err != nil {
 		t.Error(err)
 		return
 	}
@@ -691,7 +694,7 @@ func Test_pndImplementation_GetDevice(t *testing.T) {
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
-			got, err := p.GetDevice(tt.args.uuid)
+			got, err := pnd.GetDevice(tt.args.uuid)
 			if (err != nil) != tt.wantErr {
 				t.Errorf("GetDevice() error = %v, wantErr %v", err, tt.wantErr)
 				return
@@ -727,7 +730,7 @@ func Test_pndImplementation_Confirm(t *testing.T) {
 				t.Error(err)
 				return
 			}
-			if err := pnd.ChangeOND(d.ID(), TransportUpdate, "system/config/hostname", "ceos3000"); err != nil {
+			if err := pnd.ChangeOND(d.ID(), types.TransportUpdate, "system/config/hostname", "ceos3000"); err != nil {
 				t.Error(err)
 				return
 			}
diff --git a/nucleus/restconf_transport.go b/nucleus/restconf_transport.go
index 7fe89a200b5cb0a0b58e488cae1ee93a98f4a3a2..6d7237aaf9c0adb5a5451b67cdc6e26d9aacc1ad 100644
--- a/nucleus/restconf_transport.go
+++ b/nucleus/restconf_transport.go
@@ -3,6 +3,8 @@ package nucleus
 import (
 	"context"
 
+	"code.fbi.h-da.de/cocsn/gosdn/nucleus/errors"
+
 	"github.com/openconfig/ygot/ytypes"
 )
 
@@ -12,17 +14,17 @@ type Restconf struct{}
 
 // Get not yet implemented
 func (r Restconf) Get(ctx context.Context, params ...string) (interface{}, error) {
-	return nil, &ErrNotYetImplemented{}
+	return nil, &errors.ErrNotYetImplemented{}
 }
 
 // Set not yet implemented
 func (r Restconf) Set(ctx context.Context, params ...interface{}) error {
-	return &ErrNotYetImplemented{}
+	return &errors.ErrNotYetImplemented{}
 }
 
 // Subscribe not yet implemented
 func (r Restconf) Subscribe(ctx context.Context, params ...string) error {
-	return &ErrNotYetImplemented{}
+	return &errors.ErrNotYetImplemented{}
 }
 
 // Type not yet implemented
@@ -32,10 +34,10 @@ func (r Restconf) Type() string {
 
 // GetOptions not yet implemented
 func (r Restconf) GetOptions() interface{} {
-	return &ErrNotYetImplemented{}
+	return &errors.ErrNotYetImplemented{}
 }
 
 // ProcessResponse not yet implemented
 func (r Restconf) ProcessResponse(resp interface{}, root interface{}, models *ytypes.Schema) error {
-	return &ErrNotYetImplemented{}
+	return &errors.ErrNotYetImplemented{}
 }
diff --git a/nucleus/southbound.go b/nucleus/southbound.go
index bd7f6ff7f035be434321ff527290d5f2771b1026..b8eec7772e73d94aaaea5e3467c2b16bcbf86d61 100644
--- a/nucleus/southbound.go
+++ b/nucleus/southbound.go
@@ -3,6 +3,9 @@ package nucleus
 import (
 	"reflect"
 
+	"code.fbi.h-da.de/cocsn/gosdn/nucleus/errors"
+	"code.fbi.h-da.de/cocsn/gosdn/nucleus/types"
+
 	"code.fbi.h-da.de/cocsn/yang-models/generated/openconfig"
 	"github.com/google/uuid"
 	gpb "github.com/openconfig/gnmi/proto/gnmi"
@@ -27,8 +30,14 @@ type SouthboundInterface interface {
 	ID() uuid.UUID
 }
 
-// Tapi is the implementation of an TAPI SBI.
-type Tapi struct {
+// NewSBI creates a SouthboundInterface of a given type.
+func NewSBI(southbound types.Southbound) SouthboundInterface {
+	switch southbound {
+	case types.Openconfig:
+		return &OpenConfig{id: uuid.New()}
+	default:
+		return nil
+	}
 }
 
 // OpenConfig is the implementation of an OpenConfig SBI.
@@ -88,7 +97,7 @@ func unmarshal(bytes []byte, fields []string, goStruct interface{}, opt ...ytype
 		return openconfig.Unmarshal(bytes, goStruct.(*openconfig.Device), opt...)
 	case 1:
 	default:
-		return &ErrUnsupportedPath{fields}
+		return &errors.ErrUnsupportedPath{Path: fields}
 	}
 	var c ygot.GoStruct
 	var field string
diff --git a/nucleus/store.go b/nucleus/store.go
index 35edfb62a7c733fccfb4b8f1612553da485161f8..291ed361c39491e49c499a2cefab1e556df88578 100644
--- a/nucleus/store.go
+++ b/nucleus/store.go
@@ -4,7 +4,8 @@ import (
 	"reflect"
 	"sync"
 
-	p "code.fbi.h-da.de/cocsn/gosdn/nucleus/pnd"
+	"code.fbi.h-da.de/cocsn/gosdn/nucleus/errors"
+
 	"github.com/google/uuid"
 	log "github.com/sirupsen/logrus"
 )
@@ -16,18 +17,54 @@ type Storable interface {
 	ID() uuid.UUID
 }
 
+// Store describes an interface for store implementations.
+type Store interface {
+	Exists(id uuid.UUID) bool
+	Add(item Storable) error
+	Get(id uuid.UUID) (Storable, error)
+	Delete(id uuid.UUID) error
+	UUIDs() []uuid.UUID
+}
+
+// NewStore returns a generic Store
+func NewStore() Store {
+	return store{}
+}
+
+// NewPndStore returns a PndStore
+func NewPndStore() *PndStore {
+	return &PndStore{store{}}
+}
+
+// NewSbiStore returns a SbiStore
+func NewSbiStore() *SbiStore {
+	return &SbiStore{store{}}
+}
+
+// NewDeviceStore returns a DeviceStore
+func NewDeviceStore() *DeviceStore {
+	return &DeviceStore{store{}}
+}
+
+// NewChangeStore returns a ChangeStore
+func NewChangeStore() *ChangeStore {
+	return &ChangeStore{store{}}
+}
+
 type store map[uuid.UUID]Storable
 
-func (s store) exists(id uuid.UUID) bool {
+// Exists takes a Storable's UUID and checks its existence in the store.
+func (s store) Exists(id uuid.UUID) bool {
 	storeLock.RLock()
 	defer storeLock.RUnlock()
 	_, ok := s[id]
 	return ok
 }
 
-func (s store) add(item Storable) error {
-	if s.exists(item.ID()) {
-		return &ErrAlreadyExists{item: item}
+// Add adds a Storable to the Store
+func (s store) Add(item Storable) error {
+	if s.Exists(item.ID()) {
+		return &errors.ErrAlreadyExists{Item: item}
 	}
 	storeLock.Lock()
 	s[item.ID()] = item
@@ -39,9 +76,11 @@ func (s store) add(item Storable) error {
 	return nil
 }
 
-func (s store) get(id uuid.UUID) (Storable, error) {
-	if !s.exists(id) {
-		return nil, &ErrNotFound{id: id}
+// Get takes a Storable's UUID and returns the Storable. If the requested
+// Storable does not exist an error is returned.
+func (s store) Get(id uuid.UUID) (Storable, error) {
+	if !s.Exists(id) {
+		return nil, &errors.ErrNotFound{ID: id}
 	}
 	log.WithFields(log.Fields{
 		"uuid": id,
@@ -51,9 +90,11 @@ func (s store) get(id uuid.UUID) (Storable, error) {
 	return s[id], nil
 }
 
-func (s store) delete(id uuid.UUID) error {
-	if !s.exists(id) {
-		return &ErrNotFound{id: id}
+// Delete takes a Storable's UUID and deletes it. If the specified UUID does not
+// exist in the Store an error is returned.
+func (s store) Delete(id uuid.UUID) error {
+	if !s.Exists(id) {
+		return &errors.ErrNotFound{ID: id}
 	}
 	storeLock.Lock()
 	delete(s, id)
@@ -64,6 +105,7 @@ func (s store) delete(id uuid.UUID) error {
 	return nil
 }
 
+// UUIDs returns all UUIDs in the store.
 func (s store) UUIDs() []uuid.UUID {
 	storeLock.RLock()
 	defer storeLock.RUnlock()
@@ -76,20 +118,23 @@ func (s store) UUIDs() []uuid.UUID {
 	return keys
 }
 
-type sbiStore struct {
+// SbiStore is used to store SouthboundInterfaces
+type SbiStore struct {
 	store
 }
 
-func (s sbiStore) get(id uuid.UUID) (SouthboundInterface, error) {
-	item, err := s.store.get(id)
+// Get takes a SouthboundInterface's UUID and returns the SouthboundInterface. If the requested
+// SouthboundInterface does not exist an error is returned.
+func (s SbiStore) Get(id uuid.UUID) (SouthboundInterface, error) {
+	item, err := s.store.Get(id)
 	if err != nil {
 		return nil, err
 	}
 	sbi, ok := item.(SouthboundInterface)
 	if !ok {
-		return nil, &ErrInvalidTypeAssertion{
-			v: sbi,
-			t: "SouthboundInterface",
+		return nil, &errors.ErrInvalidTypeAssertion{
+			Value: sbi,
+			Type:  "SouthboundInterface",
 		}
 	}
 	log.WithFields(log.Fields{
@@ -98,20 +143,23 @@ func (s sbiStore) get(id uuid.UUID) (SouthboundInterface, error) {
 	return sbi, nil
 }
 
-type pndStore struct {
+// PndStore is used to store PrincipalNetworkDomains
+type PndStore struct {
 	store
 }
 
-func (s pndStore) get(id uuid.UUID) (PrincipalNetworkDomain, error) {
-	item, err := s.store.get(id)
+// Get takes a PrincipalNetworkDomain's UUID and returns the PrincipalNetworkDomain. If the requested
+// PrincipalNetworkDomain does not exist an error is returned.
+func (s PndStore) Get(id uuid.UUID) (PrincipalNetworkDomain, error) {
+	item, err := s.store.Get(id)
 	if err != nil {
 		return nil, err
 	}
 	pnd, ok := item.(PrincipalNetworkDomain)
 	if !ok {
-		return nil, &ErrInvalidTypeAssertion{
-			v: pnd,
-			t: "PrincipalNetworkDomain",
+		return nil, &errors.ErrInvalidTypeAssertion{
+			Value: pnd,
+			Type:  "PrincipalNetworkDomain",
 		}
 	}
 	log.WithFields(log.Fields{
@@ -120,20 +168,23 @@ func (s pndStore) get(id uuid.UUID) (PrincipalNetworkDomain, error) {
 	return pnd, nil
 }
 
-type deviceStore struct {
+// DeviceStore is used to store Devices
+type DeviceStore struct {
 	store
 }
 
-func (s deviceStore) get(id uuid.UUID) (*Device, error) {
-	item, err := s.store.get(id)
+// Get takes a Device's UUID and returns the Device. If the requested
+// Device does not exist an error is returned.
+func (s DeviceStore) Get(id uuid.UUID) (*Device, error) {
+	item, err := s.store.Get(id)
 	if err != nil {
 		return nil, err
 	}
 	device, ok := item.(*Device)
 	if !ok {
-		return nil, &ErrInvalidTypeAssertion{
-			v: device,
-			t: reflect.TypeOf(&Device{}),
+		return nil, &errors.ErrInvalidTypeAssertion{
+			Value: device,
+			Type:  reflect.TypeOf(&Device{}),
 		}
 	}
 	log.WithFields(log.Fields{
@@ -142,20 +193,23 @@ func (s deviceStore) get(id uuid.UUID) (*Device, error) {
 	return device, nil
 }
 
-type changeStore struct {
+// ChangeStore is used to store Changes
+type ChangeStore struct {
 	store
 }
 
-func (s changeStore) get(id uuid.UUID) (*p.Change, error) {
-	item, err := s.store.get(id)
+// Get takes a Change's UUID and returns the Change. If the requested
+// Change does not exist an error is returned.
+func (s ChangeStore) Get(id uuid.UUID) (*Change, error) {
+	item, err := s.store.Get(id)
 	if err != nil {
 		return nil, err
 	}
-	change, ok := item.(*p.Change)
+	change, ok := item.(*Change)
 	if !ok {
-		return nil, &ErrInvalidTypeAssertion{
-			v: change,
-			t: reflect.TypeOf(&p.Change{}),
+		return nil, &errors.ErrInvalidTypeAssertion{
+			Value: change,
+			Type:  reflect.TypeOf(&Change{}),
 		}
 	}
 	log.WithFields(log.Fields{
diff --git a/nucleus/store_test.go b/nucleus/store_test.go
index affb9a1fb5727ff9eb30a316102590e8fc945128..f2db1ed61741fb75f4ab4360bc192610573f3697 100644
--- a/nucleus/store_test.go
+++ b/nucleus/store_test.go
@@ -42,11 +42,11 @@ func Test_store_add(t *testing.T) {
 			tt.args.item.(*mocks.Storable).On("ID").Return(iid)
 			switch tt.name {
 			case "already exixts":
-				_ = tt.s.add(tt.args.item)
+				_ = tt.s.Add(tt.args.item)
 			default:
 			}
-			if err := tt.s.add(tt.args.item); (err != nil) != tt.wantErr {
-				t.Errorf("add() error = %v, wantErr %v", err, tt.wantErr)
+			if err := tt.s.Add(tt.args.item); (err != nil) != tt.wantErr {
+				t.Errorf("Add() error = %v, wantErr %v", err, tt.wantErr)
 			}
 		})
 	}
@@ -87,7 +87,7 @@ func Test_store_delete(t *testing.T) {
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
-			if err := tt.s.delete(tt.args.id); (err != nil) != tt.wantErr {
+			if err := tt.s.Delete(tt.args.id); (err != nil) != tt.wantErr {
 				t.Errorf("delete() error = %v, wantErr %v", err, tt.wantErr)
 			}
 			if tt.name == "default" {
@@ -135,7 +135,7 @@ func Test_store_exists(t *testing.T) {
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
-			if got := tt.s.exists(tt.args.id); got != tt.want {
+			if got := tt.s.Exists(tt.args.id); got != tt.want {
 				t.Errorf("exists() = %v, want %v", got, tt.want)
 			}
 		})
@@ -181,7 +181,7 @@ func Test_store_get(t *testing.T) {
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
-			got, err := tt.s.get(tt.args.id)
+			got, err := tt.s.Get(tt.args.id)
 			if (err != nil) != tt.wantErr {
 				t.Errorf("get() error = %v, wantErr %v", err, tt.wantErr)
 				return
@@ -282,10 +282,10 @@ func Test_sbiStore_get(t *testing.T) {
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
-			s := sbiStore{
+			s := SbiStore{
 				store: tt.fields.store,
 			}
-			got, err := s.get(tt.args.id)
+			got, err := s.Get(tt.args.id)
 			if (err != nil) != tt.wantErr {
 				t.Errorf("get() error = %v, wantErr %v", err, tt.wantErr)
 				return
@@ -355,10 +355,10 @@ func Test_pndStore_get(t *testing.T) {
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
-			s := pndStore{
+			s := PndStore{
 				store: tt.fields.store,
 			}
-			got, err := s.get(tt.args.id)
+			got, err := s.Get(tt.args.id)
 			if (err != nil) != tt.wantErr {
 				t.Errorf("get() error = %v, wantErr %v", err, tt.wantErr)
 				return
@@ -422,10 +422,10 @@ func Test_deviceStore_get(t *testing.T) {
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
-			s := deviceStore{
+			s := DeviceStore{
 				store: tt.fields.store,
 			}
-			got, err := s.get(tt.args.id)
+			got, err := s.Get(tt.args.id)
 			if (err != nil) != tt.wantErr {
 				t.Errorf("get() error = %v, wantErr %v", err, tt.wantErr)
 				return
diff --git a/nucleus/transport.go b/nucleus/transport.go
index 050629580f632a11d7c5da420928285429f07cbd..4a1764e42a37f2724083a5d260c9bdee23f41a43 100644
--- a/nucleus/transport.go
+++ b/nucleus/transport.go
@@ -8,20 +8,6 @@ import (
 	"github.com/openconfig/ygot/ytypes"
 )
 
-// Operation codes numerous operations used to change the state of remote resources.
-// It is used as a unified code. Each Transport implementation needs to map these
-// accordingly to its specification.
-type Operation int
-
-const (
-	// TransportUpdate codes an update operation
-	TransportUpdate Operation = iota
-	// TransportReplace codes a replace operation
-	TransportReplace
-	// TransportDelete codes a delete operation
-	TransportDelete
-)
-
 // Transport provides an interface for Transport implementations
 // like RESTCONF or gnmi
 type Transport interface {
diff --git a/nucleus/types/context.go b/nucleus/types/context.go
new file mode 100644
index 0000000000000000000000000000000000000000..aa514b17b4068fec76f569f0113c9e3a1dd568d1
--- /dev/null
+++ b/nucleus/types/context.go
@@ -0,0 +1,16 @@
+package types
+
+// CtxKeyType is a custom type to be used as key in a context.WithValue() or
+// context.Value() call. For more information see:
+// https://www.calhoun.io/pitfalls-of-context-values-and-how-to-avoid-or-mitigate-them/
+// TODO: Unexport to comply with best practice
+type CtxKeyType string
+
+const (
+	// CtxKeyOpts context key for gnmi.SubscribeOptions
+	CtxKeyOpts CtxKeyType = "opts"
+	// CtxKeyConfig is a context key for gnmi.Config
+	CtxKeyConfig = "config"
+	// CtxKeyOperation is a context key for a gNMI operation (update, replace, delete)
+	CtxKeyOperation = "op"
+)
diff --git a/nucleus/types/sbi.go b/nucleus/types/sbi.go
new file mode 100644
index 0000000000000000000000000000000000000000..4f52211e91eb4db96a0b072787e4415184f50ff5
--- /dev/null
+++ b/nucleus/types/sbi.go
@@ -0,0 +1,9 @@
+package types
+
+// Southbound codes numerous SouthboundInterface implementations used by NewSBI()
+type Southbound int
+
+const (
+	// Openconfig describes an OpenConfig SBI
+	Openconfig Southbound = iota
+)
diff --git a/nucleus/types/transport.go b/nucleus/types/transport.go
new file mode 100644
index 0000000000000000000000000000000000000000..9b0cfe965ccbabfaa7d0a86fd09a317915b8548b
--- /dev/null
+++ b/nucleus/types/transport.go
@@ -0,0 +1,15 @@
+package types
+
+// Operation codes numerous operations used to change the state of remote resources.
+// It is used as a unified code. Each Transport implementation needs to map these
+// accordingly to its specification.
+type Operation int
+
+const (
+	// TransportUpdate codes an update operation
+	TransportUpdate Operation = iota
+	// TransportReplace codes a replace operation
+	TransportReplace
+	// TransportDelete codes a delete operation
+	TransportDelete
+)
diff --git a/test/integration/nucleusIntegration_test.go b/test/integration/nucleusIntegration_test.go
index ed6d78fd929ed1d8379ca0cc18bc11d2e65e5f83..ccd5d942adb7e8436eaf117811505deed12ae416 100644
--- a/test/integration/nucleusIntegration_test.go
+++ b/test/integration/nucleusIntegration_test.go
@@ -3,6 +3,7 @@ package integration
 import (
 	"code.fbi.h-da.de/cocsn/gosdn/forks/goarista/gnmi"
 	"code.fbi.h-da.de/cocsn/gosdn/nucleus"
+	"code.fbi.h-da.de/cocsn/gosdn/nucleus/types"
 	"context"
 	gpb "github.com/openconfig/gnmi/proto/gnmi"
 	pb "google.golang.org/protobuf/proto"
@@ -236,7 +237,7 @@ func TestGnmi_SubscribeIntegration(t *testing.T) {
 				t.Error(err)
 				return
 			}
-			ctx := context.WithValue(context.Background(), nucleus.CtxKeyOpts, tt.args.opts) //nolint
+			ctx := context.WithValue(context.Background(), types.CtxKeyOpts, tt.args.opts) //nolint
 			ctx, cancel := context.WithCancel(ctx)
 			go func() {
 				subErr := g.Subscribe(ctx)