diff --git a/controller/interfaces/plugin/plugin.go b/controller/interfaces/plugin/plugin.go
index dc01a0ee8145f5638cd4ca92d0bfa5b3017b68fe..f61bda8a8ec589486a6452141d4e07727790e2c3 100644
--- a/controller/interfaces/plugin/plugin.go
+++ b/controller/interfaces/plugin/plugin.go
@@ -27,11 +27,9 @@ const (
 	//CREATED state describes a plugin which has been created but is not yet
 	//built.
 	CREATED State = iota
-	// BUILT state describes a plugin which is built and can be loaded into the
-	// controller.
-	BUILT
-	// LOADED state describes a plugin which is running within the controller.
-	LOADED
+	// INITIALIZED state describes a plugin which is running and has been
+	// initialized with the model data of the associated network element.
+	INITIALIZED
 	// FAULTY state describes a plugin which couldn't be built or loaded.
 	FAULTY
 )
diff --git a/controller/northbound/server/networkElement.go b/controller/northbound/server/networkElement.go
index 2041d576da3a7e41edbdcd4c78ac5e3fb01dce29..a7e0dda020ebb08dd6c1b22bf4be04ad61c7faae 100644
--- a/controller/northbound/server/networkElement.go
+++ b/controller/northbound/server/networkElement.go
@@ -438,17 +438,17 @@ func (n *NetworkElementServer) GetPath(ctx context.Context, request *mnepb.GetPa
 			Name:        pnd.GetName(),
 			Description: pnd.GetDescription(),
 		},
-		MneNotification: resp.(*gnmi.GetResponse).Notification,
+		MneNotification: resp.Notification,
 	}, nil
 }
 
-func (n *NetworkElementServer) getPath(ctx context.Context, mne networkelement.NetworkElement, path string) (proto.Message, error) {
+func (n *NetworkElementServer) getPath(ctx context.Context, mne networkelement.NetworkElement, path string) (*gnmi.GetResponse, error) {
 	res, err := mne.Transport().Get(ctx, path)
 	if err != nil {
 		return nil, err
 	}
 
-	resp, ok := res.(proto.Message)
+	protoMessage, ok := res.(proto.Message)
 	if !ok {
 		return nil, &customerrs.InvalidTypeAssertionError{
 			Value: res,
@@ -456,12 +456,15 @@ func (n *NetworkElementServer) getPath(ctx context.Context, mne networkelement.N
 		}
 	}
 
-	err = mne.ProcessResponse(resp)
-	if err != nil {
-		return nil, err
+	getResponse, ok := protoMessage.(*gnmi.GetResponse)
+	if !ok {
+		return nil, &customerrs.InvalidTypeAssertionError{
+			Value: res,
+			Type:  (*gnmi.GetResponse)(nil),
+		}
 	}
 
-	return resp, nil
+	return getResponse, nil
 }
 
 // GetIntendedPath gets a path as the intended state stored in the storage.
@@ -689,7 +692,12 @@ func (n *NetworkElementServer) addMne(ctx context.Context, name string, opt *tpb
 	}
 
 	if mne.IsTransportValid() {
-		_, err = n.getPath(ctx, mne, "/")
+		resp, err := n.getPath(ctx, mne, "/")
+		if err != nil {
+			return uuid.Nil, err
+		}
+
+		err = mne.ProcessResponse(resp)
 		if err != nil {
 			return uuid.Nil, err
 		}
diff --git a/controller/nucleus/networkElementService.go b/controller/nucleus/networkElementService.go
index ccd7d547314da7a5a26f93edf13fcbf286d42abe..3a8111abf466eef5af69b71b97388ccec244c379 100644
--- a/controller/nucleus/networkElementService.go
+++ b/controller/nucleus/networkElementService.go
@@ -133,7 +133,8 @@ func (s *NetworkElementService) UpdateModel(networkElementID uuid.UUID, modelAsS
 		},
 	}
 
-	// Use unmarshall from the network elements SBI to unmarshall ygot json in go struct.
+	// Use SetNode within the related plugin to map the path/value pair to the
+	// given ygot.GoStruct.
 	err = exisitingNetworkElement.GetPlugin().SetNode(path, typedValue)
 	if err != nil {
 		return err
@@ -235,22 +236,27 @@ func (s *NetworkElementService) createNetworkElementFromStore(loadedNetworkEleme
 		return nil, err
 	}
 
-	// Create 'root' path to be able to load the whole model from the store.
-	path, err := ygot.StringToPath("/", ygot.StructuredPath)
-	if err != nil {
-		return nil, err
-	}
+	// if the plugin is not initialized, we need to initialize it with the
+	// model data from the associated network element.
+	if mne.GetPlugin().State() != plugin.INITIALIZED {
+		// Create 'root' path to be able to load the whole model from the store.
+		path, err := ygot.StringToPath("/", ygot.StructuredPath)
+		if err != nil {
+			return nil, err
+		}
 
-	typedValue := &gnmi.TypedValue{
-		Value: &gnmi.TypedValue_JsonIetfVal{
-			JsonIetfVal: []byte(loadedNetworkElement.Model),
-		},
-	}
+		typedValue := &gnmi.TypedValue{
+			Value: &gnmi.TypedValue_JsonIetfVal{
+				JsonIetfVal: []byte(loadedNetworkElement.Model),
+			},
+		}
 
-	// Use unmarshall from the network elements SBI to unmarshall ygot json in go struct.
-	err = mne.GetPlugin().SetNode(path, typedValue)
-	if err != nil {
-		return nil, err
+		// Use SetNode within the related plugin to map the path/value pair to
+		// the given ygot.GoStruct.
+		err = mne.GetPlugin().SetNode(path, typedValue)
+		if err != nil {
+			return nil, err
+		}
 	}
 
 	return mne, nil
diff --git a/controller/nucleus/networkElementService_test.go b/controller/nucleus/networkElementService_test.go
index 7a02b94d8e8d4432fda45dea44f5c7fbdf65d6fd..1df0d17dc2272b3df896afe4c5cbfc2bc7b4f0d1 100644
--- a/controller/nucleus/networkElementService_test.go
+++ b/controller/nucleus/networkElementService_test.go
@@ -32,6 +32,7 @@ func getNetworkElementTestStores(t *testing.T, mneID uuid.UUID) (networkelement.
 	mockPlugin.On("ID").Return(mockPluginID)
 	mockPlugin.On("Model", mock.Anything).Return([]byte("hello"), nil)
 	mockPlugin.On("SetNode", mock.Anything, mock.Anything).Return(nil)
+	mockPlugin.On("State").Return(plugin.CREATED)
 	eventService := eventservice.NewMockEventService()
 	pluginStore := NewMemoryPluginStore()
 	networkElementStore := NewMemoryNetworkElementStore()
diff --git a/controller/nucleus/networkElementWatcher.go b/controller/nucleus/networkElementWatcher.go
index 9ff8ee31efdc05473b0ce038680be11c3c692260..2ead5fcdb1644d334978ffa1a8cebbfa155e2c56 100644
--- a/controller/nucleus/networkElementWatcher.go
+++ b/controller/nucleus/networkElementWatcher.go
@@ -151,11 +151,6 @@ func (n *NetworkElementWatcher) handleSubscribeResponseUpdate(resp *gpb.Subscrib
 		log.Error(err)
 	}
 
-	err = mne.Transport().ProcessControlPlaneSubscribeResponse(resp)
-	if err != nil {
-		log.Error(err)
-	}
-
 	pathsAndValues := make(map[string]string, len(resp.Update.Update))
 
 	for _, update := range resp.Update.Update {
diff --git a/controller/nucleus/plugin.go b/controller/nucleus/plugin.go
index adc0312b3d41c5ba03d695dcead5232d51e9563a..032c30ed4136f8741ff6a13de47b19f5a4a3275c 100644
--- a/controller/nucleus/plugin.go
+++ b/controller/nucleus/plugin.go
@@ -15,6 +15,7 @@ import (
 	"go.mongodb.org/mongo-driver/bson"
 )
 
+// Plugin is the controllers internal representation of a plugin.
 type Plugin struct {
 	UUID     uuid.UUID
 	state    plugin.State
@@ -24,6 +25,7 @@ type Plugin struct {
 	shared.DeviceModel
 }
 
+// NewPlugin creates a new Plugin.
 func NewPlugin(id uuid.UUID, execPath string) (*Plugin, error) {
 	client := hcplugin.NewClient(&hcplugin.ClientConfig{
 		HandshakeConfig:  shared.Handshake,
@@ -37,18 +39,24 @@ func NewPlugin(id uuid.UUID, execPath string) (*Plugin, error) {
 		return nil, err
 	}
 
-	// connect through grpc
+	// create a client that is within the AllowedProtocols. In this case this
+	// returns a gRPCClient. Allows to connect through gRPC.
 	gRPCClient, err := client.Client()
 	if err != nil {
 		return nil, err
 	}
 
-	// Request the plugin
+	// Request the plugin. This returns the gRPC client from the
+	// DeviceModelPlugin. This can then be casted to the interface that we are
+	// exposing through the plugin (in this case "DeviceModel").
 	raw, err := gRPCClient.Dispense("deviceModel")
 	if err != nil {
 		return nil, err
 	}
 
+	// cast the raw plugin to the DeviceModel interface. This allows to call
+	// methods on the plugin as if it were a normal DeviceModel instance but
+	// actually they are executed on the plugin sent through gRPC.
 	model, ok := raw.(shared.DeviceModel)
 	if !ok {
 		return nil, customerrs.InvalidTypeAssertionError{
@@ -67,6 +75,7 @@ func NewPlugin(id uuid.UUID, execPath string) (*Plugin, error) {
 	}, nil
 }
 
+// NewPluginThroughReattachConfig creates a new Plugin through a reattach config.
 func NewPluginThroughReattachConfig(loadedPlugin plugin.LoadedPlugin) (plugin.Plugin, error) {
 	client := hcplugin.NewClient(&hcplugin.ClientConfig{
 		HandshakeConfig:  shared.Handshake,
@@ -75,18 +84,24 @@ func NewPluginThroughReattachConfig(loadedPlugin plugin.LoadedPlugin) (plugin.Pl
 		AllowedProtocols: []hcplugin.Protocol{hcplugin.ProtocolGRPC},
 	})
 
-	// connect through grpc
+	// create a client that is within the AllowedProtocols. In this case this
+	// returns a gRPCClient. Allows to connect through gRPC.
 	gRPCClient, err := client.Client()
 	if err != nil {
 		return nil, err
 	}
 
-	// Request the plugin
+	// Request the plugin. This returns the gRPC client from the
+	// DeviceModelPlugin. This can then be casted to the interface that we are
+	// exposing through the plugin (in this case "DeviceModel").
 	raw, err := gRPCClient.Dispense("deviceModel")
 	if err != nil {
 		return nil, err
 	}
 
+	// cast the raw plugin to the DeviceModel interface. This allows to call
+	// methods on the plugin as if it were a normal DeviceModel instance but
+	// actually they are executed on the plugin sent through gRPC.
 	model, ok := raw.(shared.DeviceModel)
 	if !ok {
 		return nil, customerrs.InvalidTypeAssertionError{
@@ -100,7 +115,7 @@ func NewPluginThroughReattachConfig(loadedPlugin plugin.LoadedPlugin) (plugin.Pl
 		client:      client,
 		DeviceModel: model,
 		manifest:    &loadedPlugin.Manifest,
-		state:       plugin.CREATED,
+		state:       plugin.INITIALIZED,
 	}, nil
 }
 
@@ -116,13 +131,14 @@ func (p *Plugin) ReattachConfig() *hcplugin.ReattachConfig {
 
 // State returns the current state of the plugin.
 // Different states of the plugin can be:
-//   - built
-//   - loaded
+//   - created
+//   - initialized
 //   - faulty
 func (p *Plugin) State() plugin.State {
 	return p.state
 }
 
+// ExecPath returns the path to the executable of the plugin.
 func (p *Plugin) ExecPath() string {
 	return p.execPath
 }
@@ -137,10 +153,12 @@ func (p *Plugin) Manifest() *plugin.Manifest {
 	return p.manifest
 }
 
+// Update updates the plugin to the latest available version.
 func (p *Plugin) Update() error {
 	return fmt.Errorf("not implemented yet")
 }
 
+// Restart restarts the plugin.
 func (p *Plugin) Restart() error {
 	return fmt.Errorf("not implemented yet")
 }
diff --git a/controller/plugin/shared/client.go b/controller/plugin/shared/client.go
index 2fc69232677ef43268e6bd5f6faf21d0528d85ca..4bdfdb8399f7a96a663be4a13d89cd771a59ad33 100644
--- a/controller/plugin/shared/client.go
+++ b/controller/plugin/shared/client.go
@@ -12,8 +12,16 @@ import (
 	"github.com/sirupsen/logrus"
 )
 
+// DeviceModelClient is the implementation of a DeviceModel that can
+// communicate via gRPC. The main purpose it to act as the gRPC client for the
+// DeviceModelPlugin. A hashicorp client can consume and use it. The
+// DeviceModelClient has to satisfy the DeviceModel interface and therefore
+// implements all the needed methods.
 type DeviceModelClient struct{ client pb.PluginClient }
 
+// Unmarshal calls the Unmarshal method of the DeviceModelClients client. A
+// request is created with the given json and path. If the operation failed an
+// error is returned.
 func (m *DeviceModelClient) Unmarshal(json []byte, path *gpb.Path) error {
 	_, err := m.client.Unmarshal(context.Background(), &pb.UnmarshalRequest{
 		Json: json,
@@ -22,6 +30,9 @@ func (m *DeviceModelClient) Unmarshal(json []byte, path *gpb.Path) error {
 	return err
 }
 
+// SetNode calls the SetNode method of the DeviceModelClients client. A request
+// is created with the given path and value. If the operation failed an error is
+// returned.
 func (m *DeviceModelClient) SetNode(path *gpb.Path, value *gpb.TypedValue) error {
 	_, err := m.client.SetNode(context.Background(), &pb.SetNodeRequest{
 		Path:  path,
@@ -30,6 +41,10 @@ func (m *DeviceModelClient) SetNode(path *gpb.Path, value *gpb.TypedValue) error
 	return err
 }
 
+// GetNode calls the GetNode method of the DeviceModelClients client. A request
+// is created with the given path and the provided boolean that decides if only
+// the intended state should be requested. The response is returned as a slice
+// of notifications. If the operation failed an error is returned.
 func (m *DeviceModelClient) GetNode(path *gpb.Path, requestForIntendedState bool) ([]*gpb.Notification, error) {
 	resp, err := m.client.GetNode(context.Background(), &pb.GetNodeRequest{
 		Path:                    path,
@@ -38,6 +53,9 @@ func (m *DeviceModelClient) GetNode(path *gpb.Path, requestForIntendedState bool
 	return resp.GetNodes(), err
 }
 
+// DeleteNode calls the DeleteNode method of the DeviceModelClients client. A
+// request is created with the given path. If the operation failed an error is
+// returned.
 func (m *DeviceModelClient) DeleteNode(path *gpb.Path) error {
 	_, err := m.client.DeleteNode(context.Background(), &pb.DeleteNodeRequest{
 		Path: path,
@@ -45,6 +63,10 @@ func (m *DeviceModelClient) DeleteNode(path *gpb.Path) error {
 	return err
 }
 
+// Model calls the Model method of the DeviceModelClients client. A request is
+// created with the given boolean that decides if read-only nodes should be
+// filtered. The response returns the model (filtered or not) as json. If the
+// operation failed an error is returned.
 func (m *DeviceModelClient) Model(filterReadOnly bool) ([]byte, error) {
 	resp, err := m.client.Model(context.Background(), &pb.ModelRequest{
 		FilterReadOnly: filterReadOnly,
@@ -52,6 +74,9 @@ func (m *DeviceModelClient) Model(filterReadOnly bool) ([]byte, error) {
 	return resp.Json, err
 }
 
+// Diff calls the Diff method of the DeviceModelClients client. A request is
+// created with the given original and modified model. The response returns the
+// diff as a gnmi notifications. If the operation failed an error is returned.
 func (m *DeviceModelClient) Diff(original, modified []byte) (*gpb.Notification, error) {
 	resp, err := m.client.Diff(context.Background(), &pb.DiffRequest{
 		Original: original,
@@ -60,6 +85,10 @@ func (m *DeviceModelClient) Diff(original, modified []byte) (*gpb.Notification,
 	return resp.GetNotification(), err
 }
 
+// ValidateChange calls the ValidateChange method of the DeviceModelClients
+// client. A request is created with the given operation, path and value (as
+// gnmi.TypedValue). The response returns the model as json. If the operation
+// failed an error is returned.
 func (m *DeviceModelClient) ValidateChange(operation mnepb.ApiOperation, path *gpb.Path, value *gpb.TypedValue) ([]byte, error) {
 	resp, err := m.client.ValidateChange(context.Background(), &pb.ValidateChangeRequest{
 		Operation: operation,
@@ -69,6 +98,10 @@ func (m *DeviceModelClient) ValidateChange(operation mnepb.ApiOperation, path *g
 	return resp.GetModel(), err
 }
 
+// PruneConfigFalse calls the PruneConfigFalse method of the DeviceModelClients
+// client. A request is created with the given model value (json as byte[]).
+// The response returns the model with the pruned config false nodes. If the
+// operation failed an error is returned.
 func (m *DeviceModelClient) PruneConfigFalse(value []byte) ([]byte, error) {
 	resp, err := m.client.PruneConfigFalse(context.Background(), &pb.PruneConfigFalseRequest{
 		Value: value,
@@ -76,6 +109,8 @@ func (m *DeviceModelClient) PruneConfigFalse(value []byte) ([]byte, error) {
 	return resp.GetModel(), err
 }
 
+// SchemaTree calls the SchemaTree method of the DeviceModelClients client. The
+// response stream is packed into a slice of bytes and returned.
 func (m *DeviceModelClient) SchemaTreeGzip() ([]byte, error) {
 	schemaTreeGzipClient, err := m.client.SchemaTreeGzip(context.Background(), &pb.SchemaTreeGzipRequest{})
 	if err != nil {
diff --git a/controller/plugin/shared/interface.go b/controller/plugin/shared/interface.go
index 8f438f94d01ed497a853ce5e2bb1098df918711c..e690481b34e9747620a868f0000b1c714bdb9894 100644
--- a/controller/plugin/shared/interface.go
+++ b/controller/plugin/shared/interface.go
@@ -11,16 +11,19 @@ import (
 	gpb "github.com/openconfig/gnmi/proto/gnmi"
 )
 
+// Hanshake describes the handshake config for the plugin.
 var Handshake = plugin.HandshakeConfig{
 	ProtocolVersion:  1,
 	MagicCookieKey:   "GOSDN_PLUGIN_MAGIC_COOKIE",
 	MagicCookieValue: "woux6tn7gbsm53ipb3w4zxb59qd3se43hnqeh5bieynzvfchchktsd32pbjqwuxq",
 }
 
+// PluginMap is the map of plugins that can be used.
 var PluginMap = map[string]plugin.Plugin{
 	"deviceModel": &DeviceModelPlugin{},
 }
 
+// DeviceModel describes the interface that will be accessible through the plugin.
 type DeviceModel interface {
 	// TODO: It should be possible to pass methods like Unmarshal, SetNode,
 	// GetNode, etc. ytypes.Unmarshal-|Set-|GetOptions
@@ -35,13 +38,18 @@ type DeviceModel interface {
 	PruneConfigFalse(value []byte) ([]byte, error)
 }
 
-// DeviceModelPlugin implements a hashicorp gRPC plugin.
+// DeviceModelPlugin is the implementation of a plugin.GRPCPlugin. It embeds
+// the Plugin interface from hashicorp/go-plugin as well a the DeviceModel
+// interface.
 type DeviceModelPlugin struct {
 	plugin.Plugin
 	Impl DeviceModel
 }
 
 func (p *DeviceModelPlugin) GRPCServer(broker *plugin.GRPCBroker, s *grpc.Server) error {
+	// Register a PluginServer defined through the proto definitions to the
+	// provided server - a DeviceModelServer implements the PluginServer
+	// interface.
 	pb.RegisterPluginServer(s, &DeviceModelServer{Impl: p.Impl})
 	return nil
 }
diff --git a/controller/plugin/shared/server.go b/controller/plugin/shared/server.go
index 56d0270b31893ab0c5925991c0d273853667f93e..b49c0558b5acd87f0c9f96f364a6490fb94c1284 100644
--- a/controller/plugin/shared/server.go
+++ b/controller/plugin/shared/server.go
@@ -11,11 +11,16 @@ import (
 	"github.com/sirupsen/logrus"
 )
 
+// DeviceModelServer is the gRPC server a DeviceModelClient can communicate
+// with. A implementation of a DeviceModel should be provided.
 type DeviceModelServer struct {
 	Impl DeviceModel
 	pb.UnimplementedPluginServer
 }
 
+// Unmarshal calls the Unmarshal method of the DeviceModel implementation. It
+// returns a response with a boolean indicating if the operation was
+// successful and an error if the operation failed.
 func (m *DeviceModelServer) Unmarshal(
 	ctx context.Context,
 	req *pb.UnmarshalRequest) (*pb.UnmarshalResponse, error) {
@@ -26,6 +31,9 @@ func (m *DeviceModelServer) Unmarshal(
 	return &pb.UnmarshalResponse{Valid: true}, err
 }
 
+// SetNode calls the SetNode method of the DeviceModel implementation. It
+// returns a response with a boolean indicating if the operation was
+// successful and an error if the operation failed.
 func (m *DeviceModelServer) SetNode(
 	ctx context.Context,
 	req *pb.SetNodeRequest) (*pb.SetNodeResponse, error) {
@@ -33,6 +41,9 @@ func (m *DeviceModelServer) SetNode(
 	return &pb.SetNodeResponse{Valid: true}, err
 }
 
+// GetNode calls the GetNode method of the DeviceModel implementation. It
+// returns a response with a slice of notifications and an error if the
+// operation failed.
 func (m *DeviceModelServer) GetNode(
 	ctx context.Context,
 	req *pb.GetNodeRequest) (*pb.GetNodeResponse, error) {
@@ -40,6 +51,9 @@ func (m *DeviceModelServer) GetNode(
 	return &pb.GetNodeResponse{Nodes: nodes}, err
 }
 
+// DeleteNode calls the DeleteNode method of the DeviceModel implementation. It
+// returns a response with a boolean indicating if the operation was
+// successful and an error if the operation failed.
 func (m *DeviceModelServer) DeleteNode(
 	ctx context.Context,
 	req *pb.DeleteNodeRequest) (*pb.DeleteNodeResponse, error) {
@@ -47,6 +61,8 @@ func (m *DeviceModelServer) DeleteNode(
 	return &pb.DeleteNodeResponse{Valid: true}, err
 }
 
+// Model calls the Model method of the DeviceModel implementation. It returns a
+// response with the model as json and an error if the operation failed.
 func (m *DeviceModelServer) Model(
 	ctx context.Context,
 	req *pb.ModelRequest) (*pb.ModelResponse, error) {
@@ -54,6 +70,9 @@ func (m *DeviceModelServer) Model(
 	return &pb.ModelResponse{Json: model}, err
 }
 
+// Diff calls the Diff method of the DeviceModel implementation. It returns a
+// response with gnmi notifications containing the found Diffs and an error if
+// the operation failed.
 func (m *DeviceModelServer) Diff(
 	ctx context.Context,
 	req *pb.DiffRequest) (*pb.DiffResponse, error) {
@@ -61,6 +80,9 @@ func (m *DeviceModelServer) Diff(
 	return &pb.DiffResponse{Notification: notification}, err
 }
 
+// ValidateChange calls the ValidateChange method of the DeviceModel. It
+// returns a response with the validated model as json and an error if the
+// operation failed.
 func (m *DeviceModelServer) ValidateChange(
 	ctx context.Context,
 	req *pb.ValidateChangeRequest) (*pb.ValidateChangeResponse, error) {
@@ -68,6 +90,9 @@ func (m *DeviceModelServer) ValidateChange(
 	return &pb.ValidateChangeResponse{Model: model}, err
 }
 
+// PruneConfigFalse calls the PruneConfigFalse method of the DeviceModel. It
+// returns a response with the pruned model as json and an error if the
+// operation failed.
 func (m *DeviceModelServer) PruneConfigFalse(
 	ctx context.Context,
 	req *pb.PruneConfigFalseRequest) (*pb.PruneConfigFalseResponse, error) {
@@ -75,6 +100,8 @@ func (m *DeviceModelServer) PruneConfigFalse(
 	return &pb.PruneConfigFalseResponse{Model: model}, err
 }
 
+// SchemaTree calls the SchemaTree method of the DeviceModel.
+// The SchemaTree is a byte array that will be sent through a stream.
 func (m *DeviceModelServer) SchemaTreeGzip(
 	req *pb.SchemaTreeGzipRequest,
 	stream pb.Plugin_SchemaTreeGzipServer) error {
diff --git a/docker-compose.yml b/docker-compose.yml
index f71ce23af9023e52b768062ecf2026b958d4fa80..82bb6b7502266c9a609592858bc5592656d93af3 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -26,7 +26,9 @@ services:
         - 127.0.0.1:15672:15672
 
   plugin-registry:
-    image: plugin-registry:latest
+    build:
+        context: .
+        dockerfile: plugin-registry/plugin-registry.Dockerfile
     ports:
         - 127.0.0.1:55057:55057
 
diff --git a/plugins/examples/arista/cmd/main.go b/plugins/examples/arista/cmd/main.go
index 6db446f5be08080a1788321147e9c6404d4d2581..58046ad7dd7464aa6f6202bf455c594bbc82b1a0 100644
--- a/plugins/examples/arista/cmd/main.go
+++ b/plugins/examples/arista/cmd/main.go
@@ -11,11 +11,13 @@ import (
 )
 
 func main() {
+	// Create a new DeviceModel.
 	deviceModel, err := sdk.NewDeviceModel(generated.Schema, generated.Unmarshal, generated.SchemaTreeGzip)
 	if err != nil {
 		log.Println(err)
 		os.Exit(1)
 	}
+	// Serve the DeviceModelPlugin and provide the implemented deviceModel.
 	plugin.Serve(&plugin.ServeConfig{
 		HandshakeConfig: shared.Handshake,
 		Plugins: map[string]plugin.Plugin{
diff --git a/plugins/examples/openconfig/cmd/main.go b/plugins/examples/openconfig/cmd/main.go
index fcdd8b0bc8720a1644a2dc1192da18d29d5d1ae6..a7c3a92fe42c9eafea5ce912dbe37d420c5f9463 100644
--- a/plugins/examples/openconfig/cmd/main.go
+++ b/plugins/examples/openconfig/cmd/main.go
@@ -11,11 +11,13 @@ import (
 )
 
 func main() {
+	// Create a new DeviceModel.
 	deviceModel, err := sdk.NewDeviceModel(generated.Schema, generated.Unmarshal, generated.SchemaTreeGzip)
 	if err != nil {
 		log.Println(err)
 		os.Exit(1)
 	}
+	// Serve the DeviceModelPlugin and provide the implemented deviceModel.
 	plugin.Serve(&plugin.ServeConfig{
 		HandshakeConfig: shared.Handshake,
 		Plugins: map[string]plugin.Plugin{
diff --git a/plugins/sdk/deviceModel.go b/plugins/sdk/deviceModel.go
index 3016c4a7aa2f83325b138cec14c4094e3e8c4ce3..8aec7a59d5729b5ce8cf8c94d4b2810b6bcd18b6 100644
--- a/plugins/sdk/deviceModel.go
+++ b/plugins/sdk/deviceModel.go
@@ -15,6 +15,8 @@ import (
 	log "github.com/sirupsen/logrus"
 )
 
+// Device model satisfies the DeviceModel interface of a plugin defined in
+// "code.fbi.h-da.de/danet/gosdn/controller/plugin/shared".
 type DeviceModel struct {
 	mu                         sync.RWMutex
 	model                      ygot.ValidatedGoStruct
@@ -23,6 +25,7 @@ type DeviceModel struct {
 	genereatedSchemaTreeGzipFn func() []byte
 }
 
+// NewDeviceModel creates a new DeviceModel.
 func NewDeviceModel(generatedSchemaFn func() (*ytypes.Schema, error), generatedUnmarshalFn func([]byte, ygot.GoStruct, ...ytypes.UnmarshalOpt) error, genereatedSchemaTreeGzipFn func() []byte) (*DeviceModel, error) {
 	schema, err := generatedSchemaFn()
 	if err != nil {
@@ -228,6 +231,7 @@ func (d *DeviceModel) Diff(original, modified []byte) (*gpb.Notification, error)
 	return ygot.Diff(originalAsValidatedCopy, modifiedAsValidatedCopy, diffOpts...)
 }
 
+// ValidateChange validates that the given value can be set at the given path.
 func (d *DeviceModel) ValidateChange(operation mnepb.ApiOperation, path *gpb.Path, value *gpb.TypedValue) ([]byte, error) {
 	d.mu.RLock()
 	modelCopy, err := createValidatedCopy(d.model)
@@ -255,6 +259,7 @@ func (d *DeviceModel) ValidateChange(operation mnepb.ApiOperation, path *gpb.Pat
 	return ygot.Marshal7951(modelCopy, getYgotMarshal7951Config(), ygot.JSONIndent(""))
 }
 
+// PruneConfigFalse removes all config false elements from the given model.
 func (d *DeviceModel) PruneConfigFalse(value []byte) ([]byte, error) {
 	validatedCopy, err := createValidatedCopy(d.schema.Root)
 	if err != nil {
diff --git a/scripts/simple-dev-setup.sh b/scripts/simple-dev-setup.sh
index a776153173a64ed20968c65d965da5a723f0a5ce..8f8abeaa23d1016f826bb157a40309e5c8022215 100755
--- a/scripts/simple-dev-setup.sh
+++ b/scripts/simple-dev-setup.sh
@@ -39,7 +39,7 @@ then
     echo "Need sudo rights."
     sudo echo "sudo rights granted"
     # Start databases, etc.
-    docker compose up -d
+    docker compose up --build -d
 
     sudo containerlab deploy -t $TOPOLOGY
     start_gosdn